Draft: Fixes in DXF exporter
This commit is contained in:
parent
58dd79e79b
commit
1446ee0b69
|
@ -278,7 +278,11 @@ def getGroupContents(objectslist,walls=False):
|
||||||
newlist = []
|
newlist = []
|
||||||
for obj in objectslist:
|
for obj in objectslist:
|
||||||
if obj.isDerivedFrom("App::DocumentObjectGroup"):
|
if obj.isDerivedFrom("App::DocumentObjectGroup"):
|
||||||
newlist.extend(getGroupContents(obj.Group))
|
if obj.isDerivedFrom("Drawing::FeaturePage"):
|
||||||
|
# skip if the grou is a page
|
||||||
|
newlist.append(obj)
|
||||||
|
else:
|
||||||
|
newlist.extend(getGroupContents(obj.Group))
|
||||||
else:
|
else:
|
||||||
newlist.append(obj)
|
newlist.append(obj)
|
||||||
if walls:
|
if walls:
|
||||||
|
|
|
@ -1487,7 +1487,11 @@ def export(objectslist,filename,nospline=False):
|
||||||
global exportList
|
global exportList
|
||||||
exportList = objectslist
|
exportList = objectslist
|
||||||
|
|
||||||
|
print exportList
|
||||||
|
|
||||||
exportList = Draft.getGroupContents(exportList)
|
exportList = Draft.getGroupContents(exportList)
|
||||||
|
|
||||||
|
print exportList
|
||||||
|
|
||||||
if (len(exportList) == 1) and (Draft.getType(exportList[0]) == "ArchSectionView"):
|
if (len(exportList) == 1) and (Draft.getType(exportList[0]) == "ArchSectionView"):
|
||||||
# arch view: export it "as is"
|
# arch view: export it "as is"
|
||||||
|
|
|
@ -335,12 +335,12 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
|
||||||
results=[]
|
results=[]
|
||||||
if abs(numer/denom) < 10**(-1*(Draft.precision())):
|
if abs(numer/denom) < 10**(-1*(Draft.precision())):
|
||||||
scalefacpos = 0
|
scalefacpos = 0
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
scalefacpos = math.sqrt(numer/denom)
|
scalefacpos = math.sqrt(numer/denom)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
FreeCAD.Console.PrintMessage('sqrt(%f/%f)\n' % (numer,denom))
|
FreeCAD.Console.PrintMessage('sqrt(%f/%f)\n' % (numer,denom))
|
||||||
scalefacpos = 0
|
scalefacpos = 0
|
||||||
for scalefacsign in (1,-1):
|
for scalefacsign in (1,-1):
|
||||||
scalefac = scalefacpos * scalefacsign
|
scalefac = scalefacpos * scalefacsign
|
||||||
vcx1 = Vector(v1.y*rx/ry,-v1.x*ry/rx,0).multiply(scalefac) # Step2 F.6.5.2
|
vcx1 = Vector(v1.y*rx/ry,-v1.x*ry/rx,0).multiply(scalefac) # Step2 F.6.5.2
|
||||||
|
@ -359,19 +359,19 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
|
||||||
|
|
||||||
|
|
||||||
def getrgb(color):
|
def getrgb(color):
|
||||||
"returns a rgb value #000000 from a freecad color"
|
"returns a rgb value #000000 from a freecad color"
|
||||||
r = str(hex(int(color[0]*255)))[2:].zfill(2)
|
r = str(hex(int(color[0]*255)))[2:].zfill(2)
|
||||||
g = str(hex(int(color[1]*255)))[2:].zfill(2)
|
g = str(hex(int(color[1]*255)))[2:].zfill(2)
|
||||||
b = str(hex(int(color[2]*255)))[2:].zfill(2)
|
b = str(hex(int(color[2]*255)))[2:].zfill(2)
|
||||||
return "#"+r+g+b
|
return "#"+r+g+b
|
||||||
|
|
||||||
class svgHandler(xml.sax.ContentHandler):
|
class svgHandler(xml.sax.ContentHandler):
|
||||||
"this handler parses the svg files and creates freecad objects"
|
"this handler parses the svg files and creates freecad objects"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"retrieving Draft parameters"
|
"retrieving Draft parameters"
|
||||||
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
params = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
|
||||||
self.style = params.GetInt("svgstyle")
|
self.style = params.GetInt("svgstyle")
|
||||||
self.count = 0
|
self.count = 0
|
||||||
self.transform = None
|
self.transform = None
|
||||||
self.grouptransform = []
|
self.grouptransform = []
|
||||||
|
@ -380,42 +380,44 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
|
|
||||||
global Part
|
global Part
|
||||||
import Part
|
import Part
|
||||||
|
|
||||||
if gui and draftui:
|
if gui and draftui:
|
||||||
r = float(draftui.color.red()/255.0)
|
r = float(draftui.color.red()/255.0)
|
||||||
g = float(draftui.color.green()/255.0)
|
g = float(draftui.color.green()/255.0)
|
||||||
b = float(draftui.color.blue()/255.0)
|
b = float(draftui.color.blue()/255.0)
|
||||||
self.lw = float(draftui.linewidth)
|
self.lw = float(draftui.linewidth)
|
||||||
else:
|
else:
|
||||||
self.lw = float(params.GetInt("linewidth"))
|
self.lw = float(params.GetInt("linewidth"))
|
||||||
c = params.GetUnsigned("color")
|
c = params.GetUnsigned("color")
|
||||||
r = float(((c>>24)&0xFF)/255)
|
r = float(((c>>24)&0xFF)/255)
|
||||||
g = float(((c>>16)&0xFF)/255)
|
g = float(((c>>16)&0xFF)/255)
|
||||||
b = float(((c>>8)&0xFF)/255)
|
b = float(((c>>8)&0xFF)/255)
|
||||||
self.col = (r,g,b,0.0)
|
self.col = (r,g,b,0.0)
|
||||||
|
|
||||||
def format(self,obj):
|
def format(self,obj):
|
||||||
"applies styles to passed object"
|
"applies styles to passed object"
|
||||||
if self.style and gui:
|
if self.style and gui:
|
||||||
v = obj.ViewObject
|
v = obj.ViewObject
|
||||||
if self.color: v.LineColor = self.color
|
if self.color: v.LineColor = self.color
|
||||||
if self.width: v.LineWidth = self.width
|
if self.width: v.LineWidth = self.width
|
||||||
if self.fill: v.ShapeColor = self.fill
|
if self.fill: v.ShapeColor = self.fill
|
||||||
|
|
||||||
def startElement(self, name, attrs):
|
def startElement(self, name, attrs):
|
||||||
|
|
||||||
# reorganizing data into a nice clean dictionary
|
# reorganizing data into a nice clean dictionary
|
||||||
|
|
||||||
self.count += 1
|
self.count += 1
|
||||||
|
|
||||||
FreeCAD.Console.PrintMessage('processing element %d: %s\n'%(self.count,name))
|
FreeCAD.Console.PrintMessage('processing element %d: %s\n'%(self.count,name))
|
||||||
FreeCAD.Console.PrintMessage('existing group transform: %s\n'%(str(self.grouptransform)))
|
FreeCAD.Console.PrintMessage('existing group transform: %s\n'%(str(self.grouptransform)))
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
for (keyword,content) in attrs.items():
|
for (keyword,content) in attrs.items():
|
||||||
content = content.replace(',',' ')
|
#print keyword,content
|
||||||
content = content.split()
|
content = content.replace(',',' ')
|
||||||
data[keyword]=content
|
content = content.split()
|
||||||
|
#print keyword,content
|
||||||
|
data[keyword]=content
|
||||||
|
|
||||||
if 'style' in data:
|
if 'style' in data:
|
||||||
if not data['style']:
|
if not data['style']:
|
||||||
|
@ -425,24 +427,27 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
content = content.split(';')
|
content = content.split(';')
|
||||||
for i in content:
|
for i in content:
|
||||||
pair = i.split(':')
|
pair = i.split(':')
|
||||||
if len(pair)>1: data[pair[0]]=pair[1]
|
if len(pair)>1: data[pair[0]]=pair[1]
|
||||||
|
|
||||||
for k in ['x','y','x1','y1','x2','y2','r','rx','ry','cx','cy','width','height']:
|
for k in ['x','y','x1','y1','x2','y2','r','rx','ry','cx','cy','width','height']:
|
||||||
if k in data:
|
if k in data:
|
||||||
data[k] = getsize(data[k][0],'css')
|
data[k] = getsize(data[k][0],'css')
|
||||||
|
|
||||||
for k in ['fill','stroke','stroke-width','font-size']:
|
for k in ['fill','stroke','stroke-width','font-size']:
|
||||||
if k in data:
|
if k in data:
|
||||||
if isinstance(data[k],list):
|
if isinstance(data[k],list):
|
||||||
data[k]=data[k][0]
|
if data[k][0].lower().startswith("rgb("):
|
||||||
|
data[k] = ",".join(data[k])
|
||||||
|
else:
|
||||||
|
data[k]=data[k][0]
|
||||||
|
|
||||||
# extracting style info
|
# extracting style info
|
||||||
|
|
||||||
self.fill = None
|
self.fill = None
|
||||||
self.color = None
|
self.color = None
|
||||||
self.width = None
|
self.width = None
|
||||||
self.text = None
|
self.text = None
|
||||||
|
|
||||||
if name == 'svg':
|
if name == 'svg':
|
||||||
m=FreeCAD.Matrix()
|
m=FreeCAD.Matrix()
|
||||||
if 'width' in data and 'height' in data and \
|
if 'width' in data and 'height' in data and \
|
||||||
|
@ -481,16 +486,16 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
#fallback to 90 dpi
|
#fallback to 90 dpi
|
||||||
m.scale(Vector(25.4/90.0,25.4/90.0,1))
|
m.scale(Vector(25.4/90.0,25.4/90.0,1))
|
||||||
self.grouptransform.append(m)
|
self.grouptransform.append(m)
|
||||||
if 'fill' in data:
|
if 'fill' in data:
|
||||||
if data['fill'][0] != 'none':
|
if data['fill'][0] != 'none':
|
||||||
self.fill = getcolor(data['fill'])
|
self.fill = getcolor(data['fill'])
|
||||||
if 'stroke' in data:
|
if 'stroke' in data:
|
||||||
if data['stroke'][0] != 'none':
|
if data['stroke'][0] != 'none':
|
||||||
self.color = getcolor(data['stroke'])
|
self.color = getcolor(data['stroke'])
|
||||||
if 'stroke-width' in data:
|
if 'stroke-width' in data:
|
||||||
if data['stroke-width'] != 'none':
|
if data['stroke-width'] != 'none':
|
||||||
self.width = getsize(data['stroke-width'],'css')
|
self.width = getsize(data['stroke-width'],'css')
|
||||||
if 'transform' in data:
|
if 'transform' in data:
|
||||||
m = self.getMatrix(attrs.getValue('transform'))
|
m = self.getMatrix(attrs.getValue('transform'))
|
||||||
if name == "g":
|
if name == "g":
|
||||||
self.grouptransform.append(m)
|
self.grouptransform.append(m)
|
||||||
|
@ -500,29 +505,29 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
if name == "g":
|
if name == "g":
|
||||||
self.grouptransform.append(FreeCAD.Matrix())
|
self.grouptransform.append(FreeCAD.Matrix())
|
||||||
|
|
||||||
if (self.style == 1):
|
if (self.style == 1):
|
||||||
self.color = self.col
|
self.color = self.col
|
||||||
self.width = self.lw
|
self.width = self.lw
|
||||||
|
|
||||||
pathname = None
|
pathname = None
|
||||||
if 'id' in data:
|
if 'id' in data:
|
||||||
pathname = data['id'][0]
|
pathname = data['id'][0]
|
||||||
FreeCAD.Console.PrintMessage('name: %s\n'%pathname)
|
FreeCAD.Console.PrintMessage('name: %s\n'%pathname)
|
||||||
|
|
||||||
# processing paths
|
# processing paths
|
||||||
|
|
||||||
if name == "path":
|
if name == "path":
|
||||||
FreeCAD.Console.PrintMessage('data: %s\n'%str(data))
|
FreeCAD.Console.PrintMessage('data: %s\n'%str(data))
|
||||||
|
|
||||||
if not pathname: pathname = 'Path'
|
if not pathname: pathname = 'Path'
|
||||||
|
|
||||||
path = []
|
path = []
|
||||||
point = []
|
point = []
|
||||||
lastvec = Vector(0,0,0)
|
lastvec = Vector(0,0,0)
|
||||||
lastpole = None
|
lastpole = None
|
||||||
command = None
|
command = None
|
||||||
relative = False
|
relative = False
|
||||||
firstvec = None
|
firstvec = None
|
||||||
|
|
||||||
if "freecad:basepoint1" in data:
|
if "freecad:basepoint1" in data:
|
||||||
p1 = data["freecad:basepoint1"]
|
p1 = data["freecad:basepoint1"]
|
||||||
|
@ -748,7 +753,11 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
path.append(seg)
|
path.append(seg)
|
||||||
elif (d == "Z") or (d == "z"):
|
elif (d == "Z") or (d == "z"):
|
||||||
if not DraftVecUtils.equals(lastvec,firstvec):
|
if not DraftVecUtils.equals(lastvec,firstvec):
|
||||||
|
try:
|
||||||
seg = Part.Line(lastvec,firstvec).toShape()
|
seg = Part.Line(lastvec,firstvec).toShape()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
path.append(seg)
|
path.append(seg)
|
||||||
if path: #the path should be closed by now
|
if path: #the path should be closed by now
|
||||||
#sh=makewire(path,True)
|
#sh=makewire(path,True)
|
||||||
|
@ -774,9 +783,9 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
self.format(obj)
|
self.format(obj)
|
||||||
|
|
||||||
|
|
||||||
# processing rects
|
# processing rects
|
||||||
|
|
||||||
if name == "rect":
|
if name == "rect":
|
||||||
if not pathname: pathname = 'Rectangle'
|
if not pathname: pathname = 'Rectangle'
|
||||||
edges = []
|
edges = []
|
||||||
if ('rx' not in data or data['rx'] < 10**(-1*Draft.precision())) and \
|
if ('rx' not in data or data['rx'] < 10**(-1*Draft.precision())) and \
|
||||||
|
@ -847,37 +856,37 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
self.format(obj)
|
self.format(obj)
|
||||||
# processing lines
|
# processing lines
|
||||||
|
|
||||||
if name == "line":
|
if name == "line":
|
||||||
if not pathname: pathname = 'Line'
|
if not pathname: pathname = 'Line'
|
||||||
p1 = Vector(data['x1'],-data['y1'],0)
|
p1 = Vector(data['x1'],-data['y1'],0)
|
||||||
p2 = Vector(data['x2'],-data['y2'],0)
|
p2 = Vector(data['x2'],-data['y2'],0)
|
||||||
sh = Part.Line(p1,p2).toShape()
|
sh = Part.Line(p1,p2).toShape()
|
||||||
sh = self.applyTrans(sh)
|
sh = self.applyTrans(sh)
|
||||||
obj = self.doc.addObject("Part::Feature",pathname)
|
obj = self.doc.addObject("Part::Feature",pathname)
|
||||||
obj.Shape = sh
|
obj.Shape = sh
|
||||||
self.format(obj)
|
self.format(obj)
|
||||||
|
|
||||||
# processing polylines and polygons
|
# processing polylines and polygons
|
||||||
|
|
||||||
if name == "polyline" or name == "polygon":
|
if name == "polyline" or name == "polygon":
|
||||||
'''a simpler implementation would be sh = Part.makePolygon([Vector(svgx,-svgy,0) for svgx,svgy in zip(points[0::2],points[1::2])])
|
'''a simpler implementation would be sh = Part.makePolygon([Vector(svgx,-svgy,0) for svgx,svgy in zip(points[0::2],points[1::2])])
|
||||||
but there would be more difficlult to search for duplicate points beforehand.'''
|
but there would be more difficlult to search for duplicate points beforehand.'''
|
||||||
if not pathname: pathname = 'Polyline'
|
if not pathname: pathname = 'Polyline'
|
||||||
points=[float(d) for d in data['points']]
|
points=[float(d) for d in data['points']]
|
||||||
FreeCAD.Console.PrintMessage('points %s\n'%str(points))
|
FreeCAD.Console.PrintMessage('points %s\n'%str(points))
|
||||||
lenpoints=len(points)
|
lenpoints=len(points)
|
||||||
if lenpoints>=4 and lenpoints % 2 == 0:
|
if lenpoints>=4 and lenpoints % 2 == 0:
|
||||||
lastvec = Vector(points[0],-points[1],0)
|
lastvec = Vector(points[0],-points[1],0)
|
||||||
path=[]
|
path=[]
|
||||||
if name == 'polygon':
|
if name == 'polygon':
|
||||||
points=points+points[:2] # emulate closepath
|
points=points+points[:2] # emulate closepath
|
||||||
for svgx,svgy in zip(points[2::2],points[3::2]):
|
for svgx,svgy in zip(points[2::2],points[3::2]):
|
||||||
currentvec = Vector(svgx,-svgy,0)
|
currentvec = Vector(svgx,-svgy,0)
|
||||||
if not DraftVecUtils.equals(lastvec,currentvec):
|
if not DraftVecUtils.equals(lastvec,currentvec):
|
||||||
seg = Part.Line(lastvec,currentvec).toShape()
|
seg = Part.Line(lastvec,currentvec).toShape()
|
||||||
#print "polyline seg ",lastvec,currentvec
|
#print "polyline seg ",lastvec,currentvec
|
||||||
lastvec = currentvec
|
lastvec = currentvec
|
||||||
path.append(seg)
|
path.append(seg)
|
||||||
if path:
|
if path:
|
||||||
sh = Part.Wire(path)
|
sh = Part.Wire(path)
|
||||||
if self.fill and sh.isClosed():
|
if self.fill and sh.isClosed():
|
||||||
|
@ -908,9 +917,9 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
sh = Part.Wire([sh])
|
sh = Part.Wire([sh])
|
||||||
sh = Part.Face(sh)
|
sh = Part.Face(sh)
|
||||||
sh = self.applyTrans(sh)
|
sh = self.applyTrans(sh)
|
||||||
obj = self.doc.addObject("Part::Feature",pathname)
|
obj = self.doc.addObject("Part::Feature",pathname)
|
||||||
obj.Shape = sh
|
obj.Shape = sh
|
||||||
self.format(obj)
|
self.format(obj)
|
||||||
|
|
||||||
|
|
||||||
# processing circles
|
# processing circles
|
||||||
|
@ -925,13 +934,13 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
sh = Part.Face(sh)
|
sh = Part.Face(sh)
|
||||||
sh.translate(c)
|
sh.translate(c)
|
||||||
sh = self.applyTrans(sh)
|
sh = self.applyTrans(sh)
|
||||||
obj = self.doc.addObject("Part::Feature",pathname)
|
obj = self.doc.addObject("Part::Feature",pathname)
|
||||||
obj.Shape = sh
|
obj.Shape = sh
|
||||||
self.format(obj)
|
self.format(obj)
|
||||||
|
|
||||||
# processing texts
|
# processing texts
|
||||||
|
|
||||||
if name in ["text","tspan"]:
|
if name in ["text","tspan"]:
|
||||||
if not("freecad:skip" in data):
|
if not("freecad:skip" in data):
|
||||||
FreeCAD.Console.PrintMessage("processing a text\n")
|
FreeCAD.Console.PrintMessage("processing a text\n")
|
||||||
if 'x' in data:
|
if 'x' in data:
|
||||||
|
@ -953,12 +962,12 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
|
|
||||||
FreeCAD.Console.PrintMessage("done processing element %d\n"%self.count)
|
FreeCAD.Console.PrintMessage("done processing element %d\n"%self.count)
|
||||||
|
|
||||||
def characters(self,content):
|
def characters(self,content):
|
||||||
if self.text:
|
if self.text:
|
||||||
FreeCAD.Console.PrintMessage("reading characters %s\n" % str(content))
|
FreeCAD.Console.PrintMessage("reading characters %s\n" % str(content))
|
||||||
obj=self.doc.addObject("App::Annotation",'Text')
|
obj=self.doc.addObject("App::Annotation",'Text')
|
||||||
obj.LabelText = content.encode('latin1')
|
obj.LabelText = content.encode('latin1')
|
||||||
vec = Vector(self.x,-self.y,0)
|
vec = Vector(self.x,-self.y,0)
|
||||||
if self.transform:
|
if self.transform:
|
||||||
vec = self.translateVec(vec,self.transform)
|
vec = self.translateVec(vec,self.transform)
|
||||||
#print "own transform: ",self.transform, vec
|
#print "own transform: ",self.transform, vec
|
||||||
|
@ -967,10 +976,10 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
vec = transform.multiply(vec)
|
vec = transform.multiply(vec)
|
||||||
#print "applying vector: ",vec
|
#print "applying vector: ",vec
|
||||||
obj.Position = vec
|
obj.Position = vec
|
||||||
if gui:
|
if gui:
|
||||||
obj.ViewObject.FontSize = int(self.text)
|
obj.ViewObject.FontSize = int(self.text)
|
||||||
if self.fill: obj.ViewObject.TextColor = self.fill
|
if self.fill: obj.ViewObject.TextColor = self.fill
|
||||||
else: obj.ViewObject.TextColor = (0.0,0.0,0.0,0.0)
|
else: obj.ViewObject.TextColor = (0.0,0.0,0.0,0.0)
|
||||||
|
|
||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
if not name in ["tspan"]:
|
if not name in ["tspan"]:
|
||||||
|
@ -1010,41 +1019,41 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
|
|
||||||
def getMatrix(self,tr):
|
def getMatrix(self,tr):
|
||||||
"returns a FreeCAD matrix from a svg transform attribute"
|
"returns a FreeCAD matrix from a svg transform attribute"
|
||||||
transformre=re.compile('(matrix|translate|scale|rotate|skewX|skewY)\s*?\((.*?)\)',re.DOTALL)
|
transformre=re.compile('(matrix|translate|scale|rotate|skewX|skewY)\s*?\((.*?)\)',re.DOTALL)
|
||||||
m = FreeCAD.Matrix()
|
m = FreeCAD.Matrix()
|
||||||
for transformation, arguments in transformre.findall(tr):
|
for transformation, arguments in transformre.findall(tr):
|
||||||
argsplit=[float(arg) for arg in arguments.replace(',',' ').split()]
|
argsplit=[float(arg) for arg in arguments.replace(',',' ').split()]
|
||||||
#m.multiply(FreeCAD.Matrix (1,0,0,0,0,-1))
|
#m.multiply(FreeCAD.Matrix (1,0,0,0,0,-1))
|
||||||
#print '%s:%s %s %d' % (transformation, arguments,argsplit,len(argsplit))
|
#print '%s:%s %s %d' % (transformation, arguments,argsplit,len(argsplit))
|
||||||
if transformation == 'translate':
|
if transformation == 'translate':
|
||||||
tx = argsplit[0]
|
tx = argsplit[0]
|
||||||
ty = argsplit[1] if len(argsplit) > 1 else 0.0
|
ty = argsplit[1] if len(argsplit) > 1 else 0.0
|
||||||
m.move(Vector(tx,-ty,0))
|
m.move(Vector(tx,-ty,0))
|
||||||
elif transformation == 'scale':
|
elif transformation == 'scale':
|
||||||
sx = argsplit[0]
|
sx = argsplit[0]
|
||||||
sy = argsplit[1] if len(argsplit) > 1 else sx
|
sy = argsplit[1] if len(argsplit) > 1 else sx
|
||||||
m.scale(Vector(sx,sy,1))
|
m.scale(Vector(sx,sy,1))
|
||||||
elif transformation == 'rotate':
|
elif transformation == 'rotate':
|
||||||
angle = argsplit[0]
|
angle = argsplit[0]
|
||||||
if len(argsplit) >= 3:
|
if len(argsplit) >= 3:
|
||||||
cx = argsplit[1]
|
cx = argsplit[1]
|
||||||
cy = argsplit[2]
|
cy = argsplit[2]
|
||||||
m.move(Vector(cx,-cy,0))
|
m.move(Vector(cx,-cy,0))
|
||||||
m.rotateZ(math.radians(-angle)) #mirroring one axis equals changing the direction of rotaion
|
m.rotateZ(math.radians(-angle)) #mirroring one axis equals changing the direction of rotaion
|
||||||
if len(argsplit) >= 3:
|
if len(argsplit) >= 3:
|
||||||
m.move(Vector(-cx,cy,0))
|
m.move(Vector(-cx,cy,0))
|
||||||
elif transformation == 'skewX':
|
elif transformation == 'skewX':
|
||||||
m=m.multiply(FreeCAD.Matrix(1,-math.tan(math.radians(argsplit[0]))))
|
m=m.multiply(FreeCAD.Matrix(1,-math.tan(math.radians(argsplit[0]))))
|
||||||
elif transformation == 'skewY':
|
elif transformation == 'skewY':
|
||||||
m=m.multiply(FreeCAD.Matrix(1,0,0,0,-math.tan(math.radians(argsplit[0]))))
|
m=m.multiply(FreeCAD.Matrix(1,0,0,0,-math.tan(math.radians(argsplit[0]))))
|
||||||
elif transformation == 'matrix':
|
elif transformation == 'matrix':
|
||||||
# '''transformation matrix:
|
# '''transformation matrix:
|
||||||
# FreeCAD SVG
|
# FreeCAD SVG
|
||||||
# (+A -C +0 +E) (A C 0 E)
|
# (+A -C +0 +E) (A C 0 E)
|
||||||
# (-B +D -0 -F) = (-Y) * (B D 0 F) *(-Y)
|
# (-B +D -0 -F) = (-Y) * (B D 0 F) *(-Y)
|
||||||
# (+0 -0 +1 +0) (0 0 1 0)
|
# (+0 -0 +1 +0) (0 0 1 0)
|
||||||
# (+0 -0 +0 +1) (0 0 0 1)'''
|
# (+0 -0 +0 +1) (0 0 0 1)'''
|
||||||
m=m.multiply(FreeCAD.Matrix(argsplit[0],-argsplit[2],0,argsplit[4],-argsplit[1],argsplit[3],0,-argsplit[5]))
|
m=m.multiply(FreeCAD.Matrix(argsplit[0],-argsplit[2],0,argsplit[4],-argsplit[1],argsplit[3],0,-argsplit[5]))
|
||||||
#else:
|
#else:
|
||||||
#print 'SKIPPED %s' % transformation
|
#print 'SKIPPED %s' % transformation
|
||||||
#print "m= ",m
|
#print "m= ",m
|
||||||
|
@ -1052,17 +1061,17 @@ class svgHandler(xml.sax.ContentHandler):
|
||||||
return m
|
return m
|
||||||
|
|
||||||
def decodeName(name):
|
def decodeName(name):
|
||||||
"decodes encoded strings"
|
"decodes encoded strings"
|
||||||
try:
|
try:
|
||||||
decodedName = (name.decode("utf8"))
|
decodedName = (name.decode("utf8"))
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
try:
|
try:
|
||||||
decodedName = (name.decode("latin1"))
|
decodedName = (name.decode("latin1"))
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
FreeCAD.Console.PrintError("svg: error: couldn't determine character encoding\n")
|
FreeCAD.Console.PrintError("svg: error: couldn't determine character encoding\n")
|
||||||
|
|
||||||
decodedName = name
|
decodedName = name
|
||||||
return decodedName
|
return decodedName
|
||||||
|
|
||||||
def getContents(filename,tag,stringmode=False):
|
def getContents(filename,tag,stringmode=False):
|
||||||
"gets the contents of all the occurences of the given tag in the given file"
|
"gets the contents of all the occurences of the given tag in the given file"
|
||||||
|
@ -1087,50 +1096,50 @@ def getContents(filename,tag,stringmode=False):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def open(filename):
|
def open(filename):
|
||||||
docname=os.path.split(filename)[1]
|
docname=os.path.split(filename)[1]
|
||||||
doc=FreeCAD.newDocument(docname)
|
doc=FreeCAD.newDocument(docname)
|
||||||
doc.Label = decodeName(docname[:-4])
|
doc.Label = decodeName(docname[:-4])
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
parser.setContentHandler(svgHandler())
|
parser.setContentHandler(svgHandler())
|
||||||
parser._cont_handler.doc = doc
|
parser._cont_handler.doc = doc
|
||||||
f = pythonopen(filename)
|
f = pythonopen(filename)
|
||||||
parser.parse(f)
|
parser.parse(f)
|
||||||
f.close()
|
f.close()
|
||||||
doc.recompute()
|
doc.recompute()
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
def insert(filename,docname):
|
def insert(filename,docname):
|
||||||
try:
|
try:
|
||||||
doc=FreeCAD.getDocument(docname)
|
doc=FreeCAD.getDocument(docname)
|
||||||
except:
|
except:
|
||||||
doc=FreeCAD.newDocument(docname)
|
doc=FreeCAD.newDocument(docname)
|
||||||
FreeCAD.ActiveDocument = doc
|
FreeCAD.ActiveDocument = doc
|
||||||
parser = xml.sax.make_parser()
|
parser = xml.sax.make_parser()
|
||||||
parser.setContentHandler(svgHandler())
|
parser.setContentHandler(svgHandler())
|
||||||
parser._cont_handler.doc = doc
|
parser._cont_handler.doc = doc
|
||||||
parser.parse(pythonopen(filename))
|
parser.parse(pythonopen(filename))
|
||||||
doc.recompute()
|
doc.recompute()
|
||||||
|
|
||||||
def export(exportList,filename):
|
def export(exportList,filename):
|
||||||
"called when freecad exports a file"
|
"called when freecad exports a file"
|
||||||
|
|
||||||
svg_export_style = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetInt("svg_export_style")
|
svg_export_style = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetInt("svg_export_style")
|
||||||
if svg_export_style != 0 and svg_export_style != 1:
|
if svg_export_style != 0 and svg_export_style != 1:
|
||||||
FreeCAD.Console.PrintMessage("unknown svg export style, switching to Translated\n")
|
FreeCAD.Console.PrintMessage("unknown svg export style, switching to Translated\n")
|
||||||
svg_export_style = 0
|
svg_export_style = 0
|
||||||
|
|
||||||
# finding sheet size
|
# finding sheet size
|
||||||
minx = 10000
|
minx = 10000
|
||||||
miny = 10000
|
miny = 10000
|
||||||
maxx = 0
|
maxx = 0
|
||||||
maxy = 0
|
maxy = 0
|
||||||
for ob in exportList:
|
for ob in exportList:
|
||||||
if ob.isDerivedFrom("Part::Feature"):
|
if ob.isDerivedFrom("Part::Feature"):
|
||||||
for v in ob.Shape.Vertexes:
|
for v in ob.Shape.Vertexes:
|
||||||
if v.Point.x < minx: minx = v.Point.x
|
if v.Point.x < minx: minx = v.Point.x
|
||||||
if v.Point.x > maxx: maxx = v.Point.x
|
if v.Point.x > maxx: maxx = v.Point.x
|
||||||
if v.Point.y < miny: miny = v.Point.y
|
if v.Point.y < miny: miny = v.Point.y
|
||||||
if v.Point.y > maxy: maxy = v.Point.y
|
if v.Point.y > maxy: maxy = v.Point.y
|
||||||
if svg_export_style == 0:
|
if svg_export_style == 0:
|
||||||
# translated-style exports get a bit of a margin
|
# translated-style exports get a bit of a margin
|
||||||
margin = (maxx-minx)*.01
|
margin = (maxx-minx)*.01
|
||||||
|
@ -1138,23 +1147,23 @@ def export(exportList,filename):
|
||||||
# raw-style exports get no margin
|
# raw-style exports get no margin
|
||||||
margin = 0
|
margin = 0
|
||||||
|
|
||||||
minx -= margin
|
minx -= margin
|
||||||
maxx += margin
|
maxx += margin
|
||||||
miny -= margin
|
miny -= margin
|
||||||
maxy += margin
|
maxy += margin
|
||||||
sizex = maxx-minx
|
sizex = maxx-minx
|
||||||
sizey = maxy-miny
|
sizey = maxy-miny
|
||||||
miny += margin
|
miny += margin
|
||||||
|
|
||||||
# writing header
|
# writing header
|
||||||
# we specify the svg width and height in FreeCAD's physical units (mm),
|
# we specify the svg width and height in FreeCAD's physical units (mm),
|
||||||
# and specify the viewBox so that user units maps one-to-one to mm
|
# and specify the viewBox so that user units maps one-to-one to mm
|
||||||
svg = pythonopen(filename,'wb')
|
svg = pythonopen(filename,'wb')
|
||||||
svg.write('<?xml version="1.0"?>\n')
|
svg.write('<?xml version="1.0"?>\n')
|
||||||
svg.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"')
|
svg.write('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"')
|
||||||
svg.write(' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
|
svg.write(' "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n')
|
||||||
svg.write('<svg')
|
svg.write('<svg')
|
||||||
svg.write(' width="' + str(sizex) + 'mm" height="' + str(sizey) + 'mm"')
|
svg.write(' width="' + str(sizex) + 'mm" height="' + str(sizey) + 'mm"')
|
||||||
if svg_export_style == 0:
|
if svg_export_style == 0:
|
||||||
# translated-style exports have the viewbox starting at X=0, Y=0
|
# translated-style exports have the viewbox starting at X=0, Y=0
|
||||||
svg.write(' viewBox="0 0 ' + str(sizex) + ' ' + str(sizey) + '"')
|
svg.write(' viewBox="0 0 ' + str(sizex) + ' ' + str(sizey) + '"')
|
||||||
|
@ -1163,11 +1172,11 @@ def export(exportList,filename):
|
||||||
# we need the funny Y here because SVG is upside down, and we
|
# we need the funny Y here because SVG is upside down, and we
|
||||||
# flip the sketch right-way up with a scale later
|
# flip the sketch right-way up with a scale later
|
||||||
svg.write(' viewBox="0 ' + str(sizey * -1.0) + ' ' + str(sizex) + ' ' + str(sizey) + '"')
|
svg.write(' viewBox="0 ' + str(sizey * -1.0) + ' ' + str(sizex) + ' ' + str(sizey) + '"')
|
||||||
svg.write(' xmlns="http://www.w3.org/2000/svg" version="1.1"')
|
svg.write(' xmlns="http://www.w3.org/2000/svg" version="1.1"')
|
||||||
svg.write('>\n')
|
svg.write('>\n')
|
||||||
|
|
||||||
# writing paths
|
# writing paths
|
||||||
for ob in exportList:
|
for ob in exportList:
|
||||||
if svg_export_style == 0:
|
if svg_export_style == 0:
|
||||||
# translated-style exports have the entire sketch translated to fit in the X>0, Y>0 quadrant
|
# translated-style exports have the entire sketch translated to fit in the X>0, Y>0 quadrant
|
||||||
svg.write('<g transform="translate('+str(-minx)+','+str(-miny+(2*margin))+') scale(1,-1)">\n')
|
svg.write('<g transform="translate('+str(-minx)+','+str(-miny+(2*margin))+') scale(1,-1)">\n')
|
||||||
|
@ -1177,6 +1186,6 @@ def export(exportList,filename):
|
||||||
svg.write(Draft.getSVG(ob))
|
svg.write(Draft.getSVG(ob))
|
||||||
svg.write('</g>\n')
|
svg.write('</g>\n')
|
||||||
|
|
||||||
# closing
|
# closing
|
||||||
svg.write('</svg>')
|
svg.write('</svg>')
|
||||||
svg.close()
|
svg.close()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user