2 Solid has functions for 3D shapes.
4 Solid has some of the same functions as lineation, however you can not define geometry by dictionary string in the target because there is no getGeometryOutputByArguments function. You would have to define a shape by making the shape element. Also, you can not define geometry by 'get<Creation Name>, because the target only gets element. Instead you would have the shape element, and set the target in solid to that element.
8 from __future__ import absolute_import
9 #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.
12 from fabmetheus_utilities.geometry.creation import lineation
13 from fabmetheus_utilities.geometry.geometry_tools import path
14 from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry
15 from fabmetheus_utilities.geometry.geometry_utilities import evaluate
16 from fabmetheus_utilities.geometry.geometry_utilities import matrix
17 from fabmetheus_utilities.geometry.solids import triangle_mesh
18 from fabmetheus_utilities.vector3 import Vector3
19 from fabmetheus_utilities import euclidean
23 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
24 __credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
25 __date__ = '$Date: 2008/02/05 $'
26 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
29 def getGeometryOutputByFunction(elementNode, geometryFunction):
30 'Get geometry output by manipulationFunction.'
31 if elementNode.xmlObject == None:
32 print('Warning, there is no object in getGeometryOutputByFunction in solid for:')
35 geometryOutput = elementNode.xmlObject.getGeometryOutput()
36 if geometryOutput == None:
37 print('Warning, there is no geometryOutput in getGeometryOutputByFunction in solid for:')
40 return geometryFunction(elementNode, geometryOutput, '')
42 def getGeometryOutputByManipulation(elementNode, geometryOutput):
43 'Get geometryOutput manipulated by the plugins in the manipulation shapes & solids folders.'
44 xmlProcessor = elementNode.getXMLProcessor()
45 matchingPlugins = getSolidMatchingPlugins(elementNode)
46 matchingPlugins.sort(evaluate.compareExecutionOrderAscending)
47 for matchingPlugin in matchingPlugins:
48 prefix = matchingPlugin.__name__.replace('_', '') + '.'
49 geometryOutput = matchingPlugin.getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
52 def getLoopLayersSetCopy(elementNode, geometryOutput, importRadius, radius):
53 'Get the loop layers and set the copyShallow.'
54 halfLayerHeight = 0.5 * radius
55 copyShallow = elementNode.getCopyShallow()
56 processElementNodeByGeometry(copyShallow, geometryOutput)
57 targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode)
58 matrix.setElementNodeDictionaryMatrix(copyShallow, targetMatrix)
59 transformedVertexes = copyShallow.xmlObject.getTransformedVertexes()
60 minimumZ = boolean_geometry.getMinimumZ(copyShallow.xmlObject)
62 copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject)
64 maximumZ = euclidean.getTopPath(transformedVertexes)
65 copyShallow.attributes['visible'] = True
66 copyShallowObjects = [copyShallow.xmlObject]
67 bottomLoopLayer = euclidean.LoopLayer(minimumZ)
68 z = minimumZ + 0.1 * radius
69 zoneArrangement = triangle_mesh.ZoneArrangement(radius, transformedVertexes)
70 bottomLoopLayer.loops = boolean_geometry.getEmptyZLoops(copyShallowObjects, importRadius, False, z, zoneArrangement)
71 loopLayers = [bottomLoopLayer]
72 z = minimumZ + halfLayerHeight
73 loopLayers += boolean_geometry.getLoopLayers(copyShallowObjects, importRadius, halfLayerHeight, maximumZ, False, z, zoneArrangement)
74 copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject)
77 def getLoopOrEmpty(loopIndex, loopLayers):
78 'Get the loop, or if the loopIndex is out of range, get an empty list.'
79 if loopIndex < 0 or loopIndex >= len(loopLayers):
81 return loopLayers[loopIndex].loops[0]
83 def getNewDerivation(elementNode):
85 return SolidDerivation(elementNode)
87 def getSolidMatchingPlugins(elementNode):
88 'Get solid plugins in the manipulation matrix, shapes & solids folders.'
89 xmlProcessor = elementNode.getXMLProcessor()
90 matchingPlugins = evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationMatrixDictionary)
91 return matchingPlugins + evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationShapeDictionary)
93 def processArchiveRemoveSolid(elementNode, geometryOutput):
94 'Process the target by the manipulationFunction.'
95 solidMatchingPlugins = getSolidMatchingPlugins(elementNode)
96 if len(solidMatchingPlugins) == 0:
97 elementNode.parentNode.xmlObject.archivableObjects.append(elementNode.xmlObject)
98 matrix.getBranchMatrixSetElementNode(elementNode)
100 processElementNodeByGeometry(elementNode, getGeometryOutputByManipulation(elementNode, geometryOutput))
102 def processElementNode(elementNode):
103 'Process the xml element.'
104 processElementNodeByDerivation(None, elementNode)
106 def processElementNodeByDerivation(derivation, elementNode):
107 'Process the xml element by derivation.'
108 if derivation == None:
109 derivation = SolidDerivation(elementNode)
110 elementAttributesCopy = elementNode.attributes.copy()
111 for target in derivation.targets:
112 targetAttributesCopy = target.attributes.copy()
113 target.attributes = elementAttributesCopy
114 processTarget(target)
115 target.attributes = targetAttributesCopy
117 def processElementNodeByFunction(elementNode, manipulationFunction):
118 'Process the xml element.'
119 if 'target' not in elementNode.attributes:
120 print('Warning, there was no target in processElementNodeByFunction in solid for:')
123 target = evaluate.getEvaluatedLinkValue(elementNode, str(elementNode.attributes['target']).strip())
124 if target.__class__.__name__ == 'ElementNode':
125 manipulationFunction(elementNode, target)
127 path.convertElementNode(elementNode, target)
128 manipulationFunction(elementNode, elementNode)
130 def processElementNodeByFunctionPair(elementNode, geometryFunction, pathFunction):
131 'Process the xml element by the appropriate manipulationFunction.'
132 elementAttributesCopy = elementNode.attributes.copy()
133 targets = evaluate.getElementNodesByKey(elementNode, 'target')
134 for target in targets:
135 targetAttributesCopy = target.attributes.copy()
136 target.attributes = elementAttributesCopy
137 processTargetByFunctionPair(geometryFunction, pathFunction, target)
138 target.attributes = targetAttributesCopy
140 def processElementNodeByGeometry(elementNode, geometryOutput):
141 'Process the xml element by geometryOutput.'
142 if geometryOutput != None:
143 elementNode.getXMLProcessor().convertElementNode(elementNode, geometryOutput)
145 def processTarget(target):
146 'Process the target.'
147 if target.xmlObject == None:
148 print('Warning, there is no object in processElementNode in solid for:')
151 geometryOutput = target.xmlObject.getGeometryOutput()
152 if geometryOutput == None:
153 print('Warning, there is no geometryOutput in processElementNode in solid for:')
154 print(target.xmlObject)
156 geometryOutput = getGeometryOutputByManipulation(target, geometryOutput)
157 lineation.removeChildNodesFromElementObject(target)
158 target.getXMLProcessor().convertElementNode(target, geometryOutput)
160 def processTargetByFunctionPair(geometryFunction, pathFunction, target):
161 'Process the target by the manipulationFunction.'
162 if target.xmlObject == None:
163 print('Warning, there is no object in processTargetByFunctions in solid for:')
166 if len(target.xmlObject.getPaths()) > 0:
167 lineation.processTargetByFunction(pathFunction, target)
169 geometryOutput = getGeometryOutputByFunction(target, geometryFunction)
170 lineation.removeChildNodesFromElementObject(target)
171 target.getXMLProcessor().convertElementNode(target, geometryOutput)
174 class SolidDerivation:
175 'Class to hold solid variables.'
176 def __init__(self, elementNode):
178 self.targets = evaluate.getElementNodesByKey(elementNode, 'target')