178 lines
8 KiB
Python
178 lines
8 KiB
Python
"""
|
|
Solid has functions for 3D shapes.
|
|
|
|
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.
|
|
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
#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.
|
|
import __init__
|
|
|
|
from fabmetheus_utilities.geometry.creation import lineation
|
|
from fabmetheus_utilities.geometry.geometry_tools import path
|
|
from fabmetheus_utilities.geometry.geometry_utilities import boolean_geometry
|
|
from fabmetheus_utilities.geometry.geometry_utilities import evaluate
|
|
from fabmetheus_utilities.geometry.geometry_utilities import matrix
|
|
from fabmetheus_utilities.geometry.solids import triangle_mesh
|
|
from fabmetheus_utilities.vector3 import Vector3
|
|
from fabmetheus_utilities import euclidean
|
|
import math
|
|
|
|
|
|
__author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
|
|
__credits__ = 'Art of Illusion <http://www.artofillusion.org/>'
|
|
__date__ = '$Date: 2008/02/05 $'
|
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
|
|
|
|
|
def getGeometryOutputByFunction(elementNode, geometryFunction):
|
|
'Get geometry output by manipulationFunction.'
|
|
if elementNode.xmlObject == None:
|
|
print('Warning, there is no object in getGeometryOutputByFunction in solid for:')
|
|
print(elementNode)
|
|
return None
|
|
geometryOutput = elementNode.xmlObject.getGeometryOutput()
|
|
if geometryOutput == None:
|
|
print('Warning, there is no geometryOutput in getGeometryOutputByFunction in solid for:')
|
|
print(elementNode)
|
|
return None
|
|
return geometryFunction(elementNode, geometryOutput, '')
|
|
|
|
def getGeometryOutputByManipulation(elementNode, geometryOutput):
|
|
'Get geometryOutput manipulated by the plugins in the manipulation shapes & solids folders.'
|
|
xmlProcessor = elementNode.getXMLProcessor()
|
|
matchingPlugins = getSolidMatchingPlugins(elementNode)
|
|
matchingPlugins.sort(evaluate.compareExecutionOrderAscending)
|
|
for matchingPlugin in matchingPlugins:
|
|
prefix = matchingPlugin.__name__.replace('_', '') + '.'
|
|
geometryOutput = matchingPlugin.getManipulatedGeometryOutput(elementNode, geometryOutput, prefix)
|
|
return geometryOutput
|
|
|
|
def getLoopLayersSetCopy(elementNode, geometryOutput, importRadius, radius):
|
|
'Get the loop layers and set the copyShallow.'
|
|
halfLayerHeight = 0.5 * radius
|
|
copyShallow = elementNode.getCopyShallow()
|
|
processElementNodeByGeometry(copyShallow, geometryOutput)
|
|
targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode)
|
|
matrix.setElementNodeDictionaryMatrix(copyShallow, targetMatrix)
|
|
transformedVertexes = copyShallow.xmlObject.getTransformedVertexes()
|
|
minimumZ = boolean_geometry.getMinimumZ(copyShallow.xmlObject)
|
|
if minimumZ == None:
|
|
copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject)
|
|
return []
|
|
maximumZ = euclidean.getTopPath(transformedVertexes)
|
|
copyShallow.attributes['visible'] = True
|
|
copyShallowObjects = [copyShallow.xmlObject]
|
|
bottomLoopLayer = euclidean.LoopLayer(minimumZ)
|
|
z = minimumZ + 0.1 * radius
|
|
zoneArrangement = triangle_mesh.ZoneArrangement(radius, transformedVertexes)
|
|
bottomLoopLayer.loops = boolean_geometry.getEmptyZLoops(copyShallowObjects, importRadius, False, z, zoneArrangement)
|
|
loopLayers = [bottomLoopLayer]
|
|
z = minimumZ + halfLayerHeight
|
|
loopLayers += boolean_geometry.getLoopLayers(copyShallowObjects, importRadius, halfLayerHeight, maximumZ, False, z, zoneArrangement)
|
|
copyShallow.parentNode.xmlObject.archivableObjects.remove(copyShallow.xmlObject)
|
|
return loopLayers
|
|
|
|
def getLoopOrEmpty(loopIndex, loopLayers):
|
|
'Get the loop, or if the loopIndex is out of range, get an empty list.'
|
|
if loopIndex < 0 or loopIndex >= len(loopLayers):
|
|
return []
|
|
return loopLayers[loopIndex].loops[0]
|
|
|
|
def getNewDerivation(elementNode):
|
|
'Get new derivation.'
|
|
return SolidDerivation(elementNode)
|
|
|
|
def getSolidMatchingPlugins(elementNode):
|
|
'Get solid plugins in the manipulation matrix, shapes & solids folders.'
|
|
xmlProcessor = elementNode.getXMLProcessor()
|
|
matchingPlugins = evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationMatrixDictionary)
|
|
return matchingPlugins + evaluate.getMatchingPlugins(elementNode, xmlProcessor.manipulationShapeDictionary)
|
|
|
|
def processArchiveRemoveSolid(elementNode, geometryOutput):
|
|
'Process the target by the manipulationFunction.'
|
|
solidMatchingPlugins = getSolidMatchingPlugins(elementNode)
|
|
if len(solidMatchingPlugins) == 0:
|
|
elementNode.parentNode.xmlObject.archivableObjects.append(elementNode.xmlObject)
|
|
matrix.getBranchMatrixSetElementNode(elementNode)
|
|
return
|
|
processElementNodeByGeometry(elementNode, getGeometryOutputByManipulation(elementNode, geometryOutput))
|
|
|
|
def processElementNode(elementNode):
|
|
'Process the xml element.'
|
|
processElementNodeByDerivation(None, elementNode)
|
|
|
|
def processElementNodeByDerivation(derivation, elementNode):
|
|
'Process the xml element by derivation.'
|
|
if derivation == None:
|
|
derivation = SolidDerivation(elementNode)
|
|
elementAttributesCopy = elementNode.attributes.copy()
|
|
for target in derivation.targets:
|
|
targetAttributesCopy = target.attributes.copy()
|
|
target.attributes = elementAttributesCopy
|
|
processTarget(target)
|
|
target.attributes = targetAttributesCopy
|
|
|
|
def processElementNodeByFunction(elementNode, manipulationFunction):
|
|
'Process the xml element.'
|
|
if 'target' not in elementNode.attributes:
|
|
print('Warning, there was no target in processElementNodeByFunction in solid for:')
|
|
print(elementNode)
|
|
return
|
|
target = evaluate.getEvaluatedLinkValue(elementNode, str(elementNode.attributes['target']).strip())
|
|
if target.__class__.__name__ == 'ElementNode':
|
|
manipulationFunction(elementNode, target)
|
|
return
|
|
path.convertElementNode(elementNode, target)
|
|
manipulationFunction(elementNode, elementNode)
|
|
|
|
def processElementNodeByFunctionPair(elementNode, geometryFunction, pathFunction):
|
|
'Process the xml element by the appropriate manipulationFunction.'
|
|
elementAttributesCopy = elementNode.attributes.copy()
|
|
targets = evaluate.getElementNodesByKey(elementNode, 'target')
|
|
for target in targets:
|
|
targetAttributesCopy = target.attributes.copy()
|
|
target.attributes = elementAttributesCopy
|
|
processTargetByFunctionPair(geometryFunction, pathFunction, target)
|
|
target.attributes = targetAttributesCopy
|
|
|
|
def processElementNodeByGeometry(elementNode, geometryOutput):
|
|
'Process the xml element by geometryOutput.'
|
|
if geometryOutput != None:
|
|
elementNode.getXMLProcessor().convertElementNode(elementNode, geometryOutput)
|
|
|
|
def processTarget(target):
|
|
'Process the target.'
|
|
if target.xmlObject == None:
|
|
print('Warning, there is no object in processElementNode in solid for:')
|
|
print(target)
|
|
return
|
|
geometryOutput = target.xmlObject.getGeometryOutput()
|
|
if geometryOutput == None:
|
|
print('Warning, there is no geometryOutput in processElementNode in solid for:')
|
|
print(target.xmlObject)
|
|
return
|
|
geometryOutput = getGeometryOutputByManipulation(target, geometryOutput)
|
|
lineation.removeChildNodesFromElementObject(target)
|
|
target.getXMLProcessor().convertElementNode(target, geometryOutput)
|
|
|
|
def processTargetByFunctionPair(geometryFunction, pathFunction, target):
|
|
'Process the target by the manipulationFunction.'
|
|
if target.xmlObject == None:
|
|
print('Warning, there is no object in processTargetByFunctions in solid for:')
|
|
print(target)
|
|
return
|
|
if len(target.xmlObject.getPaths()) > 0:
|
|
lineation.processTargetByFunction(pathFunction, target)
|
|
return
|
|
geometryOutput = getGeometryOutputByFunction(target, geometryFunction)
|
|
lineation.removeChildNodesFromElementObject(target)
|
|
target.getXMLProcessor().convertElementNode(target, geometryOutput)
|
|
|
|
|
|
class SolidDerivation:
|
|
'Class to hold solid variables.'
|
|
def __init__(self, elementNode):
|
|
'Set defaults.'
|
|
self.targets = evaluate.getElementNodesByKey(elementNode, 'target')
|