Draft: importSVG.py, improved Python style, spacing around commas
This commit is contained in:
@@ -246,36 +246,36 @@ def getcolor(color):
|
||||
if (color[0] == "#"):
|
||||
# Color string '#12ab9f'
|
||||
if len(color) == 7:
|
||||
r = float(int(color[1:3],16)/255.0)
|
||||
g = float(int(color[3:5],16)/255.0)
|
||||
b = float(int(color[5:],16)/255.0)
|
||||
r = float(int(color[1:3], 16)/255.0)
|
||||
g = float(int(color[3:5], 16)/255.0)
|
||||
b = float(int(color[5:], 16)/255.0)
|
||||
# Color string '#1af'
|
||||
elif len(color) == 4:
|
||||
# Expand the hex digits
|
||||
r = float(int(color[1],16)*17/255.0)
|
||||
g = float(int(color[2],16)*17/255.0)
|
||||
b = float(int(color[3],16)*17/255.0)
|
||||
return (r,g,b,0.0)
|
||||
r = float(int(color[1], 16)*17/255.0)
|
||||
g = float(int(color[2], 16)*17/255.0)
|
||||
b = float(int(color[3], 16)*17/255.0)
|
||||
return (r, g, b, 0.0)
|
||||
# Color string 'rgb(0.12,0.23,0.3,0.0)'
|
||||
elif color.lower().startswith('rgb('):
|
||||
cvalues=color[3:].lstrip('(').rstrip(')').replace('%','').split(',')
|
||||
cvalues = color[3:].lstrip('(').rstrip(')').replace('%', '').split(',')
|
||||
if '%' in color:
|
||||
r,g,b = [int(float(cv))/100.0 for cv in cvalues]
|
||||
r, g, b = [int(float(cv))/100.0 for cv in cvalues]
|
||||
else:
|
||||
r,g,b = [int(float(cv))/255.0 for cv in cvalues]
|
||||
return (r,g,b,0.0)
|
||||
r, g, b = [int(float(cv))/255.0 for cv in cvalues]
|
||||
return (r, g, b, 0.0)
|
||||
# Color string 'MediumAquamarine'
|
||||
else:
|
||||
v=svgcolorslower.get(color.lower())
|
||||
v = svgcolorslower.get(color.lower())
|
||||
if v:
|
||||
r,g,b = [float(vf)/255.0 for vf in v]
|
||||
return (r,g,b,0.0)
|
||||
#for k,v in svgcolors.items():
|
||||
r, g, b = [float(vf)/255.0 for vf in v]
|
||||
return (r, g, b, 0.0)
|
||||
# for k,v in svgcolors.items():
|
||||
# if (k.lower() == color.lower()):
|
||||
# pass
|
||||
|
||||
|
||||
def transformCopyShape(shape,m):
|
||||
def transformCopyShape(shape, m):
|
||||
"""Apply transformation matrix m on given shape.
|
||||
|
||||
Since OCCT 6.8.0 transformShape can be used to apply certain
|
||||
@@ -301,7 +301,7 @@ def transformCopyShape(shape,m):
|
||||
if abs(m.A11**2+m.A12**2 -m.A21**2-m.A22**2) < 1e-8 and \
|
||||
abs(m.A11*m.A21+m.A12*m.A22) < 1e-8:
|
||||
try:
|
||||
newshape=shape.copy()
|
||||
newshape = shape.copy()
|
||||
newshape.transformShape(m)
|
||||
return newshape
|
||||
# Older versions of OCCT will refuse to work on
|
||||
@@ -311,7 +311,7 @@ def transformCopyShape(shape,m):
|
||||
return shape.transformGeometry(m)
|
||||
|
||||
|
||||
def getsize(length,mode='discard',base=1):
|
||||
def getsize(length, mode='discard', base=1):
|
||||
"""Parse the length string containing number and unit.
|
||||
|
||||
Parameters
|
||||
@@ -400,13 +400,13 @@ def getsize(length,mode='discard',base=1):
|
||||
'%': 100 #arbitrarily chosen; has to depend on viewport size or (for filling patterns) on bounding box
|
||||
}
|
||||
# Extract a number from a string like '+56215.14565E+6mm'
|
||||
number, exponent, unit=re.findall('([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(px|pt|pc|mm|cm|in|em|ex|%)?',length)[0]
|
||||
if mode =='discard':
|
||||
number, exponent, unit = re.findall('([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)(px|pt|pc|mm|cm|in|em|ex|%)?',length)[0]
|
||||
if mode == 'discard':
|
||||
return float(number)
|
||||
elif mode == 'tuple':
|
||||
return float(number),unit
|
||||
return float(number), unit
|
||||
elif mode == 'isabsolute':
|
||||
return unit in ('mm','cm','in','px','pt')
|
||||
return unit in ('mm', 'cm', 'in', 'px', 'pt')
|
||||
elif mode == 'mm96.0' or mode == 'mm90.0':
|
||||
return float(number)*tomm[unit]
|
||||
elif mode == 'css96.0' or mode == 'css90.0':
|
||||
@@ -416,7 +416,7 @@ def getsize(length,mode='discard',base=1):
|
||||
return float(number)*base
|
||||
|
||||
|
||||
def makewire(path,checkclosed=False,donttry=False):
|
||||
def makewire(path, checkclosed=False, donttry=False):
|
||||
'''Try to make a wire out of the list of edges.
|
||||
|
||||
If the wire functions fails or the wire is not closed,
|
||||
@@ -454,7 +454,7 @@ def makewire(path,checkclosed=False,donttry=False):
|
||||
if donttry or not isok:
|
||||
#Code from wmayer forum p15549 to fix the tolerance problem
|
||||
#original tolerance = 0.00001
|
||||
comp=Part.Compound(path)
|
||||
comp = Part.Compound(path)
|
||||
sh = comp.connectEdgesToWires(False,10**(-1*(Draft.precision()-2))).Wires[0]
|
||||
if len(sh.Edges) != len(path):
|
||||
FreeCAD.Console.PrintWarning("Unable to form a wire\n")
|
||||
@@ -462,7 +462,7 @@ def makewire(path,checkclosed=False,donttry=False):
|
||||
return sh
|
||||
|
||||
|
||||
def arccenter2end(center,rx,ry,angle1,angledelta,xrotation=0.0):
|
||||
def arccenter2end(center, rx, ry, angle1, angledelta, xrotation=0.0):
|
||||
'''Calculate start and end points, and flags of an arc.
|
||||
|
||||
Calculate start and end points, and flags of an arc given in
|
||||
@@ -491,18 +491,19 @@ def arccenter2end(center,rx,ry,angle1,angledelta,xrotation=0.0):
|
||||
indicating whether the arc is less than 180 degrees or not,
|
||||
and whether the angledelta is negative.
|
||||
'''
|
||||
vr1=Vector(rx*math.cos(angle1),ry*math.sin(angle1),0)
|
||||
vr2=Vector(rx*math.cos(angle1+angledelta),ry*math.sin(angle1+angledelta),0)
|
||||
mxrot=FreeCAD.Matrix()
|
||||
vr1 = Vector(rx*math.cos(angle1), ry*math.sin(angle1), 0)
|
||||
vr2 = Vector(rx*math.cos(angle1+angledelta), ry*math.sin(angle1+angledelta), 0)
|
||||
mxrot = FreeCAD.Matrix()
|
||||
mxrot.rotateZ(xrotation)
|
||||
v1 = mxrot.multiply(vr1).add(center)
|
||||
v2 = mxrot.multiply(vr2).add(center)
|
||||
fa = ((abs(angledelta) / math.pi) % 2) > 1 # <180deg
|
||||
fs = angledelta < 0
|
||||
return v1,v2,fa,fs
|
||||
return v1, v2, fa, fs
|
||||
|
||||
|
||||
def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
|
||||
def arcend2center(lastvec, currentvec, rx, ry,
|
||||
xrotation=0.0, correction=False):
|
||||
'''Calculate the possible centers for an arc in endpoint parameterization.
|
||||
|
||||
Calculate (positive and negative) possible centers for an arc given in
|
||||
@@ -548,9 +549,9 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
|
||||
ry = float(ry)
|
||||
v0 = lastvec.sub(currentvec)
|
||||
v0.multiply(0.5)
|
||||
m1=FreeCAD.Matrix()
|
||||
m1 = FreeCAD.Matrix()
|
||||
m1.rotateZ(-xrotation) #Formular 6.5.1
|
||||
v1=m1.multiply(v0)
|
||||
v1 = m1.multiply(v0)
|
||||
if correction:
|
||||
eparam = v1.x**2 / rx**2 + v1.y**2 / ry**2
|
||||
if eparam > 1:
|
||||
@@ -559,7 +560,7 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
|
||||
ry = eproot * ry
|
||||
denom = rx**2 * v1.y**2+ ry**2 * v1.x**2
|
||||
numer = rx**2 * ry**2 -denom
|
||||
results=[]
|
||||
results = []
|
||||
|
||||
# If the division is very small, set the scaling factor to zero,
|
||||
# otherwise try to calculate it by taking the square root
|
||||
@@ -572,11 +573,11 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
|
||||
FreeCAD.Console.PrintMessage('sqrt(%f/%f)\n' % (numer,denom))
|
||||
scalefacpos = 0
|
||||
# Calculate two values because the square root may be positive or negative
|
||||
for scalefacsign in (1,-1):
|
||||
for scalefacsign in (1, -1):
|
||||
scalefac = scalefacpos * scalefacsign
|
||||
# Step2 F.6.5.2
|
||||
vcx1 = Vector(v1.y*rx/ry,-v1.x*ry/rx,0).multiply(scalefac)
|
||||
m2=FreeCAD.Matrix()
|
||||
m2 = FreeCAD.Matrix()
|
||||
m2.rotateZ(xrotation)
|
||||
centeroff = currentvec.add(lastvec)
|
||||
centeroff.multiply(.5)
|
||||
@@ -590,10 +591,18 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
|
||||
# (-v1.y - vcx1.y) / ry,
|
||||
# 0)) # F.6.5.6
|
||||
# we need the right sign for the angle
|
||||
angle1 = DraftVecUtils.angle(Vector(1,0,0),Vector((v1.x-vcx1.x)/rx,(v1.y-vcx1.y)/ry,0)) # F.6.5.5
|
||||
angledelta = DraftVecUtils.angle(Vector((v1.x-vcx1.x)/rx,(v1.y-vcx1.y)/ry,0),Vector((-v1.x-vcx1.x)/rx,(-v1.y-vcx1.y)/ry,0)) # F.6.5.6
|
||||
results.append((vcenter,angle1,angledelta))
|
||||
return results,(rx,ry)
|
||||
angle1 = DraftVecUtils.angle(Vector(1, 0, 0),
|
||||
Vector((v1.x-vcx1.x)/rx,
|
||||
(v1.y-vcx1.y)/ry,
|
||||
0)) # F.6.5.5
|
||||
angledelta = DraftVecUtils.angle(Vector((v1.x-vcx1.x)/rx,
|
||||
(v1.y-vcx1.y)/ry,
|
||||
0),
|
||||
Vector((-v1.x-vcx1.x)/rx,
|
||||
(-v1.y-vcx1.y)/ry,
|
||||
0)) # F.6.5.6
|
||||
results.append((vcenter, angle1, angledelta))
|
||||
return results, (rx, ry)
|
||||
|
||||
|
||||
def getrgb(color):
|
||||
@@ -646,7 +655,7 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
r = float(((c>>24)&0xFF)/255)
|
||||
g = float(((c>>16)&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):
|
||||
"""Apply styles to the object if the graphical interface is up."""
|
||||
@@ -671,17 +680,17 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
Dictionary of content of the elements
|
||||
"""
|
||||
self.count += 1
|
||||
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('processing element %d: %s\n'% (self.count, name))
|
||||
FreeCAD.Console.PrintMessage('existing group transform: %s\n'% (str(self.grouptransform)))
|
||||
|
||||
data = {}
|
||||
for (keyword,content) in list(attrs.items()):
|
||||
for (keyword, content) in list(attrs.items()):
|
||||
#print keyword,content
|
||||
if keyword != "style":
|
||||
content = content.replace(',',' ')
|
||||
content = content.split()
|
||||
#print keyword,content
|
||||
data[keyword]=content
|
||||
data[keyword] = content
|
||||
|
||||
# If it's the first element, which is <svg>,
|
||||
# check if the file is created by Inkscape, and its version,
|
||||
@@ -710,8 +719,8 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
self.svgdpi = 96.0
|
||||
if not 'inkscape:version' in data:
|
||||
msgBox = QtGui.QMessageBox()
|
||||
msgBox.setText(translate("ImportSVG","This SVG file does not appear to have been produced by Inkscape. If it does not contain absolute units then a DPI setting will be used."))
|
||||
msgBox.setInformativeText(translate("ImportSVG","Do you wish to use 96dpi? Choosing 'No' will revert to the older standard 90dpi"))
|
||||
msgBox.setText(translate("ImportSVG", "This SVG file does not appear to have been produced by Inkscape. If it does not contain absolute units then a DPI setting will be used."))
|
||||
msgBox.setInformativeText(translate("ImportSVG", "Do you wish to use 96dpi? Choosing 'No' will revert to the older standard 90dpi"))
|
||||
msgBox.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
|
||||
msgBox.setDefaultButton(QtGui.QMessageBox.No)
|
||||
ret = msgBox.exec_()
|
||||
@@ -730,25 +739,25 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
# Empty style attribute stops inheriting from parent
|
||||
pass
|
||||
else:
|
||||
content = data['style'].replace(' ','')
|
||||
content = data['style'].replace(' ', '')
|
||||
content = content.split(';')
|
||||
for i in content:
|
||||
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:
|
||||
data[k] = getsize(data[k][0],'css'+str(self.svgdpi))
|
||||
|
||||
for k in ['fill','stroke','stroke-width','font-size']:
|
||||
for k in ['fill', 'stroke', 'stroke-width', 'font-size']:
|
||||
if k in data:
|
||||
if isinstance(data[k],list):
|
||||
if isinstance(data[k], list):
|
||||
if data[k][0].lower().startswith("rgb("):
|
||||
data[k] = ",".join(data[k])
|
||||
else:
|
||||
data[k]=data[k][0]
|
||||
data[k] = data[k][0]
|
||||
|
||||
# Extract style info
|
||||
self.fill = None
|
||||
@@ -757,43 +766,43 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
self.text = None
|
||||
|
||||
if name == 'svg':
|
||||
m=FreeCAD.Matrix()
|
||||
m = FreeCAD.Matrix()
|
||||
if not self.disableUnitScaling:
|
||||
if 'width' in data \
|
||||
and 'height' in data \
|
||||
and 'viewBox' in data:
|
||||
vbw=float(data['viewBox'][2])
|
||||
vbh=float(data['viewBox'][3])
|
||||
w=attrs.getValue('width')
|
||||
h=attrs.getValue('height')
|
||||
self.viewbox=(vbw,vbh)
|
||||
if len(self.grouptransform)==0:
|
||||
unitmode='mm'+str(self.svgdpi)
|
||||
vbw = float(data['viewBox'][2])
|
||||
vbh = float(data['viewBox'][3])
|
||||
w = attrs.getValue('width')
|
||||
h = attrs.getValue('height')
|
||||
self.viewbox = (vbw, vbh)
|
||||
if len(self.grouptransform) == 0:
|
||||
unitmode = 'mm'+str(self.svgdpi)
|
||||
else:
|
||||
# nested svg element
|
||||
unitmode='css'+str(self.svgdpi)
|
||||
abw = getsize(w,unitmode)
|
||||
abh = getsize(h,unitmode)
|
||||
sx=abw/vbw
|
||||
sy=abh/vbh
|
||||
preservearstr=' '.join(data.get('preserveAspectRatio',[])).lower()
|
||||
uniformscaling = round(sx/sy,5) == 1
|
||||
unitmode = 'css'+str(self.svgdpi)
|
||||
abw = getsize(w, unitmode)
|
||||
abh = getsize(h, unitmode)
|
||||
sx = abw/vbw
|
||||
sy = abh/vbh
|
||||
preservearstr = ' '.join(data.get('preserveAspectRatio', [])).lower()
|
||||
uniformscaling = round(sx/sy, 5) == 1
|
||||
if uniformscaling:
|
||||
m.scale(Vector(sx,sy,1))
|
||||
m.scale(Vector(sx, sy, 1))
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning('Scaling Factors do not match!!!\n')
|
||||
if preservearstr.startswith('none'):
|
||||
m.scale(Vector(sx,sy,1))
|
||||
m.scale(Vector(sx, sy, 1))
|
||||
else:
|
||||
# preserve the aspect ratio
|
||||
if preservearstr.endswith('slice'):
|
||||
sxy=max(sx,sy)
|
||||
sxy = max(sx, sy)
|
||||
else:
|
||||
sxy=min(sx,sy)
|
||||
m.scale(Vector(sxy,sxy,1))
|
||||
elif len(self.grouptransform)==0:
|
||||
sxy = min(sx, sy)
|
||||
m.scale(Vector(sxy, sxy, 1))
|
||||
elif len(self.grouptransform) == 0:
|
||||
# fallback to current dpi
|
||||
m.scale(Vector(25.4/self.svgdpi,25.4/self.svgdpi,1))
|
||||
m.scale(Vector(25.4/self.svgdpi, 25.4/self.svgdpi, 1))
|
||||
self.grouptransform.append(m)
|
||||
if 'fill' in data:
|
||||
if data['fill'][0] != 'none':
|
||||
@@ -833,7 +842,7 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
|
||||
path = []
|
||||
point = []
|
||||
lastvec = Vector(0,0,0)
|
||||
lastvec = Vector(0, 0, 0)
|
||||
lastpole = None
|
||||
command = None
|
||||
relative = False
|
||||
@@ -841,92 +850,97 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
|
||||
if "freecad:basepoint1" in data:
|
||||
p1 = data["freecad:basepoint1"]
|
||||
p1 = Vector(float(p1[0]),-float(p1[1]),0)
|
||||
p1 = Vector(float(p1[0]), -float(p1[1]), 0)
|
||||
p2 = data["freecad:basepoint2"]
|
||||
p2 = Vector(float(p2[0]),-float(p2[1]),0)
|
||||
p2 = Vector(float(p2[0]), -float(p2[1]), 0)
|
||||
p3 = data["freecad:dimpoint"]
|
||||
p3 = Vector(float(p3[0]),-float(p3[1]),0)
|
||||
obj = Draft.makeDimension(p1,p2,p3)
|
||||
p3 = Vector(float(p3[0]), -float(p3[1]), 0)
|
||||
obj = Draft.makeDimension(p1, p2, p3)
|
||||
self.applyTrans(obj)
|
||||
self.format(obj)
|
||||
self.lastdim = obj
|
||||
data['d']=[]
|
||||
data['d'] = []
|
||||
|
||||
pathcommandsre=re.compile('\s*?([mMlLhHvVaAcCqQsStTzZ])\s*?([^mMlLhHvVaAcCqQsStTzZ]*)\s*?',re.DOTALL)
|
||||
pointsre=re.compile('([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)',re.DOTALL)
|
||||
for d,pointsstr in pathcommandsre.findall(' '.join(data['d'])):
|
||||
pathcommandsre = re.compile('\s*?([mMlLhHvVaAcCqQsStTzZ])\s*?([^mMlLhHvVaAcCqQsStTzZ]*)\s*?', re.DOTALL)
|
||||
pointsre = re.compile('([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)', re.DOTALL)
|
||||
for d, pointsstr in pathcommandsre.findall(' '.join(data['d'])):
|
||||
relative = d.islower()
|
||||
pointlist = [float(number) for number,exponent in pointsre.findall(pointsstr.replace(',',' '))]
|
||||
pointlist = [float(number) for number, exponent in pointsre.findall(pointsstr.replace(',', ' '))]
|
||||
|
||||
if (d == "M" or d == "m"):
|
||||
x = pointlist.pop(0)
|
||||
y = pointlist.pop(0)
|
||||
if path:
|
||||
#sh = Part.Wire(path)
|
||||
# sh = Part.Wire(path)
|
||||
sh = makewire(path)
|
||||
if self.fill and sh.isClosed():
|
||||
sh = Part.Face(sh)
|
||||
sh = self.applyTrans(sh)
|
||||
obj = self.doc.addObject("Part::Feature",pathname)
|
||||
obj = self.doc.addObject("Part::Feature", pathname)
|
||||
obj.Shape = sh
|
||||
self.format(obj)
|
||||
if self.currentsymbol:
|
||||
self.symbols[self.currentsymbol].append(obj)
|
||||
path = []
|
||||
# if firstvec:
|
||||
# Move relative to last move command
|
||||
# not last draw command
|
||||
# Move relative to last move command
|
||||
# not last draw command
|
||||
# lastvec = firstvec
|
||||
if relative:
|
||||
lastvec = lastvec.add(Vector(x,-y,0))
|
||||
lastvec = lastvec.add(Vector(x, -y, 0))
|
||||
else:
|
||||
lastvec = Vector(x,-y,0)
|
||||
lastvec = Vector(x, -y, 0)
|
||||
firstvec = lastvec
|
||||
FreeCAD.Console.PrintMessage('move %s\n'%str(lastvec))
|
||||
lastpole = None
|
||||
|
||||
if (d == "L" or d == "l") or \
|
||||
((d == 'm' or d == 'M') and pointlist) :
|
||||
for x,y in zip(pointlist[0::2],pointlist[1::2]):
|
||||
for x, y in zip(pointlist[0::2], pointlist[1::2]):
|
||||
if relative:
|
||||
currentvec = lastvec.add(Vector(x,-y,0))
|
||||
currentvec = lastvec.add(Vector(x, -y, 0))
|
||||
else:
|
||||
currentvec = Vector(x,-y,0)
|
||||
if not DraftVecUtils.equals(lastvec,currentvec):
|
||||
seg = Part.LineSegment(lastvec,currentvec).toShape()
|
||||
FreeCAD.Console.PrintMessage("line %s %s\n" %(lastvec,currentvec))
|
||||
currentvec = Vector(x, -y, 0)
|
||||
if not DraftVecUtils.equals(lastvec, currentvec):
|
||||
seg = Part.LineSegment(lastvec, currentvec).toShape()
|
||||
FreeCAD.Console.PrintMessage("line %s %s\n" % (lastvec, currentvec))
|
||||
lastvec = currentvec
|
||||
path.append(seg)
|
||||
lastpole = None
|
||||
elif (d == "H" or d == "h"):
|
||||
for x in pointlist:
|
||||
if relative:
|
||||
currentvec = lastvec.add(Vector(x,0,0))
|
||||
currentvec = lastvec.add(Vector(x, 0, 0))
|
||||
else:
|
||||
currentvec = Vector(x,lastvec.y,0)
|
||||
seg = Part.LineSegment(lastvec,currentvec).toShape()
|
||||
currentvec = Vector(x, lastvec.y, 0)
|
||||
seg = Part.LineSegment(lastvec, currentvec).toShape()
|
||||
lastvec = currentvec
|
||||
lastpole = None
|
||||
path.append(seg)
|
||||
elif (d == "V" or d == "v"):
|
||||
for y in pointlist:
|
||||
if relative:
|
||||
currentvec = lastvec.add(Vector(0,-y,0))
|
||||
currentvec = lastvec.add(Vector(0, -y, 0))
|
||||
else:
|
||||
currentvec = Vector(lastvec.x,-y,0)
|
||||
currentvec = Vector(lastvec.x, -y, 0)
|
||||
if lastvec!=currentvec:
|
||||
seg = Part.LineSegment(lastvec,currentvec).toShape()
|
||||
seg = Part.LineSegment(lastvec, currentvec).toShape()
|
||||
lastvec = currentvec
|
||||
lastpole = None
|
||||
path.append(seg)
|
||||
elif (d == "A" or d == "a"):
|
||||
for rx,ry,xrotation, largeflag, sweepflag,x,y in \
|
||||
zip(pointlist[0::7],pointlist[1::7],pointlist[2::7],pointlist[3::7],pointlist[4::7],pointlist[5::7],pointlist[6::7]):
|
||||
piter = zip(pointlist[0::7], pointlist[1::7],
|
||||
pointlist[2::7], pointlist[3::7],
|
||||
pointlist[4::7], pointlist[5::7],
|
||||
pointlist[6::7])
|
||||
for (rx, ry, xrotation,
|
||||
largeflag, sweepflag,
|
||||
x, y) in piter:
|
||||
#support for large-arc and x-rotation are missing
|
||||
if relative:
|
||||
currentvec = lastvec.add(Vector(x,-y,0))
|
||||
currentvec = lastvec.add(Vector(x, -y, 0))
|
||||
else:
|
||||
currentvec = Vector(x,-y,0)
|
||||
currentvec = Vector(x, -y, 0)
|
||||
chord = currentvec.sub(lastvec)
|
||||
# small circular arc
|
||||
if (not largeflag) and abs(rx-ry) < 10**(-1*Draft.precision()):
|
||||
@@ -934,34 +948,39 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
# here is a better way to find the perpendicular
|
||||
if sweepflag == 1:
|
||||
# clockwise
|
||||
perp = DraftVecUtils.rotate2D(chord,-math.pi/2)
|
||||
perp = DraftVecUtils.rotate2D(chord, -math.pi/2)
|
||||
else:
|
||||
# anticlockwise
|
||||
perp = DraftVecUtils.rotate2D(chord,math.pi/2)
|
||||
perp = DraftVecUtils.rotate2D(chord, math.pi/2)
|
||||
chord.multiply(.5)
|
||||
if chord.Length > rx: a = 0
|
||||
else: a = math.sqrt(rx**2-chord.Length**2)
|
||||
if chord.Length > rx:
|
||||
a = 0
|
||||
else:
|
||||
a = math.sqrt(rx**2-chord.Length**2)
|
||||
s = rx - a
|
||||
perp.multiply(s/perp.Length)
|
||||
midpoint = lastvec.add(chord.add(perp))
|
||||
seg = Part.Arc(lastvec,midpoint,currentvec).toShape()
|
||||
seg = Part.Arc(lastvec, midpoint, currentvec).toShape()
|
||||
# big arc or elliptical arc
|
||||
else:
|
||||
# Calculate the possible centers for an arc
|
||||
# in 'endpoint parameterization'.
|
||||
solution,(rx,ry) = arcend2center(lastvec,currentvec,rx,ry,math.radians(-xrotation),True)
|
||||
solution, (rx, ry) = arcend2center(lastvec, currentvec,
|
||||
rx, ry,
|
||||
xrotation=math.radians(-xrotation),
|
||||
correction=True)
|
||||
# Chose one of the two solutions
|
||||
negsol = (largeflag != sweepflag)
|
||||
vcenter,angle1,angledelta = solution[negsol]
|
||||
vcenter, angle1, angledelta = solution[negsol]
|
||||
#print angle1
|
||||
#print angledelta
|
||||
if ry > rx:
|
||||
rx,ry=ry,rx
|
||||
rx, ry = ry, rx
|
||||
swapaxis = True
|
||||
else:
|
||||
swapaxis = False
|
||||
#print 'Elliptical arc %s rx=%f ry=%f' % (vcenter,rx,ry)
|
||||
e1 = Part.Ellipse(vcenter,rx,ry)
|
||||
e1 = Part.Ellipse(vcenter, rx, ry)
|
||||
if sweepflag:
|
||||
#angledelta=-(-angledelta % (math.pi *2)) # Step4
|
||||
#angledelta=(-angledelta % (math.pi *2)) # Step4
|
||||
@@ -969,17 +988,18 @@ class svgHandler(xml.sax.ContentHandler):
|
||||
angledelta = -angledelta
|
||||
#angle1 = math.pi - angle1
|
||||
|
||||
e1a = Part.Arc(e1,angle1-swapaxis*math.radians(90),\
|
||||
angle1+angledelta-swapaxis*math.radians(90))
|
||||
e1a = Part.Arc(e1,
|
||||
angle1-swapaxis*math.radians(90),
|
||||
angle1+angledelta-swapaxis*math.radians(90))
|
||||
#e1a = Part.Arc(e1,angle1-0*swapaxis*math.radians(90),angle1+angledelta-0*swapaxis*math.radians(90))
|
||||
if swapaxis or xrotation > 10**(-1*Draft.precision()):
|
||||
m3=FreeCAD.Matrix()
|
||||
m3 = FreeCAD.Matrix()
|
||||
m3.move(vcenter)
|
||||
# 90
|
||||
rot90=FreeCAD.Matrix(0,-1,0,0,1,0)
|
||||
rot90 = FreeCAD.Matrix(0, -1, 0, 0, 1, 0)
|
||||
#swapaxism=FreeCAD.Matrix(0,1,0,0,1,0)
|
||||
if swapaxis:
|
||||
m3=m3.multiply(rot90)
|
||||
m3 = m3.multiply(rot90)
|
||||
m3.rotateZ(math.radians(-xrotation))
|
||||
m3.move(vcenter.multiply(-1))
|
||||
e1a.transform(m3)
|
||||
|
||||
Reference in New Issue
Block a user