Draft: importSVG.py, improved docstrings, and comments

This commit is contained in:
vocx-fc
2019-07-31 19:42:29 -05:00
committed by Yorik van Havre
parent f58858c478
commit 97a648ba3c

View File

@@ -401,9 +401,31 @@ def getsize(length,mode='discard',base=1):
else:
return float(number)*base
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 if required the 'connectEdgesToWires' function is used'''
'''Try to make a wire out of the list of edges.
If the wire functions fails or the wire is not closed,
if required the TopoShapeCompoundPy::connectEdgesToWires()
function is used.
Parameters
----------
path : Part.Edge
A collection of edges
checkclosed : bool, optional
Default is `False`.
donttry : bool, optional
Default is `False`. If it's `True` it won't try to check
for a closed path.
Returns
-------
Part::Wire
A wire created from the ordered edges.
Part::Compound
A compound made of the edges, but unable to form a wire.
'''
if not donttry:
try:
import Part
@@ -424,10 +446,36 @@ def makewire(path,checkclosed=False,donttry=False):
sh = comp
return sh
def arccenter2end(center,rx,ry,angle1,angledelta,xrotation=0.0):
'''calculate start and end vector and flags of an arc given in center parametrization
see http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
returns (v1,v2,largerc,sweep)'''
'''Calculate start and end points, and flags of an arc.
Calculate start and end points, and flags of an arc given in
``center parametrization``.
See http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
Parameters
----------
center : Base::Vector3
Coordinates of the center of the ellipse.
rx : float
Radius of the ellipse, semi-major axis in the X direction
ry : float
Radius of the ellipse, semi-minor axis in the Y direction
angle1 : float
Initial angle in radians
angledelta : float
Additional angle in radians
xrotation : float, optional
Default 0. Rotation around the Z axis
Returns
-------
v1, v2, largerc, sweep
Tuple indicating the end points of the arc, and two boolean values
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()
@@ -438,13 +486,49 @@ def arccenter2end(center,rx,ry,angle1,angledelta,xrotation=0.0):
fs = angledelta < 0
return v1,v2,fa,fs
def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
'''calculate (positive and negative) possible centers for an arc in endpoint parameterization
see http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
rotation or x-axis has to be specified in radians (CCW)
the sweepflag is interpreted as: sweepflag <==> arc is travelled clockwise
returns [(vcenter+,angle1+,angledelta+),(...-)]'''
#scalefacsign = 1 if (largeflag != sweepflag) else -1
'''Calculate the possible centers for an arc in endpoint parameterization.
Calculate (positive and negative) possible centers for an arc given in
``endpoint parametrization``.
See http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
the sweepflag is interpreted as: sweepflag <==> arc is travelled clockwise
Parameters
----------
lastvec : Base::Vector3
First point of the arc.
currentvec : Base::Vector3
End point (current) of the arc.
rx : float
Radius of the ellipse, semi-major axis in the X direction.
ry : float
Radius of the ellipse, semi-minor axis in the Y direction.
xrotation : float, optional
Default is 0. Rotation around the Z axis, in radians (CCW).
correction : bool, optional
Default is `False`. If it is `True`, the radii will be scaled
by a factor.
Returns
-------
list, (float, float)
A tuple that consists of one list, and a tuple of radii.
[(positive), (negative)], (rx, ry)
The first element of the list is the positive tuple,
the second is the negative tuple.
[(Base::Vector3, float, float),
(Base::Vector3, float, float)], (float, float)
Types
[(vcenter+, angle1+, angledelta+),
(vcenter-, angle1-, angledelta-)], (rx, ry)
The first element of the list is the positive tuple,
consisting of center, angle, and angle increment;
the second element is the negative tuple.
'''
# scalefacsign = 1 if (largeflag != sweepflag) else -1
rx = float(rx)
ry = float(ry)
v0 = lastvec.sub(currentvec)
@@ -461,6 +545,9 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
denom = rx**2 * v1.y**2+ ry**2 * v1.x**2
numer = rx**2 * ry**2 -denom
results=[]
# If the division is very small, set the scaling factor to zero,
# otherwise try to calculate it by taking the square root
if abs(numer/denom) < 10**(-1*(Draft.precision())):
scalefacpos = 0
else:
@@ -469,17 +556,25 @@ def arcend2center(lastvec,currentvec,rx,ry,xrotation=0.0,correction=False):
except ValueError:
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):
scalefac = scalefacpos * scalefacsign
vcx1 = Vector(v1.y*rx/ry,-v1.x*ry/rx,0).multiply(scalefac) # Step2 F.6.5.2
# Step2 F.6.5.2
vcx1 = Vector(v1.y*rx/ry,-v1.x*ry/rx,0).multiply(scalefac)
m2=FreeCAD.Matrix()
m2.rotateZ(xrotation)
centeroff = currentvec.add(lastvec)
centeroff.multiply(.5)
vcenter = m2.multiply(vcx1).add(centeroff) # Step3 F.6.5.3
#angle1 = Vector(1,0,0).getAngle(Vector((v1.x-vcx1.x)/rx,(v1.y-vcx1.y)/ry,0)) # F.6.5.5
#angledelta = Vector((v1.x-vcx1.x)/rx,(v1.y-vcx1.y)/ry,0).getAngle(Vector((-v1.x-vcx1.x)/rx,(-v1.y-vcx1.y)/ry,0)) # F.6.5.6
#we need the right sign for the angle
# angle1 = Vector(1, 0, 0).getAngle(Vector((v1.x - vcx1.x) / rx,
# (v1.y - vcx1.y) / ry,
# 0)) # F.6.5.5
# angledelta = Vector((v1.x - vcx1.x) / rx,
# (v1.y - vcx1.y) / ry,
# 0).getAngle(Vector((-v1.x - vcx1.x) / rx,
# (-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))