def execute(self, fp): edges = fp.Edges if edges < 3: edges = 3 length = fp.Length radius = fp.Radius height = fp.Height m = Base.Matrix() m.rotateZ(math.radians(360.0 / edges)) # create polygon polygon = [] v = Base.Vector(length, 0, 0) for i in range(edges): polygon.append(v) v = m.multiply(v) polygon.append(v) wire = Part.makePolygon(polygon) # create circle circ = Part.makeCircle(radius) # Create the face with the polygon as outline and the circle as hole face = Part.Face([wire, Part.Wire(circ)]) # Extrude in z to create the final solid extrude = face.extrude(Base.Vector(0, 0, height)) fp.Shape = extrude
def makeSquareTool(s, m): # makes a cylinder with an inner square hole, used as cutting tool # create square face msq = Base.Matrix() msq.rotateZ(math.radians(90.0)) polygon = [] vsq = Base.Vector(s / 2.0, s / 2.0, -m * 0.1) for i in range(4): polygon.append(vsq) vsq = msq.multiply(vsq) polygon.append(vsq) square = Part.makePolygon(polygon) square = Part.Face(square) # create circle face circ = Part.makeCircle(s * 3.0, Base.Vector(0.0, 0.0, -m * 0.1)) circ = Part.Face(Part.Wire(circ)) # Create the face with the circle as outline and the square as hole face=circ.cut(square) # Extrude in z to create the final cutting tool exSquare = face.extrude(Base.Vector(0.0, 0.0, m * 1.2)) # Part.show(exHex) return exSquare
def makeBottle(myWidth=50.0, myHeight=70.0, myThickness=30.0): aPnt1 = Base.Vector(-myWidth / 2., 0, 0) aPnt2 = Base.Vector(-myWidth / 2., -myThickness / 4., 0) aPnt3 = Base.Vector(0, -myThickness / 2., 0) aPnt4 = Base.Vector(myWidth / 2., -myThickness / 4., 0) aPnt5 = Base.Vector(myWidth / 2., 0, 0) aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4) aSegment1 = Part.Line(aPnt1, aPnt2) aSegment2 = Part.Line(aPnt4, aPnt5) aEdge1 = aSegment1.toShape() aEdge2 = aArcOfCircle.toShape() aEdge3 = aSegment2.toShape() aWire = Part.Wire([aEdge1, aEdge2, aEdge3]) aTrsf = Base.Matrix() aTrsf.rotateZ(math.pi) # rotate around the z-axis aMirroredWire = aWire.copy() aMirroredWire.transformShape(aTrsf) myWireProfile = Part.Wire([aWire, aMirroredWire]) myFaceProfile = Part.Face(myWireProfile) aPrismVec = Base.Vector(0, 0, myHeight) myBody = myFaceProfile.extrude(aPrismVec) myBody = myBody.makeFillet(myThickness / 12.0, myBody.Edges) neckLocation = Base.Vector(0, 0, myHeight) neckNormal = Base.Vector(0, 0, 1) myNeckRadius = myThickness / 4. myNeckHeight = myHeight / 10 myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation, neckNormal) myBody = myBody.fuse(myNeck) faceToRemove = 0 zMax = -1.0 for xp in myBody.Faces: try: surf = xp.Surface if type(surf) == Part.Plane: z = surf.Position.z if z > zMax: zMax = z faceToRemove = xp except: continue # This doesn't work for any reason myBody = myBody.makeThickness([faceToRemove], -myThickness / 50, 1.e-3) myThreading = Part.makeThread(myNeckHeight / 10, myNeckRadius * 0.06, myHeight / 10, myNeckRadius * 0.99) myThreading.translate(Base.Vector(0, 0, myHeight)) myCompound = Part.Compound([myBody, myThreading]) return myCompound
def matrix2d(svgmat): """ Convert a 2D matrix from SVG into a FreeCAD 3D Matrix. e.g. mat = [[0.9659258262890683, 0.25881904510252074, 0.0], [-0.25881904510252074, 0.9659258262890683, 0.0]] results in Matrix ((0.965926,0.258819,0,0),(-0.258819,0.965926,0,0),(0,0,1,0),(0,0,0,1)) """ # FIXME: is the handling of svgmat[*][2] correct? return Base.Matrix(svgmat[0][0], svgmat[0][1], 0, svgmat[0][2], svgmat[1][0], svgmat[1][1], 0, svgmat[1][2])
def makeCopy(shape, radius, angle): mat = Base.Matrix() mat.rotateZ(math.radians(angle)) step = int(360.0 / angle) shape = shape.copy() shape.translate((radius, 0, 0)) comp = shape.copy() for i in range(step): shape.transformShape(mat) comp = comp.fuse(shape) return comp
def process(self): if not any(socket.is_linked for socket in self.outputs): return solids_in = self.inputs[0].sv_get() matrixes = self.inputs[1].sv_get() solids = [] for solid, matrix in zip(*mlr([solids_in, matrixes])): mat = Base.Matrix(*[i for v in matrix for i in v]) solid_o = solid.transformGeometry(mat) solids.append(solid_o) self.outputs['Solid'].sv_set(solids)
def GetPathSolid(self, tool, cmd, pos): toolPath = PathGeom.edgeForCmd(cmd, pos) # curpos = e1.valueAt(e1.LastParameter) startDir = toolPath.tangentAt(0) startDir[2] = 0.0 endPos = toolPath.valueAt(toolPath.LastParameter) endDir = toolPath.tangentAt(toolPath.LastParameter) try: startDir.normalize() endDir.normalize() except: return (None, endPos) # height = self.height # hack to overcome occ bugs rad = tool.Diameter / 2.0 - 0.001 * pos[2] # rad = rad + 0.001 * self.icmd if type(toolPath.Curve ) is Part.Circle and toolPath.Curve.Radius <= rad: rad = toolPath.Curve.Radius - 0.01 * (pos[2] + 1) return (None, endPos) # create the path shell toolProf = self.CreateToolProfile(tool, startDir, pos, rad) rotmat = Base.Matrix() rotmat.move(pos.negative()) rotmat.rotateZ(math.pi) rotmat.move(pos) mirroredProf = toolProf.transformGeometry(rotmat) fullProf = Part.Wire([toolProf, mirroredProf]) pathWire = Part.Wire(toolPath) try: pathShell = pathWire.makePipeShell([fullProf], False, True) except: if self.debug: Part.show(pathWire) Part.show(fullProf) return (None, endPos) # create the start cup startCup = toolProf.revolve(pos, Vector(0, 0, 1), -180) # create the end cup endProf = self.CreateToolProfile(tool, endDir, endPos, rad) endCup = endProf.revolve(endPos, Vector(0, 0, 1), 180) fullShell = Part.makeShell(startCup.Faces + pathShell.Faces + endCup.Faces) return (Part.makeSolid(fullShell).removeSplitter(), endPos)
def execute(self, fp): a = fp.A b = fp.B c = fp.C m = Base.Matrix() m.A11 = a.x m.A12 = a.y m.A13 = a.z m.A21 = b.x m.A22 = b.y m.A23 = b.z m.A31 = c.x m.A32 = c.y m.A33 = c.z box = Part.makeBox(1, 1, 1) fp.Shape = box.transformGeometry(m)
def makeBottle1(self): aPnt1 = Base.Vector(-self.width / 2., 0, 0) aPnt2 = Base.Vector(-self.width / 2., -self.thickness / 4., 0) aPnt3 = Base.Vector(0, -self.thickness / 2., 0) aPnt4 = Base.Vector(self.width / 2., -self.thickness / 4., 0) aPnt5 = Base.Vector(self.width / 2., 0, 0) ## 上面定义5个点:只与myThickness,myWidth有关 aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4) aSegment1 = Part.LineSegment(aPnt1, aPnt2) aSegment2 = Part.LineSegment(aPnt4, aPnt5) ## 上面构建2条线和一个圆弧: 线1: 1-2; 线2: 4-5; 圆弧:2-3-4 aEdge1 = aSegment1.toShape() aEdge2 = aArcOfCircle.toShape() aEdge3 = aSegment2.toShape() aWire = Part.Wire([aEdge1, aEdge2, aEdge3]) ## 由几何结构(line和circle)构造形状Shape:(Solid-Shell-Face-Wire-Edge-Vertex) aTrsf = Base.Matrix() ## Matrix是变换到三维的一个常用工具,他包含了几乎所有的变换 aTrsf.rotateZ(math.pi) # rotate around the z-axis aMirroredWire = aWire.transformGeometry(aTrsf) # myWireProfile = Part.Wire([aWire, aMirroredWire]) myFaceProfile = Part.Face(myWireProfile) # 将线变成了面 aPrismVec = Base.Vector(0, 0, self.height) myBody = myFaceProfile.extrude(aPrismVec) # myBody=myBody.makeFillet(myThickness/12.0,myBody.Edges) ##上面语句为,先180镜像,之后形成一个closed face,之后 # 用extrude进行拉升 myHeight的高度 # 随后使用makeFillet,扣除 myThickness/12.0 的厚度 neckLocation = Base.Vector(0, 0, self.height) neckNormal = Base.Vector(0, 0, 1) myNeckRadius = self.thickness / 4. myNeckHeight = self.height / 10. myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation, neckNormal) myBody = myBody.fuse(myNeck) # myBody = myBody.makeFillet(myThickness/12.0,myBody.Edges) # App.getDocument('Cube').addObject('Part::PartFeature','Shape') = myBody.toShape() # Gui.getDocument("Cube").getObject("Shape").ShapeColor=color Part.show(myBody) Gui.getDocument("Bottle").getObject("Shape001").ShapeColor = self.color
def testIntersectionOfParallelTriangles(self): self.planarMesh.append( [0.0,10.0,10.0] ) self.planarMesh.append( [10.0,0.0,10.0] ) self.planarMesh.append( [10.0,10.0,10.0] ) self.planarMesh.append( [6.0,8.0,10.1] ) self.planarMesh.append( [16.0,8.0,10.1] ) self.planarMesh.append( [6.0,18.0,10.1] ) planarMeshObject = Mesh.Mesh(self.planarMesh) mat = Base.Matrix() mat.rotateX(1.0) mat.rotateY(1.0) mat.rotateZ(1.0) planarMeshObject.transformGeometry(mat) f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] res=f1.intersect(f2) self.assertTrue(len(res) == 0)
def testIntersectionOfTransformedMesh(self): self.planarMesh.append( [0.0,10.0,10.0] ) self.planarMesh.append( [10.0,0.0,10.0] ) self.planarMesh.append( [10.0,10.0,10.0] ) self.planarMesh.append( [6.0,8.0,10.0] ) self.planarMesh.append( [16.0,8.0,10.0] ) self.planarMesh.append( [6.0,18.0,10.0] ) planarMeshObject = Mesh.Mesh(self.planarMesh) mat = Base.Matrix() mat.rotateX(1.0) mat.rotateY(1.0) mat.rotateZ(1.0) planarMeshObject.transformGeometry(mat) f1 = planarMeshObject.Facets[0] f2 = planarMeshObject.Facets[1] res=f1.intersect(f2) self.assertEqual(len(res), 2)
def _matrix_from_svg(self, svgmat, coordcvt=True): """ Convert a 2D matrix from SVG into a FreeCAD 3D Matrix. e.g. mat = [[0.9659258262890683, 0.25881904510252074, 0.0], [-0.25881904510252074, 0.9659258262890683, 0.0]] If coordcvt is True, then coordinate system conversion from SVG to FreeCAD is applied to the matrix. Otherwise only datatype conversion is performed. Returns: e.g. Matrix ((0.965926,0.258819,0,0),(-0.258819,0.965926,0,0),(0,0,1,0),(0,0,0,1)) """ # FIXME: is the handling of svgmat[*][2] correct? self.m = Base.Matrix(svgmat[0][0], svgmat[0][1], 0, svgmat[0][2], svgmat[1][0], svgmat[1][1], 0, svgmat[1][2]) if coordcvt: self._coord_from_svg() return self.m
def get_joint_transform(self, joint): """Return the transform from base to joint Return a tuple (m, Pjminus1), where m is the transformation matrix from base (not base joint) to the joint, and Pjminus1 is the position of previous joint. """ # Get the list of joints from base to joint # The transform from the base to the base joint is given by # self.base_t. l = self.base_t[0] + self.base_t[1] + self.base_t[2] + self.base_t[3] from FreeCAD import Base m = Base.Matrix(*l) Pj = Base.Vector(0, 0, 0) for jnt in self.chain.get_subchain_to(joint): # Pjminus1 is Pj from the step before Pjminus1 = Pj m *= Ttomatrix(jnt.T) Pj = Base.Vector(m.A14, m.A24, m.A34) return m, Pjminus1
def makeBottleTut(myWidth=50.0, myHeight=70.0, myThickness=30.0): aPnt1 = Base.Vector(-myWidth / 2., 0, 0) aPnt2 = Base.Vector(-myWidth / 2., -myThickness / 4., 0) aPnt3 = Base.Vector(0, -myThickness / 2., 0) aPnt4 = Base.Vector(myWidth / 2., -myThickness / 4., 0) aPnt5 = Base.Vector(myWidth / 2., 0, 0) aArcOfCircle = Part.Arc(aPnt2, aPnt3, aPnt4) aSegment1 = Part.LineSegment(aPnt1, aPnt2) aSegment2 = Part.LineSegment(aPnt4, aPnt5) aEdge1 = aSegment1.toShape() aEdge2 = aArcOfCircle.toShape() aEdge3 = aSegment2.toShape() aWire = Part.Wire([aEdge1, aEdge2, aEdge3]) aTrsf = Base.Matrix() aTrsf.rotateZ(math.pi) # rotate around the z-axis aMirroredWire = aWire.copy() aMirroredWire.transformShape(aTrsf) myWireProfile = Part.Wire([aWire, aMirroredWire]) myFaceProfile = Part.Face(myWireProfile) aPrismVec = Base.Vector(0, 0, myHeight) myBody = myFaceProfile.extrude(aPrismVec) myBody = myBody.makeFillet(myThickness / 12.0, myBody.Edges) neckLocation = Base.Vector(0, 0, myHeight) neckNormal = Base.Vector(0, 0, 1) myNeckRadius = myThickness / 4. myNeckHeight = myHeight / 10. myNeck = Part.makeCylinder(myNeckRadius, myNeckHeight, neckLocation, neckNormal) myBody = myBody.fuse(myNeck) return myBody
def process(filename, scale, posX, posY, posZ, rotX, rotY, rotZ, useSpline, splitSpline, coords=[]): if len(coords) == 0: coords = readpointsonfile(filename) # do we use a BSpline? if useSpline: if splitSpline: #do we split between upper and lower side? if coords.__contains__(FreeCAD.Vector( 0, 0, 0)): # lgtm[py/modification-of-default-value] flippoint = coords.index(FreeCAD.Vector(0, 0, 0)) else: lenghtList = [v.Length for v in coords] flippoint = lenghtList.index(min(lenghtList)) splineLower = Part.BSplineCurve() splineUpper = Part.BSplineCurve() splineUpper.interpolate(coords[:flippoint + 1]) splineLower.interpolate(coords[flippoint:]) if coords[0] != coords[-1]: wire = Part.Wire([ splineUpper.toShape(), splineLower.toShape(), Part.makeLine(coords[0], coords[-1]) ]) else: wire = Part.Wire( [splineUpper.toShape(), splineLower.toShape()]) else: spline = Part.BSplineCurve() spline.interpolate(coords) if coords[0] != coords[-1]: wire = Part.Wire( [spline.toShape(), Part.makeLine(coords[0], coords[-1])]) else: wire = Part.Wire(spline.toShape()) else: # alternate solution, uses common Part Faces lines = [] first_v = None last_v = None for v in coords: if first_v is None: first_v = v # End of if first_v is None # Line between v and last_v if they're not equal if (last_v != None) and (last_v != v): lines.append(Part.makeLine(last_v, v)) # End of if (last_v != None) and (last_v != v) # The new last_v last_v = v # End of for v in upper # close the wire if needed if last_v != first_v: lines.append(Part.makeLine(last_v, first_v)) wire = Part.Wire(lines) face = Part.Face( wire ) #.scale(scale) #Scale the foil, # issue31 doesn't work with v0.18 myScale = Base.Matrix() # issue31 myScale.scale(scale, scale, scale) # issue31 face = face.transformGeometry(myScale) # issue31 return face, coords
def __init__(self, batteryWidth, batteryDepth, batteryHeight, row_betweenBattery, boxThickness, additionalHeight, rotation, x, y, z, scale_by_x, scale_by_y, scale_by_z): self.batteryWidth = batteryWidth self.batteryDepth = batteryDepth self.batteryHeight = batteryHeight self.row_betweenBattery = row_betweenBattery self.boxThickness = boxThickness self.additionalHeight = additionalHeight self.rotation = rotation self.x = x self.y = y self.z = z self.scale_by_x = scale_by_x self.scale_by_y = scale_by_y self.scale_by_z = scale_by_z # Scaling a shape (Masshtabirovaniye formy) myMat = Base.Matrix() myMat.scale(scale_by_x, scale_by_y, scale_by_z) wallLeftWidth = float(boxThickness) # Width (Shirina) (x) wallLeftDepth = float((5 * (batteryDepth) + row_betweenBattery * 6)) # Depth (glubina) (y) wallLeftHeight = float(batteryHeight + additionalHeight - 150) # Height (Vysota) (z) # Coordinates of the left wall of a box (Koordinaty levoy stenki yashchika)(x, y, z) LeftWall_X = float( (-batteryWidth - 2 * row_betweenBattery - boxThickness)) LeftWall_Y = float(-row_betweenBattery) LeftWall_Z = float(0.0) # Form of the left wall of a box (Forma levoy stenki korobki) boxShapeLTh = Part.makeBox( wallLeftWidth, wallLeftDepth, wallLeftHeight, Base.Vector(LeftWall_X, LeftWall_Y, LeftWall_Z)) # Turn of the left wall of a box (Povorot levoy steny korobki) boxShapeLTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShapeLTh = boxShapeLTh.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box1 = document.addObject('Part::Feature', 'Box') box1.Shape = boxShapeLTh # Right wall of a box (Pravaya stenka korobki) (x, y, z) wallRightWidth = float(boxThickness) # Width (Shirina) (x) wallRightDepth = float((5 * (batteryDepth) + row_betweenBattery * 6)) # Depth (glubina) (y) wallRightHeight = float( (batteryHeight + additionalHeight - 150)) # Height (Vysota) (z) # Coordinates of the right wall of a box (Koordinaty pravoy stenki yashchika) (x, y, z) RightWall_X = float(batteryWidth + row_betweenBattery) RightWall_Y = float(-row_betweenBattery) RightWall_Z = float(0.0) # Form of the right wall of a box (Forma pravoy stenki yashchika) boxShapeRTh = Part.makeBox( wallRightWidth, wallRightDepth, wallRightHeight, Base.Vector(RightWall_X, RightWall_Y, RightWall_Z)) # Turn of the right wall of a box (Povorot pravoy stenki yashchika) boxShapeRTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShapeRTh = boxShapeRTh.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box2 = document.addObject('Part::Feature', 'Box') box2.Shape = boxShapeRTh # Front face of a box (Perednyaya storona korobki) (x, y, z) wallAnteriortWidth = float((2 * batteryWidth + row_betweenBattery * 3 + 2 * boxThickness)) # Width (Shirina) (x) wallAnteriortDepth = float(boxThickness) # Depth (glubina) (y) wallAnteriortHeight = float( (batteryHeight + additionalHeight - 150)) # Height (Vysota) (z) # Coordinates of a front wall of a box (Koordinaty peredney stenki korobki) (x, y, z) AnteriortWall_X = float( (-batteryWidth - 2 * row_betweenBattery - boxThickness)) AnteriortWall_Y = float((-row_betweenBattery - boxThickness)) AnteriortWall_Z = float(0.0) # Form of a front wall of a box (Forma peredney stenki korobki) boxShapeATh = Part.makeBox( wallAnteriortWidth, wallAnteriortDepth, wallAnteriortHeight, Base.Vector(AnteriortWall_X, AnteriortWall_Y, AnteriortWall_Z)) # Turn of a front wall of a box (Povorot peredney stenki korobki) boxShapeATh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShapeATh = boxShapeATh.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box3 = document.addObject('Part::Feature', 'Box') box3.Shape = boxShapeATh # Back face of a box (Zadnyaya storona korobki) (x, y, z) wallPosteriorWidth = float((2 * batteryWidth + row_betweenBattery * 3 + 2 * boxThickness)) # Width (Shirina) (x) wallPosteriorDepth = float(boxThickness) # Depth (glubina) (y) wallPosteriorHeight = float( (batteryHeight + additionalHeight - 150)) # Height (Vysota) (z) # Coordinates of a back wall of a box (Koordinaty zadney stenki yashchika) (x, y, z) PosteriorWall_X = float( (-batteryWidth - 2 * row_betweenBattery - boxThickness)) PosteriorWall_Y = float((5 * row_betweenBattery + 5 * batteryDepth)) PosteriorWall_Z = float(0.0) # Form of a back wall of a box (Forma zadney stenki korobki) boxShapePTh = Part.makeBox( wallPosteriorWidth, wallPosteriorDepth, wallPosteriorHeight, Base.Vector(PosteriorWall_X, PosteriorWall_Y, PosteriorWall_Z)) # Turn of a back wall of a box (Povorot zadney stenki yashchika) boxShapePTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShapePTh = boxShapePTh.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box4 = document.addObject('Part::Feature', 'Box') box4.Shape = boxShapePTh # Lower side of a box (Nizhnyaya storona korobki) (x, y, z) wallLowerWidth = float((2 * batteryWidth + row_betweenBattery * 3 + 2 * boxThickness)) # Width (Shirina) (x) wallLowerDepth = float(6 * row_betweenBattery + +5 * batteryDepth + 2 * boxThickness) # Depth (glubina) (y) wallLowerHeight = float(boxThickness) # Height (Vysota) (z) # Coordinates of the lower wall of a box (Koordinaty nizhney stenki yashchika) (x, y, z) LowerWall_X = float( (-batteryWidth - 2 * row_betweenBattery - boxThickness)) LowerWall_Y = float((-row_betweenBattery - boxThickness)) LowerWall_Z = float(-boxThickness) # Form of the lower wall of a box (Forma nizhney stenki yashchika) boxShapeLoTh = Part.makeBox( wallLowerWidth, wallLowerDepth, wallLowerHeight, Base.Vector(LowerWall_X, LowerWall_Y, LowerWall_Z)) # Turn of the lower wall of a box (Povorot nizhney stenki yashchika) boxShapeLoTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShapeLoTh = boxShapeLoTh.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box5 = document.addObject('Part::Feature', 'Box') box5.Shape = boxShapeLoTh # Layouts of a cube for the 1st row (Makety kuba dlya 1-y stroki) (x,y,z) row1_cubeLocation_X = float(0.0) # Width (Shirina) (x) row1_cubeLocation_Y = float(batteryDepth) # Depth (glubina) (y) row1_cubeLocation_Z = float(0.0) # Height (Vysota) (z) # Layouts of a cube for the 2nd row (Makety kuba dlya vtoroy stroki) (x, y, z) row2_cubeLocation_X = float( (-batteryWidth - row_betweenBattery)) # Width (Shirina) (x) row2_cubeLocation_Y = float(batteryDepth) # Depth (glubina) (y) row2_cubeLocation_Z = float(0.0) # Height (Vysota) (z) # Form of a cube of the 1st row (1) (Forma kuba 1-go ryada (1)) boxShape_1_1 = Part.makeBox(batteryWidth, batteryDepth, batteryHeight, Base.Vector(0, 0, 0)) # Turn of a cube of the 1st row, the 2nd cube (Povorot kuba 1-go ryada, 2-y kub) boxShape_1_1.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_1_1 = boxShape_1_1.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_1_1 # Form of a cube of the 1st row (2) (Forma kuba 1-go ryada (2)) boxShape_1_2 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row1_cubeLocation_X, row1_cubeLocation_Y + row_betweenBattery, row1_cubeLocation_Z)) # Turn of a cube of the 1st row, the 2nd cube (Povorot kuba 1-go ryada, 2-y kub) boxShape_1_2.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_1_2 = boxShape_1_2.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_1_2 # Form of a cube of the 1st row (3) (Forma kuba 1-go ryada (3)) boxShape_1_3 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row1_cubeLocation_X, 2 * (row1_cubeLocation_Y) + row_betweenBattery * 2, row1_cubeLocation_Z)) # Turn of a cube of the 1st row, the 3rd cube (Povorot kuba 1-go ryada, 3-go kuba) boxShape_1_3.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_1_3 = boxShape_1_3.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_1_3 # Form of a cube of the 1st row (4) (Forma kuba 1-go ryada (4)) boxShape_1_4 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row1_cubeLocation_X, 3 * (row1_cubeLocation_Y) + row_betweenBattery * 3, row1_cubeLocation_Z)) # Turn of a cube of the 1st row, the 4th cube (Povorot kuba 1-go ryada, 4-y kub) boxShape_1_4.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_1_4 = boxShape_1_4.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_1_4 # Form of a cube of the 1st row (5) (Forma kuba 1-go ryada (5)) boxShape_1_5 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row1_cubeLocation_X, 4 * (row1_cubeLocation_Y) + row_betweenBattery * 4, row1_cubeLocation_Z)) # Turn of a cube of the 1st row, the 5th cube (Povorot kuba 1-go ryada, 5-y kub) boxShape_1_5.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_1_5 = boxShape_1_5.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_1_5 # Form of a cube of the 2nd row (1) (Forma kuba vtorogo ryada (1)) boxShape_2_1 = Part.makeBox(batteryWidth, batteryDepth, batteryHeight, Base.Vector(row2_cubeLocation_X, 0, 0)) # Turn of a cube of the 2nd row, the 1st cube (Povorot kuba 2-go ryada, 1-y kub) boxShape_2_1.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_2_1 = boxShape_2_1.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_2_1 # Form of a cube of the 2nd row (2) (Forma kuba vtorogo ryada (2)) boxShape_2_2 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row2_cubeLocation_X, row1_cubeLocation_Y + row_betweenBattery, row1_cubeLocation_Z)) # Turn of a cube of the 2nd row, the 2nd cube (Povorot kuba 2-go ryada, 2-y kub) boxShape_2_2.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_2_2 = boxShape_2_2.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_2_2 # Form of a cube of the 2nd row (3) (Forma kuba vtorogo ryada (3)) boxShape_2_3 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row2_cubeLocation_X, 2 * (row1_cubeLocation_Y) + row_betweenBattery * 2, row1_cubeLocation_Z)) # Turn of a cube of the 2nd row, the 3rd cube (Povorot kuba 2-go ryada, 3-go kuba) boxShape_2_3.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_2_3 = boxShape_2_3.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_2_3 # Form of a cube of the 2nd row (4) (Forma kuba vtorogo ryada (4)) boxShape_2_4 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row2_cubeLocation_X, 3 * (row1_cubeLocation_Y) + row_betweenBattery * 3, row1_cubeLocation_Z)) # Turn of a cube of the 2nd row, the 4th cube (Povorot kuba 2-go ryada, 4-y kub) boxShape_2_4.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_2_4 = boxShape_2_4.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_2_4 # Form of a cube of the 2nd row (5) (Forma kuba 2-go ryada (5)) boxShape_2_5 = Part.makeBox( batteryWidth, batteryDepth, batteryHeight, Base.Vector(row2_cubeLocation_X, 4 * (row1_cubeLocation_Y) + row_betweenBattery * 4, row1_cubeLocation_Z)) # Turn of a cube of the 2nd row, the 5th cube (Povorot kuba 2-go ryada, 5-y kub) boxShape_2_5.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(x, y, z), rotation) # Scaling a shape (Masshtabirovaniye formy) boxShape_2_5 = boxShape_2_5.transformGeometry(myMat) # Object for display of the form (Ob"yekt dlya otobrazheniya formy) box = document.addObject('Part::Feature', 'Box') box.Shape = boxShape_2_5 ############################################################################################## ### self.partVersion = "1.0" ### self.box1Clone = Draft.clone(box1) self.box2Clone = Draft.clone(box2) self.box3Clone = Draft.clone(box3) self.box4Clone = Draft.clone(box4) self.box5Clone = Draft.clone(box5) self.box6Clone = Draft.clone(box5) ### boxShapeLTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(1, 0, 0), -90) boxShapeRTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(1, 0, 0), -90) boxShapeATh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(1, 0, 0), -90) boxShapePTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(1, 0, 0), -90) boxShapeLoTh.rotate( Base.Vector( (-batteryWidth - 2 * row_betweenBattery - boxThickness), (-row_betweenBattery), 0), Base.Vector(1, 0, 0), -90) ### self.box1Clone.Shape = boxShapeLTh self.box2Clone.Shape = boxShapeRTh self.box3Clone.Shape = boxShapeATh self.box4Clone.Shape = boxShapePTh self.box5Clone.Shape = boxShapeLoTh self.box6Clone.Shape = boxShapeLoTh ### self.box1Clone.ViewObject.Visibility = 0 self.box2Clone.ViewObject.Visibility = 0 self.box3Clone.ViewObject.Visibility = 0 self.box4Clone.ViewObject.Visibility = 0 self.box5Clone.ViewObject.Visibility = 0 self.box6Clone.ViewObject.Visibility = 0 ### shelveGroup.addObject(self.box1Clone) shelveGroup.addObject(self.box2Clone) shelveGroup.addObject(self.box3Clone) shelveGroup.addObject(self.box4Clone) shelveGroup.addObject(self.box5Clone) shelveGroup.addObject(self.box6Clone)
def transform_solid(matrix, solid): """ Utility funciton to apply mathutils.Matrix to a Solid object. """ mat = Base.Matrix(*[i for v in matrix for i in v]) return solid.transformGeometry(mat)
def objArc(self, d, cx, cy, rx, ry, st, en, closed, node, mat): """ We ignore the path d, and produce a nice arc object. We distinguish two cases. If it looks like a circle, we produce ArcOfCircle, else we produce ArcOfEllipse. To find the arc end points, we use the value() property of the Circle and Ellipse objects. With Circle we have to take care of mirror and rotation ourselves. If closed, we connect the two ends to the center with lines. The connections are secured with constraints. Radii are currently not secured with constraints. """ ### CAUTION: Keep in sync with objEllipse() above. # print("objArc: st,en,closed", st, en, closed) self._matrix_from_svg(mat) c = self._from_svg(cx, cy, bbox=False) ori = self._from_svg(0, 0, bbox=False) vrx = self._from_svg(rx, 0, bbox=False) - ori vry = self._from_svg(0, ry, bbox=False) - ori i = self.ske.GeometryCount (st_idx, en_idx) = (1, 2) majAxisIdx = None if abs(vrx.Length - vry.Length) < epsilon: # it is a circle. self.bbox.add(c + vrx + vry) self.bbox.add(c - vrx - vry) ce = Part.Circle(Center=c, Normal=Base.Vector(0, 0, 1), Radius=vrx.Length) # Circles are immune to rotation and mirorring. Apply this manually. if self.yflip: (st, en) = (-en, -st) ## coord system is mirrored. else: (st, en) = (en, st) ## hmm. print("FIXME: ArcOfCircle() with yflip=False needs debugging.") r = Base.Matrix() r.rotateZ(st) pst = r.multiply(vrx) st = pst.getAngle(Base.Vector( 1, 0, 0)) # ce.rotateZ() is a strange beast. pst = pst + c r = Base.Matrix() r.rotateZ(en) pen = r.multiply(vrx) en = pen.getAngle(Base.Vector( 1, 0, 0)) # ce.rotateZ() is a strange beast. pen = pen + c self.ske.addGeometry([Part.ArcOfCircle(ce, st, en)]) self.stats['objArc'] += 1 else: # major axis is defined by Center and S1, # major radius is the distance between Center and S1, # minor radius is the distance between S2 and the major axis. s1 = self._from_svg(cx + rx, cy, bbox=False) s2 = self._from_svg(cx, cy + ry, bbox=False) (V1, V2, V3, V4) = self._ellipse_vertices2d(c, s1, s2) self.bbox.add(V1) self.bbox.add(V2) self.bbox.add(V3) self.bbox.add(V4) i = int(self.ske.GeometryCount) ce = Part.Ellipse(S1=V1, S2=V2, Center=c) self.ske.addGeometry([Part.ArcOfEllipse(ce, st, en)]) if self.expose_int: self.ske.exposeInternalGeometry(i) majAxisIdx = i + 1 # CAUTION: is that a safe assumption? self.stats['objArc'] += 1 ## CAUTION: with yflip=True sketcher reverses the endpoints of ## an ArcOfEllipse to: en=1, st=2 ## ArcOfCircle seems unaffected. if self.yflip: (st_idx, en_idx) = (2, 1) r = Base.Matrix() r.rotateZ(st) pst = r.multiply(vrx) + c r = Base.Matrix() r.rotateZ(en) pen = r.multiply(vrx) + c j = self.ske.GeometryCount if closed: self.ske.addGeometry([ Part.LineSegment(ce.value(en), c), Part.LineSegment(c, ce.value(st)) ]) if True: # when debugging deformations, switch off constriants first. self.ske.addConstraint([ Sketcher.Constraint('Coincident', i + 0, en_idx, j + 0, 1), # arc with line Sketcher.Constraint('Coincident', j + 1, 2, i + 0, st_idx), # line with arc Sketcher.Constraint('Coincident', j + 0, 2, j + 1, 1), # line with line Sketcher.Constraint('Coincident', j + 0, 2, i + 0, 3) ]) # line with center if False: # some debugging circles. self.ske.addGeometry( [ # Part.Circle(Center=pst, Normal=Base.Vector(0,0,1), Radius=2), # Part.Circle(Center=pen, Normal=Base.Vector(0,0,1), Radius=3), # Part.Circle(Center=ce.value(st), Normal=Base.Vector(0,0,1), Radius=4), Part.Circle(Center=ce.value(en), Normal=Base.Vector(0, 0, 1), Radius=5) ], True) # we return the start, end and center points, as triple (sketcher_index, sketcher_index_point, Vector) return ((i + 0, st_idx, ce.value(st)), (i + 0, en_idx, ce.value(en)), (i + 0, 3, c), majAxisIdx)
def Ttomatrix(T): # TODO: remove FreeCAD dependency from this module from FreeCAD import Base # Flatten converts a matrix into an array and then it is converted into a list l = T.flatten().tolist() return Base.Matrix(*l)
def build_freecad(self, doc, xoffset=0.0, yoffset=0.0, twist=0.0): doc.make_extra_group('Wing_' + self.name) # right_ref = Base.Vector(0, xoffset, yoffset) # left_ref = Base.Vector(0, -xoffset, yoffset) # right_rot = Base.Rotation(Base.Vector(1, 0, 0), self.dihedral) # right_pl = FreeCAD.Placement(right_ref, right_rot) # left_rot = Base.Rotation(Base.Vector(1, 0, 0), -self.dihedral) # left_pl = FreeCAD.Placement(left_ref, left_rot) right_m = Base.Matrix() right_m.rotateY(math.radians(-twist)) right_m.rotateX(math.radians(self.dihedral)) right_m.move(Base.Vector(0, xoffset, yoffset)) left_m = Base.Matrix() left_m.rotateY(math.radians(-twist)) left_m.rotateX(math.radians(-self.dihedral)) left_m.move(Base.Vector(0, -xoffset, yoffset)) left_pl = FreeCAD.Placement(left_m) right_pl = FreeCAD.Placement(right_m) # make parts for rib in self.right_ribs: part = doc.make_object(rib.contour.poly, rib.thickness, rib.pos, rib.nudge) part.Placement = right_pl doc.add_object("kit", "rib", part) for rib in self.left_ribs: part = doc.make_object(rib.contour.poly, rib.thickness, rib.pos, rib.nudge) part.Placement = left_pl doc.add_object("kit", "rib", part) for te in self.trailing_edges: if te.side == "left": part = doc.make_extrusion("trailing edge", te.points, te.side == "left") part.Placement = left_pl doc.add_object('stock', "trailing edge", part) if te.side == "right": part = doc.make_extrusion("trailing edge", te.points, te.side == "left") part.Placement = right_pl doc.add_object('stock', "trailing edge", part) for le in self.leading_edges: if le.side == "left": part = doc.make_extrusion("leading edge", le.points, le.side == "left") part.Placement = left_pl doc.add_object('stock', "leading edge", part) if le.side == "right": part = doc.make_extrusion("leading edge", le.points, le.side == "left") part.Placement = right_pl doc.add_object('stock', "leading edge", part) for spar in self.spars: if spar.side == "left": part = doc.make_extrusion("spar", spar.points, spar.side == "left") part.Placement = left_pl doc.add_object('stock', "spar", part) if spar.side == "right": part = doc.make_extrusion("spar", spar.points, spar.side == "left") part.Placement = right_pl doc.add_object('stock', "spar", part) for stringer in self.stringers: if stringer.side == "left": part = doc.make_extrusion("stringer", stringer.points, stringer.side == "left") part.Placement = left_pl doc.add_object('stock', "stringer", part) if stringer.side == "right": part = doc.make_extrusion("stringer", stringer.points, stringer.side == "left") part.Placement = right_pl doc.add_object('stock', "stringer", part)
import Part, math from FreeCAD import Base size = 10 poly = Part.makePolygon([(0, 0, 0), (size, 0, 0), (size, 0, size), (0, 0, size), (0, 0, 0)]) face1 = Part.Face(poly) face2 = Part.Face(poly) face3 = Part.Face(poly) face4 = Part.Face(poly) face5 = Part.Face(poly) face6 = Part.Face(poly) myMat = Base.Matrix() myMat.rotateZ(math.pi / 2) face2.transformShape(myMat) face2.translate(Base.Vector(size, 0, 0)) myMat.rotateZ(math.pi / 2) face3.transformShape(myMat) face3.translate(Base.Vector(size, size, 0)) myMat.rotateZ(math.pi / 2) face4.transformShape(myMat) face4.translate(Base.Vector(0, size, 0)) myMat = Base.Matrix() myMat.rotateX(-math.pi / 2)
def makeMatrix(self, transformation): """takes a cgkit.cgtypes.mat4, returns FreeCAD.Matrix""" m = Base.Matrix() (m.A11, m.A21, m.A31, m.A41, m.A12, m.A22, m.A32, m.A42, m.A13, m.A23, m.A33, m.A43, m.A14, m.A24, m.A34, m.A44) = transformation.toList() return m