6 from __future__ import absolute_import
7 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
10 from fabmetheus_utilities.geometry.creation import lineation
11 from fabmetheus_utilities.geometry.geometry_tools import path
12 from fabmetheus_utilities.geometry.geometry_utilities import evaluate
13 from fabmetheus_utilities.vector3 import Vector3
14 from fabmetheus_utilities import euclidean
18 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
19 __credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
20 __date__ = '$Date: 2008/02/05 $'
21 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
24 def getGeometryOutput(derivation, elementNode):
25 "Get vector3 vertexes from attribute dictionary."
26 if derivation == None:
27 derivation = CircleDerivation(elementNode)
28 angleTotal = math.radians(derivation.start)
30 sidesCeiling = int(math.ceil(abs(derivation.sides) * derivation.extent / 360.0))
31 sideAngle = math.radians(derivation.extent) / sidesCeiling
32 if derivation.sides < 0.0:
33 sideAngle = -sideAngle
34 spiral = lineation.Spiral(derivation.spiral, 0.5 * sideAngle / math.pi)
35 for side in xrange(sidesCeiling + 1):
36 unitPolar = euclidean.getWiddershinsUnitPolar(angleTotal)
37 x = unitPolar.real * derivation.radiusArealized.real
38 y = unitPolar.imag * derivation.radiusArealized.imag
39 vertex = spiral.getSpiralPoint(unitPolar, Vector3(x, y))
40 angleTotal += sideAngle
42 radiusMaximum = 0.000001 * max(derivation.radiusArealized.real, derivation.radiusArealized.imag)
43 loop = euclidean.getLoopWithoutCloseEnds(radiusMaximum, loop)
44 lineation.setClosedAttribute(elementNode, derivation.revolutions)
45 return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop, sideAngle))
47 def getGeometryOutputByArguments(arguments, elementNode):
48 "Get vector3 vertexes from attribute dictionary by arguments."
49 evaluate.setAttributesByArguments(['radius', 'start', 'end', 'revolutions'], arguments, elementNode)
50 return getGeometryOutput(None, elementNode)
52 def getNewDerivation(elementNode):
54 return CircleDerivation(elementNode)
56 def processElementNode(elementNode):
57 "Process the xml element."
58 path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
61 class CircleDerivation:
62 "Class to hold circle variables."
63 def __init__(self, elementNode):
65 self.radius = lineation.getRadiusComplex(elementNode, complex(1.0, 1.0))
66 self.sides = evaluate.getEvaluatedFloat(None, elementNode, 'sides')
67 if self.sides == None:
68 radiusMaximum = max(self.radius.real, self.radius.imag)
69 self.sides = evaluate.getSidesMinimumThreeBasedOnPrecisionSides(elementNode, radiusMaximum)
70 self.radiusArealized = evaluate.getRadiusArealizedBasedOnAreaRadius(elementNode, self.radius, self.sides)
71 self.start = evaluate.getEvaluatedFloat(0.0, elementNode, 'start')
72 end = evaluate.getEvaluatedFloat(360.0, elementNode, 'end')
73 self.revolutions = evaluate.getEvaluatedFloat(1.0, elementNode, 'revolutions')
74 self.extent = evaluate.getEvaluatedFloat(end - self.start, elementNode, 'extent')
75 self.extent += 360.0 * (self.revolutions - 1.0)
76 self.spiral = evaluate.getVector3ByPrefix(None, elementNode, 'spiral')