chiark / gitweb /
Add uppercase STL and HEX to file dialog filters for linux/MacOS
[cura.git] / Cura / fabmetheus_utilities / geometry / manipulation_meta / _array.py
1 """
2 Boolean geometry array.
3
4 """
5
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.
8 import __init__
9
10 from fabmetheus_utilities.geometry.geometry_tools import vertex
11 from fabmetheus_utilities.geometry.geometry_utilities import evaluate
12 from fabmetheus_utilities.geometry.geometry_utilities import matrix
13 from fabmetheus_utilities import euclidean
14 import math
15
16
17 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
18 __credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
19 __date__ = '$Date: 2008/02/05 $'
20 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
21
22
23 def addPathToGroup(derivation, groupDictionaryCopy, path, targetMatrix, totalIndex):
24         'Add path to the array group.'
25         for pointIndex, point in enumerate(path):
26                 arrayElement = derivation.target.getCopy(derivation.elementNode.getIDSuffix(totalIndex), derivation.elementNode)
27                 arrayDictionary = arrayElement.attributes
28                 arrayDictionary['visible'] = str(derivation.visible).lower()
29                 arrayDictionary.update(groupDictionaryCopy)
30                 euclidean.removeTrueFromDictionary(arrayDictionary, 'visible')
31                 vertexMatrix = matrix.Matrix(matrix.getTranslateTetragridByTranslation(point))
32                 zAngle = totalIndex * 50.0
33                 rotationMatrix = getRotationMatrix(arrayDictionary, derivation, path, point, pointIndex)
34                 arrayElementMatrix = vertexMatrix.getSelfTimesOther(rotationMatrix.getSelfTimesOther(targetMatrix.tetragrid).tetragrid)
35                 arrayDictionary.update(arrayElementMatrix.getAttributes('matrix.'))
36                 arrayDictionary['_arrayIndex'] = totalIndex
37                 arrayDictionary['_arrayPoint'] = point
38                 totalIndex += 1
39
40 def getNewDerivation(elementNode):
41         'Get new derivation.'
42         return ArrayDerivation(elementNode)
43
44 def getRotationMatrix(arrayDictionary, derivation, path, point, pointIndex):
45         'Get rotationMatrix.'
46         if len(path) < 2 or not derivation.track:
47                 return matrix.Matrix()
48         point = point.dropAxis()
49         begin = path[(pointIndex + len(path) - 1) % len(path)].dropAxis()
50         end = path[(pointIndex + 1) % len(path)].dropAxis()
51         pointMinusBegin = point - begin
52         pointMinusBeginLength = abs(pointMinusBegin)
53         endMinusPoint = end - point
54         endMinusPointLength = abs(endMinusPoint)
55         if not derivation.closed:
56                 if pointIndex == 0 and endMinusPointLength > 0.0:
57                         return getRotationMatrixByPolar(arrayDictionary, endMinusPoint, endMinusPointLength)
58                 elif pointIndex == len(path) - 1 and pointMinusBeginLength > 0.0:
59                         return getRotationMatrixByPolar(arrayDictionary, pointMinusBegin, pointMinusBeginLength)
60         if pointMinusBeginLength <= 0.0:
61                 print('Warning, point equals previous point in getRotationMatrix in array for:')
62                 print(path)
63                 print(pointIndex)
64                 print(derivation.elementNode)
65                 return matrix.Matrix()
66         pointMinusBegin /= pointMinusBeginLength
67         if endMinusPointLength <= 0.0:
68                 print('Warning, point equals next point in getRotationMatrix in array for:')
69                 print(path)
70                 print(pointIndex)
71                 print(derivation.elementNode)
72                 return matrix.Matrix()
73         endMinusPoint /= endMinusPointLength
74         averagePolar = pointMinusBegin + endMinusPoint
75         averagePolarLength = abs(averagePolar)
76         if averagePolarLength <= 0.0:
77                 print('Warning, averagePolarLength is zero in getRotationMatrix in array for:')
78                 print(path)
79                 print(pointIndex)
80                 print(derivation.elementNode)
81                 return matrix.Matrix()
82         return getRotationMatrixByPolar(arrayDictionary, averagePolar, averagePolarLength)
83
84 def getRotationMatrixByPolar(arrayDictionary, polar, polarLength):
85         'Get rotationMatrix by polar and polarLength.'
86         polar /= polarLength
87         arrayDictionary['_arrayRotation'] = math.degrees(math.atan2(polar.imag, polar.real))
88         return matrix.Matrix(matrix.getDiagonalSwitchedTetragridByPolar([0, 1], polar))
89
90 def processElementNode(elementNode):
91         "Process the xml element."
92         processElementNodeByDerivation(None, elementNode)
93
94 def processElementNodeByDerivation(derivation, elementNode):
95         'Process the xml element by derivation.'
96         if derivation == None:
97                 derivation = ArrayDerivation(elementNode)
98         if derivation.target == None:
99                 print('Warning, array could not get target for:')
100                 print(elementNode)
101                 return
102         if len(derivation.paths) < 1:
103                 print('Warning, array could not get paths for:')
104                 print(elementNode)
105                 return
106         groupDictionaryCopy = elementNode.attributes.copy()
107         euclidean.removeElementsFromDictionary(groupDictionaryCopy, ['closed', 'paths', 'target', 'track', 'vertexes'])
108         evaluate.removeIdentifiersFromDictionary(groupDictionaryCopy)
109         targetMatrix = matrix.getBranchMatrixSetElementNode(derivation.target)
110         elementNode.localName = 'group'
111         totalIndex = 0
112         for path in derivation.paths:
113                 addPathToGroup(derivation, groupDictionaryCopy, path, targetMatrix, totalIndex)
114         elementNode.getXMLProcessor().processElementNode(elementNode)
115
116
117 class ArrayDerivation:
118         "Class to hold array variables."
119         def __init__(self, elementNode):
120                 'Set defaults.'
121                 self.closed = evaluate.getEvaluatedBoolean(True, elementNode, 'closed')
122                 self.elementNode = elementNode
123                 self.paths = evaluate.getTransformedPathsByKey([], elementNode, 'paths')
124                 vertexTargets = evaluate.getElementNodesByKey(elementNode, 'vertexes')
125                 for vertexTarget in vertexTargets:
126                         self.paths.append(vertexTarget.getVertexes())
127                 self.target = evaluate.getElementNodeByKey(elementNode, 'target')
128                 self.track = evaluate.getEvaluatedBoolean(True, elementNode, 'track')
129                 self.visible = evaluate.getEvaluatedBoolean(True, elementNode, 'visible')