2 Boolean geometry sphere.
7 from __future__ import absolute_import
8 #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.
11 from fabmetheus_utilities.geometry.creation import solid
12 from fabmetheus_utilities.geometry.geometry_utilities import evaluate
13 from fabmetheus_utilities.geometry.solids import cube
14 from fabmetheus_utilities.geometry.solids import triangle_mesh
15 from fabmetheus_utilities.vector3 import Vector3
16 from fabmetheus_utilities import euclidean
19 __author__ = 'Enrique Perez (perez_enrique@yahoo.com)'
20 __credits__ = 'Nophead <http://hydraraptor.blogspot.com/>\nArt of Illusion <http://www.artofillusion.org/>'
21 __date__ = '$Date: 2008/21/04 $'
22 __license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
25 def addSphere(elementNode, faces, radius, vertexes):
26 'Add sphere by radius.'
28 sides = evaluate.getSidesMinimumThreeBasedOnPrecision(elementNode, max(radius.x, radius.y, radius.z))
29 sphereSlices = max(sides / 2, 2)
30 equator = euclidean.getComplexPolygonByComplexRadius(complex(radius.x, radius.y), sides)
31 polygons = [triangle_mesh.getAddIndexedLoop([complex()], vertexes, bottom)]
32 zIncrement = (radius.z + radius.z) / float(sphereSlices)
34 for sphereSlice in xrange(1, sphereSlices):
36 zPortion = abs(z) / radius.z
37 multipliedPath = euclidean.getComplexPathByMultiplier(math.sqrt(1.0 - zPortion * zPortion), equator)
38 polygons.append(triangle_mesh.getAddIndexedLoop(multipliedPath, vertexes, z))
39 polygons.append(triangle_mesh.getAddIndexedLoop([complex()], vertexes, radius.z))
40 triangle_mesh.addPillarByLoops(faces, polygons)
42 def getGeometryOutput(elementNode, radius):
43 'Get triangle mesh from attribute dictionary.'
46 addSphere(elementNode, faces, radius, vertexes)
47 return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}}
49 def getNewDerivation(elementNode):
51 return SphereDerivation(elementNode)
53 def processElementNode(elementNode):
54 'Process the xml element.'
55 evaluate.processArchivable(Sphere, elementNode)
58 class Sphere(cube.Cube):
60 def createShape(self):
62 addSphere(self.elementNode, self.faces, self.radius, self.vertexes)
64 def setToElementNode(self, elementNode):
66 attributes = elementNode.attributes
67 self.elementNode = elementNode
68 self.radius = SphereDerivation(elementNode).radius
69 if 'radius' in attributes:
70 del attributes['radius']
71 attributes['radius.x'] = self.radius.x
72 attributes['radius.y'] = self.radius.y
73 attributes['radius.z'] = self.radius.z
75 solid.processArchiveRemoveSolid(elementNode, self.getGeometryOutput())
78 class SphereDerivation:
79 "Class to hold sphere variables."
80 def __init__(self, elementNode):
82 self.radius = evaluate.getVector3ByPrefixes(elementNode, ['demisize', 'radius'], Vector3(1.0, 1.0, 1.0))
83 self.radius = evaluate.getVector3ByMultiplierPrefixes(elementNode, 2.0, ['diameter', 'size'], self.radius)