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 = LineDerivation(elementNode)
28 endMinusStart = derivation.end - derivation.start
29 endMinusStartLength = abs(endMinusStart)
30 if endMinusStartLength <= 0.0:
31 print('Warning, end is the same as start in getGeometryOutput in line for:')
32 print(derivation.start)
36 typeStringTwoCharacters = derivation.typeString.lower()[: 2]
37 elementNode.attributes['closed'] = str(derivation.closed)
38 if derivation.step == None and derivation.steps == None:
39 return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop([derivation.start, derivation.end]))
40 loop = [derivation.start]
41 if derivation.step != None and derivation.steps != None:
42 stepVector = derivation.step / endMinusStartLength * endMinusStart
43 derivation.end = derivation.start + stepVector * derivation.steps
44 return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
45 if derivation.step == None:
46 stepVector = endMinusStart / derivation.steps
47 return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
48 endMinusStartLengthOverStep = endMinusStartLength / derivation.step
49 if typeStringTwoCharacters == 'av':
50 derivation.steps = max(1.0, round(endMinusStartLengthOverStep))
51 stepVector = derivation.step / endMinusStartLength * endMinusStart
52 derivation.end = derivation.start + stepVector * derivation.steps
53 return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
54 if typeStringTwoCharacters == 'ma':
55 derivation.steps = math.ceil(endMinusStartLengthOverStep)
56 if derivation.steps < 1.0:
57 return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop([derivation.start, derivation.end]))
58 stepVector = endMinusStart / derivation.steps
59 return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
60 if typeStringTwoCharacters == 'mi':
61 derivation.steps = math.floor(endMinusStartLengthOverStep)
62 if derivation.steps < 1.0:
63 return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop))
64 stepVector = endMinusStart / derivation.steps
65 return getGeometryOutputByStep(elementNode, derivation.end, loop, derivation.steps, stepVector)
66 print('Warning, the step type was not one of (average, maximum or minimum) in getGeometryOutput in line for:')
67 print(derivation.typeString)
69 loop.append(derivation.end)
70 return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop))
72 def getGeometryOutputByArguments(arguments, elementNode):
73 "Get vector3 vertexes from attribute dictionary by arguments."
74 evaluate.setAttributesByArguments(['start', 'end', 'step'], arguments, elementNode)
75 return getGeometryOutput(None, elementNode)
77 def getGeometryOutputByStep(elementNode, end, loop, steps, stepVector):
78 "Get line geometry output by the end, loop, steps and stepVector."
79 stepsFloor = int(math.floor(abs(steps)))
80 for stepIndex in xrange(1, stepsFloor):
81 loop.append(loop[stepIndex - 1] + stepVector)
83 return lineation.getGeometryOutputByLoop(elementNode, lineation.SideLoop(loop))
85 def getNewDerivation(elementNode):
87 return LineDerivation(elementNode)
89 def processElementNode(elementNode):
90 "Process the xml element."
91 path.convertElementNode(elementNode, getGeometryOutput(None, elementNode))
95 "Class to hold line variables."
96 def __init__(self, elementNode):
98 self.closed = evaluate.getEvaluatedBoolean(False, elementNode, 'closed')
99 self.end = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'end')
100 self.start = evaluate.getVector3ByPrefix(Vector3(), elementNode, 'start')
101 self.step = evaluate.getEvaluatedFloat(None, elementNode, 'step')
102 self.steps = evaluate.getEvaluatedFloat(None, elementNode, 'steps')
103 self.typeMenuRadioStrings = 'average maximum minimum'.split()
104 self.typeString = evaluate.getEvaluatedString('minimum', elementNode, 'type')