def getAddIndexedSegmentedPerimeter(heightGrid, maximumXY, minimumXY, step, vertexes, z=0.0): 'Get and add an indexed segmented perimeter.' indexedSegmentedPerimeter = [] firstRow = heightGrid[0] columnOffset = minimumXY.real numberOfRowsMinusTwo = len(heightGrid) - 2 for column in firstRow: vector3index = Vector3Index(len(vertexes), columnOffset, minimumXY.imag, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) columnOffset += step.real rowOffset = minimumXY.imag for rowIndex in xrange(numberOfRowsMinusTwo): rowOffset += step.imag vector3index = Vector3Index(len(vertexes), maximumXY.real, rowOffset, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) columnOffset = maximumXY.real for column in firstRow: vector3index = Vector3Index(len(vertexes), columnOffset, maximumXY.imag, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) columnOffset -= step.real rowOffset = maximumXY.imag for rowIndex in xrange(numberOfRowsMinusTwo): rowOffset -= step.imag vector3index = Vector3Index(len(vertexes), minimumXY.real, rowOffset, z) vertexes.append(vector3index) indexedSegmentedPerimeter.append(vector3index) return indexedSegmentedPerimeter
def addLoop(endMultiplier, extrudeDerivation, loopLists, path, portionDirectionIndex, portionDirections, vertexes): "Add an indexed loop to the vertexes." portionDirection = portionDirections[portionDirectionIndex] if portionDirection.directionReversed == True: loopLists.append([]) loops = loopLists[-1] interpolationOffset = extrudeDerivation.interpolationDictionary['offset'] offset = interpolationOffset.getVector3ByPortion(portionDirection) if endMultiplier != None: if portionDirectionIndex == 0: setOffsetByMultiplier(interpolationOffset.path[1], interpolationOffset.path[0], endMultiplier, offset) elif portionDirectionIndex == len(portionDirections) - 1: setOffsetByMultiplier(interpolationOffset.path[-2], interpolationOffset.path[-1], endMultiplier, offset) scale = extrudeDerivation.interpolationDictionary[ 'scale'].getComplexByPortion(portionDirection) twist = extrudeDerivation.interpolationDictionary['twist'].getYByPortion( portionDirection) projectiveSpace = euclidean.ProjectiveSpace() if extrudeDerivation.tiltTop == None: tilt = extrudeDerivation.interpolationDictionary[ 'tilt'].getComplexByPortion(portionDirection) projectiveSpace = projectiveSpace.getByTilt(tilt) else: normals = getNormals(interpolationOffset, offset, portionDirection) normalFirst = normals[0] normalAverage = getNormalAverage(normals) if extrudeDerivation.tiltFollow and extrudeDerivation.oldProjectiveSpace != None: projectiveSpace = extrudeDerivation.oldProjectiveSpace.getNextSpace( normalAverage) else: projectiveSpace = projectiveSpace.getByBasisZTop( normalAverage, extrudeDerivation.tiltTop) extrudeDerivation.oldProjectiveSpace = projectiveSpace projectiveSpace.unbuckle(extrudeDerivation.maximumUnbuckling, normalFirst) projectiveSpace = projectiveSpace.getSpaceByXYScaleAngle(twist, scale) loop = [] if (abs(projectiveSpace.basisX) + abs(projectiveSpace.basisY)) < 0.0001: vector3Index = Vector3Index(len(vertexes)) addOffsetAddToLists(loop, offset, vector3Index, vertexes) loops.append(loop) return for point in path: vector3Index = Vector3Index(len(vertexes)) projectedVertex = projectiveSpace.getVector3ByPoint(point) vector3Index.setToVector3(projectedVertex) addOffsetAddToLists(loop, offset, vector3Index, vertexes) loops.append(loop)
def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get inset geometryOutput.' derivation = InsetDerivation(elementNode, prefix) if derivation.radius == 0.0: return geometryOutput halfLayerHeight = 0.5 * derivation.radius importRadius = 0.5 * derivation.radius * setting.getImportCoarseness(elementNode) loopLayers = solid.getLoopLayersSetCopy(elementNode, geometryOutput, importRadius, derivation.radius) triangleAltitude = math.sqrt(0.75) * derivation.radius loops = [] vertexes = [] for loopLayerIndex in xrange(1, len(loopLayers), 2): loopLayer = loopLayers[loopLayerIndex] loopLayer.loops[0] = intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], triangleAltitude) for loopLayerIndex in xrange(0, len(loopLayers), 2): loopLayer = loopLayers[loopLayerIndex] loopLists = [[solid.getLoopOrEmpty(loopLayerIndex - 2, loopLayers)]] loopLists.append([solid.getLoopOrEmpty(loopLayerIndex - 1, loopLayers)]) loopLists.append([intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], derivation.radius)]) if evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'insetTop'): loopLists.append([solid.getLoopOrEmpty(loopLayerIndex + 1, loopLayers)]) loopLists.append([solid.getLoopOrEmpty(loopLayerIndex + 2, loopLayers)]) largestLoop = euclidean.getLargestLoop(boolean_solid.getLoopsIntersection(importRadius, loopLists)) triangle_mesh.addVector3Loop(largestLoop, loops, vertexes, loopLayer.z) if evaluate.getEvaluatedBoolean(False, elementNode, prefix + 'addExtraTopLayer') and len(loops) > 0: topLoop = loops[-1] vector3Loop = [] loops.append(vector3Loop) z = topLoop[0].z + derivation.radius for point in topLoop: vector3Index = Vector3Index(len(vertexes), point.x, point.y, z) vector3Loop.append(vector3Index) vertexes.append(vector3Index) return triangle_mesh.getMeldedPillarOutput(loops)
def getSymmetricYLoop(path, vertexes, y): 'Get symmetrix y loop.' loop = [] for point in path: vector3Index = Vector3Index(len(vertexes), point.real, y, point.imag) loop.append(vector3Index) vertexes.append(vector3Index) return loop
def getAddIndexedLoop( loop, vertexes, z ): 'Get and add an indexed loop.' indexedLoop = [] for index in xrange(len(loop)): pointComplex = loop[ index ] vector3index = Vector3Index( len(vertexes), pointComplex.real, pointComplex.imag, z ) indexedLoop.append( vector3index ) vertexes.append( vector3index ) return indexedLoop
def addVector3Loop(loop, loops, vertexes, z): 'Add vector3Loop to loops if there is something in it, for inset and outset.' vector3Loop = [] for point in loop: vector3Index = Vector3Index(len(vertexes), point.real, point.imag, z) vector3Loop.append(vector3Index) vertexes.append(vector3Index) if len(vector3Loop) > 0: loops.append(vector3Loop)
def getAddIndexedGrid( grid, vertexes, z ): 'Get and add an indexed grid.' indexedGrid = [] for row in grid: indexedRow = [] indexedGrid.append( indexedRow ) for pointComplex in row: vector3index = Vector3Index( len(vertexes), pointComplex.real, pointComplex.imag, z ) indexedRow.append( vector3index ) vertexes.append( vector3index ) return indexedGrid
def addBottomLoop(deltaZ, loops): "Add bottom loop to loops." bottomLoop = loops[0] bottomAddition = [] bottomZ = euclidean.getBottomPath(bottomLoop) + deltaZ for point in bottomLoop: bottomAddition.append(Vector3Index(len(bottomAddition), point.x, point.y, bottomZ)) loops.insert(0, bottomAddition) numberOfVertexes = 0 for loop in loops: for point in loop: point.index = numberOfVertexes numberOfVertexes += 1
def getAddIndexedHeightGrid(heightGrid, minimumXY, step, top, vertexes): 'Get and add an indexed heightGrid.' indexedHeightGrid = [] for rowIndex, row in enumerate(heightGrid): indexedRow = [] indexedHeightGrid.append(indexedRow) rowOffset = step.imag * float(rowIndex) + minimumXY.imag for columnIndex, element in enumerate(row): columnOffset = step.real * float(columnIndex) + minimumXY.real vector3index = Vector3Index(len(vertexes), columnOffset, rowOffset, top * element) indexedRow.append(vector3index) vertexes.append(vector3index) return indexedHeightGrid
def getPillarOutput(loops): 'Get pillar output.' faces = [] vertexDictionary = {} vertexes = [] for loop in loops: for vertexIndex, vertex in enumerate(loop): position = (vertex.x, vertex.y, vertex.z) if position in vertexDictionary: loop[vertexIndex] = vertexDictionary[position] else: if vertex.__class__ != Vector3Index: loop[vertexIndex] = Vector3Index(len(vertexDictionary), vertex.x, vertex.y, vertex.z) vertexDictionary[position] = loop[vertexIndex] vertexes.append(loop[vertexIndex]) addPillarByLoops(faces, loops) return {'trianglemesh' : {'vertex' : vertexes, 'face' : faces}}
def getUniqueVertexes(loops): 'Get unique vertexes.' vertexDictionary = {} uniqueVertexes = [] for loop in loops: for vertexIndex, vertex in enumerate(loop): vertexTuple = (vertex.x, vertex.y, vertex.z) if vertexTuple in vertexDictionary: loop[vertexIndex] = vertexDictionary[vertexTuple] else: if vertex.__class__ == Vector3Index: loop[vertexIndex].index = len(vertexDictionary) else: loop[vertexIndex] = Vector3Index(len(vertexDictionary), vertex.x, vertex.y, vertex.z) vertexDictionary[vertexTuple] = loop[vertexIndex] uniqueVertexes.append(loop[vertexIndex]) return uniqueVertexes
def addBevelGear(derivation, extrudeDerivation, pitchRadius, positives, teeth, vector3GearProfile): "Get extrude output for a cylinder gear." totalPitchRadius = derivation.pitchRadiusGear + derivation.pitchRadius totalTeeth = derivation.teethPinion + derivation.teethGear portionDirections = extrude.getSpacedPortionDirections(extrudeDerivation.interpolationDictionary) loopLists = extrude.getLoopListsByPath(extrudeDerivation, None, vector3GearProfile[0], portionDirections) firstLoopList = loopLists[0] gearOverPinion = float(totalTeeth - teeth) / float(teeth) thirdLayerThickness = 0.33333333333 * evaluate.getLayerThickness(derivation.xmlElement) pitchRadian = math.atan(math.sin(derivation.operatingRadian) / (gearOverPinion + math.cos(derivation.operatingRadian))) coneDistance = pitchRadius / math.sin(pitchRadian) apex = Vector3(0.0, 0.0, math.sqrt(coneDistance * coneDistance - pitchRadius * pitchRadius)) cosPitch = apex.z / coneDistance sinPitch = math.sin(pitchRadian) for loop in firstLoopList: for point in loop: alongWay = point.z / coneDistance oneMinusAlongWay = 1.0 - alongWay pointComplex = point.dropAxis() pointComplexLength = abs(pointComplex) deltaRadius = pointComplexLength - pitchRadius cosDeltaRadius = cosPitch * deltaRadius sinDeltaRadius = sinPitch * deltaRadius pointComplex *= (cosDeltaRadius + pitchRadius) / pointComplexLength point.x = pointComplex.real point.y = pointComplex.imag point.z += sinDeltaRadius point.x *= oneMinusAlongWay point.y *= oneMinusAlongWay addBottomLoop(-thirdLayerThickness, firstLoopList) topLoop = firstLoopList[-1] topAddition = [] topZ = euclidean.getTopPath(topLoop) + thirdLayerThickness oldIndex = topLoop[-1].index for point in topLoop: oldIndex += 1 topAddition.append(Vector3Index(oldIndex, 0.8 * point.x, 0.8 * point.y, topZ)) firstLoopList.append(topAddition) translation = Vector3(0.0, 0.0, -euclidean.getBottomPaths(firstLoopList)) euclidean.translateVector3Paths(firstLoopList, translation) geometryOutput = trianglemesh.getPillarsOutput(loopLists) positives.append(geometryOutput)
def getVector3Index(index=0, x=0.0, y=0.0, z=0.0): 'Get the vector3.' return Vector3Index(index, x, y, z)
def getManipulatedGeometryOutput(elementNode, geometryOutput, prefix): 'Get inset geometryOutput.' derivation = InsetDerivation(elementNode, prefix) if derivation.radius == 0.0: return geometryOutput copyShallow = elementNode.getCopyShallow() solid.processElementNodeByGeometry(copyShallow, geometryOutput) targetMatrix = matrix.getBranchMatrixSetElementNode(elementNode) matrix.setElementNodeDictionaryMatrix(copyShallow, targetMatrix) transformedVertexes = copyShallow.xmlObject.getTransformedVertexes() minimumZ = boolean_geometry.getMinimumZ(copyShallow.xmlObject) maximumZ = euclidean.getTopPath(transformedVertexes) layerThickness = setting.getLayerThickness(elementNode) importRadius = setting.getImportRadius(elementNode) zoneArrangement = triangle_mesh.ZoneArrangement(layerThickness, transformedVertexes) copyShallow.attributes['visible'] = True copyShallowObjects = [copyShallow.xmlObject] bottomLoopLayer = euclidean.LoopLayer(minimumZ) z = minimumZ + 0.1 * layerThickness bottomLoopLayer.loops = boolean_geometry.getEmptyZLoops( copyShallowObjects, importRadius, False, z, zoneArrangement) loopLayers = [bottomLoopLayer] z = minimumZ + layerThickness loopLayers += boolean_geometry.getLoopLayers(copyShallowObjects, importRadius, layerThickness, maximumZ, False, z, zoneArrangement) copyShallow.parentNode.xmlObject.archivableObjects.remove( copyShallow.xmlObject) belowLoop = [] diagonalRadius = math.sqrt(0.5) * derivation.radius insetDiagonalLoops = [] loops = [] vertexes = [] for loopLayer in loopLayers: insetDiagonalLoops.append( intercircle.getLargestInsetLoopFromLoop(loopLayer.loops[0], diagonalRadius)) for loopLayerIndex, loopLayer in enumerate(loopLayers): vector3Loop = [] insetLoop = intercircle.getLargestInsetLoopFromLoop( loopLayer.loops[0], derivation.radius) loopLists = [[getLoopOrEmpty(loopLayerIndex - 1, insetDiagonalLoops)], [insetLoop]] largestLoop = euclidean.getLargestLoop( boolean_solid.getLoopsIntersection(importRadius, loopLists)) if evaluate.getEvaluatedBoolean(True, elementNode, prefix + 'insetTop'): loopLists = [[ getLoopOrEmpty(loopLayerIndex + 1, insetDiagonalLoops) ], [largestLoop]] largestLoop = euclidean.getLargestLoop( boolean_solid.getLoopsIntersection(importRadius, loopLists)) for point in largestLoop: vector3Index = Vector3Index(len(vertexes), point.real, point.imag, loopLayer.z) vector3Loop.append(vector3Index) vertexes.append(vector3Index) if len(vector3Loop) > 0: loops.append(vector3Loop) if evaluate.getEvaluatedBoolean(False, elementNode, prefix + 'addExtraTopLayer') and len(loops) > 0: topLoop = loops[-1] vector3Loop = [] loops.append(vector3Loop) z = topLoop[0].z + layerThickness for point in topLoop: vector3Index = Vector3Index(len(vertexes), point.x, point.y, z) vector3Loop.append(vector3Index) vertexes.append(vector3Index) geometryOutput = triangle_mesh.getMeldedPillarOutput(loops) return geometryOutput