def createObject(self): """Create the actual object in the current document.""" plane = App.DraftWorkingPlane p1 = self.node[0] p3 = self.node[-1] diagonal = p3.sub(p1) halfdiag = App.Vector(diagonal).multiply(0.5) center = p1.add(halfdiag) p2 = p1.add(DraftVecUtils.project(diagonal, plane.v)) p4 = p1.add(DraftVecUtils.project(diagonal, plane.u)) r1 = (p4.sub(p1).Length) / 2 r2 = (p2.sub(p1).Length) / 2 try: # The command to run is built as a series of text strings # to be committed through the `draftutils.todo.ToDo` class. rot, sup, pts, fil = self.getStrings() if r2 > r1: r1, r2 = r2, r1 m = App.Matrix() m.rotateZ(math.pi / 2) rot1 = App.Rotation() rot1.Q = eval(rot) rot2 = App.Placement(m) rot2 = rot2.Rotation rot = str((rot1.multiply(rot2)).Q) if utils.getParam("UsePartPrimitives", False): # Insert a Part::Primitive object Gui.addModule("Part") _cmd = 'FreeCAD.ActiveDocument.' _cmd += 'addObject("Part::Ellipse", "Ellipse")' _cmd_list = [ 'ellipse = ' + _cmd, 'ellipse.MajorRadius = ' + str(r1), 'ellipse.MinorRadius = ' + str(r2), 'pl = FreeCAD.Placement()', 'pl.Rotation.Q= ' + rot, 'pl.Base = ' + DraftVecUtils.toString(center), 'ellipse.Placement = pl', 'Draft.autogroup(ellipse)', 'FreeCAD.ActiveDocument.recompute()' ] self.commit(translate("draft", "Create Ellipse"), _cmd_list) else: # Insert a Draft ellipse Gui.addModule("Draft") _cmd = 'Draft.makeEllipse' _cmd += '(' _cmd += str(r1) + ', ' + str(r2) + ', ' _cmd += 'placement=pl, ' _cmd += 'face=' + fil + ', ' _cmd += 'support=' + sup _cmd += ')' _cmd_list = [ 'pl = FreeCAD.Placement()', 'pl.Rotation.Q = ' + rot, 'pl.Base = ' + DraftVecUtils.toString(center), 'ellipse = ' + _cmd, 'Draft.autogroup(ellipse)', 'FreeCAD.ActiveDocument.recompute()' ] self.commit(translate("draft", "Create Ellipse"), _cmd_list) except Exception: _err("Draft: Error: Unable to create object.") self.finish(cont=True)
def getPlaneRotation(u, v, w=None): "returns a rotation matrix defining the (u,v,w) coordinates system" if (not u) or (not v): return None if not w: w = u.cross(v) typecheck([(u, Vector), (v, Vector), (w, Vector)], "getPlaneRotation") m = FreeCAD.Matrix(u.x, v.x, w.x, 0, u.y, v.y, w.y, 0, u.z, v.z, w.z, 0, 0.0, 0.0, 0.0, 1.0) return m
def matrixAt(self, p, i): t = self.rails[i].valueAt(p) u,v,w = self.frameAt(p,i) m = FreeCAD.Matrix( u.x, v.x, w.x, t.x, u.y, v.y, w.y, t.y, u.z, v.z, w.z, t.z, 0.0, 0.0, 0.0, 1.0) return(m)
def execute(self, fp): m = fp.module.Value teeth = fp.teeth r_r = fp.bolt_radius.Value r_0 = m * teeth / 2 r_max = r_0 + r_r + fp.head * m phi_max = (r_r + np.sqrt(r_max**2 - r_0**2)) / r_0 def find_phi_min(phi_min): return r_0*(phi_min**2*r_0 - 2*phi_min*r_0*np.sin(phi_min) - \ 2*phi_min*r_r - 2*r_0*np.cos(phi_min) + 2*r_0 + 2*r_r*np.sin(phi_min)) try: import scipy.optimize phi_min = scipy.optimize.root(find_phi_min, (phi_max + r_r / r_0 * 4) / 5).x[0] # , r_r / r_0, phi_max) except ImportError: App.Console.PrintWarning("scipy not available. Can't compute numerical root. Leads to a wrong bolt-radius") phi_min = r_r / r_0 # phi_min = 0 # r_r / r_0 phi = np.linspace(phi_min, phi_max, fp.num_profiles) x = r_0 * (np.cos(phi) + phi * np.sin(phi)) - r_r * np.sin(phi) y = r_0 * (np.sin(phi) - phi * np.cos(phi)) + r_r * np.cos(phi) xy1 = np.array([x, y]).T p_1 = xy1[0] p_1_end = xy1[-1] bsp_1 = BSplineCurve() bsp_1.interpolate(list(map(fcvec, xy1))) w_1 = bsp_1.toShape() xy2 = xy1 * np.array([1., -1.]) p_2 = xy2[0] p_2_end = xy2[-1] bsp_2 = BSplineCurve() bsp_2.interpolate(list(map(fcvec, xy2))) w_2 = bsp_2.toShape() p_12 = np.array([r_0 - r_r, 0.]) arc = Part.Arc(App.Vector(*p_1, 0.), App.Vector(*p_12, 0.), App.Vector(*p_2, 0.)).toShape() rot = rotation(-np.pi * 2 / teeth) p_3 = rot(np.array([p_2_end]))[0] # l = Part.LineSegment(fcvec(p_1_end), fcvec(p_3)).toShape() l = part_arc_from_points_and_center(p_1_end, p_3, np.array([0., 0.])).toShape() w = Part.Wire([w_2, arc, w_1, l]) wires = [w] rot = App.Matrix() for _ in range(teeth - 1): rot.rotateZ(np.pi * 2 / teeth) wires.append(w.transformGeometry(rot)) wi = Part.Wire(wires) if fp.height.Value == 0: fp.Shape = wi else: fp.Shape = Part.Face(wi).extrude(App.Vector(0, 0, fp.height))
def makeSurfaceFromSag(self, obj, rpoints=10, phipoints=12): shape = obj.shapeclass aperture = obj.apertureclass coords = obj.LocalCoordinatesLink.globalcoordinates basisX = obj.LocalCoordinatesLink.localbasisX basisY = obj.LocalCoordinatesLink.localbasisY basisZ = obj.LocalCoordinatesLink.localbasisZ vobj = obj.ViewObject surshape = None if aperture.annotations["typicaldimension"] < 100.0: surPoints = [] rvalues = np.linspace(0, aperture.annotations["typicaldimension"], rpoints) phivalues = np.linspace(0, 2 * math.pi - 2 * math.pi / phipoints, phipoints) PHI, R = np.meshgrid(phivalues, rvalues) X = (R * np.cos(PHI)).reshape((rpoints * phipoints, )).T Y = (R * np.sin(PHI)).reshape((rpoints * phipoints, )).T Z = shape.getSag(X, Y) Z[np.isnan( Z)] = 0.0 # something has to happen if sqrts become negative # TODO: setting values to last defined values # TODO: constructing wires set from last defined values # TODO: generating final aperture from this wires set XYZ = np.vstack((X, Y, Z)).T XYZ = XYZ.reshape((rpoints, phipoints, 3)) surPoints = [[FreeCAD.Base.Vector(*p) for p in r] for r in XYZ.tolist()] sur = Part.BSplineSurface() sur.interpolate(surPoints) sur.setVPeriodic() surshape = sur.toShape() vobj.ShapeColor = (0., 0., 1.) else: surshape = Part.makePlane(2, 2) surshape.translate((-1, -1, 0)) vobj.ShapeColor = (1., 0., 0.) surshape.transformShape( FreeCAD.Matrix(basisX[0], basisY[0], basisZ[0], 0, basisX[1], basisY[1], basisZ[1], 0, basisX[2], basisY[2], basisZ[2], 0, 0, 0, 0, 1)) surshape.translate(coords) return surshape
def execute(self,obj): v1 = obj.v1 v2 = obj.v2 v3 = obj.v3 m = App.Matrix( v1.x, v2.x, v3.x, 0, v1.y, v2.y, v3.y, 0, v1.z, v2.z, v3.z, 0, 0, 0, 0, 1 ) obj.Shape = obj.Base.Shape.transformGeometry(m)
def createGeometry(self, fp): print("Resize create Geometry") import FreeCAD mat = FreeCAD.Matrix() mat.A11 = self.Vector[0] mat.A22 = self.Vector[1] mat.A33 = self.Vector[2] print(mat) fp.Shape = self.Target.Shape.transformGeometry(mat)
def wire_sim_xy(vecList): edgList = [] if vecList[0].x != 0: # the first element is not on the Y axis,so we create a first point vec = FreeCAD.Vector(0, vecList[0].y, vecList[0].z) seg = Part.Line(vec, vecList[0]) # segment edg = seg.toShape() # edge edgList.append(edg) # append to the edge list listlen = len(vecList) for index, vec in enumerate(vecList): if vec.x < 0 or vec.y < 0: logger.error('WireSimXY with negative points') if index < listlen - 1: # it is not the last element seg = Part.Line(vec, vecList[index + 1]) edg = seg.toShape() edgList.append(edg) index += 1 if vecList[-1].y != 0: # the last element is not on the X axis vec = FreeCAD.Vector(vecList[-1].x, 0, vecList[-1].z) seg = Part.Line(vecList[-1], vec) edg = seg.toShape() edgList.append(edg) # the wire for the first cuadrant, quarter quwire = Part.Wire(edgList) # mirror on Y axis MirY = FreeCAD.Matrix() MirY.scale(FreeCAD.Vector(-1, 1, 1)) mir_quwire = quwire.transformGeometry(MirY) # another option # mir_quwire = quwire.mirror(FreeCAD.Vector(0,0,0), FreeCAD.Vector(1,0,0)) #halfwire = Part.Wire([quwire, mir_quwire]) # get the half wire halfwire = Part.Wire([mir_quwire, quwire]) # get the half wire # otherwise it doesnt work because the edges are not aligned halfwire.fixWire() # mirror on X axis MirX = FreeCAD.Matrix() MirX.scale(FreeCAD.Vector(1, -1, 1)) mir_halfwire = halfwire.transformGeometry(MirX) totwire = Part.Wire([mir_halfwire, halfwire]) # get the total wire totwire.fixWire() return totwire
def toggleMesh(self, checked=False): "turns mesh display on/off" if not FreeCAD.ActiveDocument: FreeCAD.newDocument() if FreeCAD.ActiveDocument: if checked: if self.mesh: self.mesh.ViewObject.show() else: import importIFC s = importIFC.getScaling(self.ifc) s *= 1000 # ifcopenshell outputs its meshes in metres trf = None if s != 1: trf = FreeCAD.Matrix() trf.scale(s, s, s) basemesh = Mesh.Mesh() import ifcopenshell from ifcopenshell import geom s = geom.settings() s.set(s.USE_WORLD_COORDS, True) for product in self.products: try: m = geom.create_shape(s, product) g = m.geometry v = g.verts f = g.faces verts = [ FreeCAD.Vector(v[i:i + 3]) for i in range(0, len(v), 3) ] faces = [ tuple(f[i:i + 3]) for i in range(0, len(f), 3) ] omesh = Mesh.Mesh((verts, faces)) if trf: omesh.transform(trf) self.omeshes[product.id()] = omesh basemesh.addMesh(omesh) except: pass self.mesh = FreeCAD.ActiveDocument.addObject( "Mesh::Feature", "IFCMesh") self.mesh.Mesh = basemesh self.mesh.ViewObject.Transparency = 85 FreeCAD.ActiveDocument.recompute() FreeCADGui.Selection.clearSelection() FreeCADGui.Selection.addSelection(self.mesh) FreeCADGui.SendMsgToActiveView("ViewSelection") else: if self.mesh: self.mesh.ViewObject.hide() if self.currentmesh: self.currentmesh.ViewObject.hide()
def accept(self): CS1_1 = self.form.CS1_1.value() CS1_2 = self.form.CS1_2.value() CS2_1 = self.form.CS2_1.value() CS2_2 = self.form.CS2_2.value() CT_1 = self.form.CT1.value() CT_2 = self.form.CT2.value() D = self.form.D.value() ILD = self.form.ILD.value() X = self.form.Xpos.value() Y = self.form.Ypos.value() Z = self.form.Zpos.value() Xrot = self.form.Xrot.value() Yrot = self.form.Yrot.value() Zrot = self.form.Zrot.value() matcat1 = self.form.mat1.Catalog.currentText() if matcat1 == "Value": matref1 = str(self.form.mat1.Value.value()) else: matref1 = self.form.mat1.Reference.currentText() matcat2 = self.form.mat2.Catalog.currentText() if matcat2 == "Value": matref2 = str(self.form.mat2.Value.value()) else: matref2 = self.form.mat2.Reference.currentText() obj = InsertDL( CS1_1, CS2_1, CT_1, CS1_2, CS2_2, CT_2, D, ILD, "L", matcat1, matref1, matcat2, matref2, ) m = FreeCAD.Matrix() m.rotateX(radians(Xrot)) m.rotateY(radians(Yrot)) m.rotateZ(radians(Zrot)) m.move((X, Y, Z)) p1 = FreeCAD.Placement(m) obj.Placement = p1 FreeCADGui.Control.closeDialog()
def getShape(obj): "gets a shape from an IfcOpenShell object" import StringIO sh = Part.Shape() sh.importBrep(StringIO.StringIO(obj.mesh.brep_data)) m = obj.matrix mat = FreeCAD.Matrix(m[0], m[3], m[6], m[9], m[1], m[4], m[7], m[10], m[2], m[5], m[8], m[11], 0, 0, 0, 1) sh.Placement = FreeCAD.Placement(mat) return sh
def run_FreeCAD_Toy(self): self.setNodename("HU"+str(time.time())) self.setImage("freecad_cone") pml=[1,2,3,4,5,6,7,8,10,11,12,12,14,15,16,] tt=FreeCAD.Placement(FreeCAD.Matrix(*pml)) pm2=self.getPinPlacement("PlacementPin_in") say("got",pm2) self.setPinPlacement("PlacementPin_out",tt.multiply(pm2))
def testRotation(self): r = FreeCAD.Rotation(1, 0, 0, 0) # 180 deg around (1,0,0) self.assertEqual(r.Axis, FreeCAD.Vector(1, 0, 0)) self.assertAlmostEqual(math.fabs(r.Angle), math.fabs(math.pi)) r = r.multiply(r) # identity self.assertEqual(r.Axis, FreeCAD.Vector(0, 0, 1)) self.assertAlmostEqual(r.Angle, 0) r = FreeCAD.Rotation(1, 0, 0, 0) r.Q = (0, 0, 0, 1) # update axis and angle s = FreeCAD.Rotation(0, 0, 0, 1) self.assertEqual(r.Axis, s.Axis) self.assertAlmostEqual(r.Angle, s.Angle) self.assertTrue(r.isSame(s)) r = FreeCAD.Rotation(1, 0, 0, 0) r.Matrix = FreeCAD.Matrix() # update axis and angle s = FreeCAD.Rotation(0, 0, 0, 1) self.assertEqual(r.Axis, s.Axis) self.assertAlmostEqual(r.Angle, s.Angle) self.assertTrue(r.isSame(s)) r = FreeCAD.Rotation(1, 0, 0, 0) r.Axes = (FreeCAD.Vector(0, 0, 1), FreeCAD.Vector(0, 0, 1) ) # update axis and angle s = FreeCAD.Rotation(0, 0, 0, 1) self.assertEqual(r.Axis, s.Axis) self.assertAlmostEqual(r.Angle, s.Angle) self.assertTrue(r.isSame(s)) #add 360 deg to angle r = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 270) s = FreeCAD.Rotation(FreeCAD.Vector(1, 0, 0), 270 + 360) self.assertEqual(r.Axis, s.Axis) #self.assertAlmostEqual(r.Angle, s.Angle + 2*math.pi) self.assertTrue(r.isSame(s)) #subtract 360 deg from angle using Euler angles r = FreeCAD.Rotation(0, 0, 180) r.invert() s = FreeCAD.Rotation(0, 0, -180) self.assertTrue(r.isSame(s)) #subtract 360 deg from angle using quaternion r = FreeCAD.Rotation(1, 0, 0, 0) s = FreeCAD.Rotation(-1, 0, 0, 0) #angles have the same sign if r.Angle * s.Angle > 0: self.assertEqual(r.Axis, s.Axis * (-1)) else: self.assertAlmostEqual(r.Angle, -s.Angle) self.assertTrue(r.isSame(s)) r.invert() self.assertTrue(r.isSame(s))
def transform_to_n(self, profile, p, n): '''transform a profile (Shape): rotating from t to n and translating from 0 to p''' n.normalize() t = sketch_normal(n, self.Object.path) t.normalize() v = n.cross(t) v.normalize() rot_mat = App.Matrix() rot_mat.A11 = t.x rot_mat.A21 = t.y rot_mat.A31 = t.z rot_mat.A12 = v.x rot_mat.A22 = v.y rot_mat.A32 = v.z rot_mat.A13 = n.x rot_mat.A23 = n.y rot_mat.A33 = n.z rot_mat.A14 = p.x rot_mat.A24 = p.y rot_mat.A34 = p.z if hasattr(self.Object.profile, "Sources"): translation = self.Object.profile.Sources[0].Placement.Base #translation += self.Object.profile.Placement.Base else: translation = self.Object.profile.Placement.Base print(self.Object.profile.Placement) print(profile.Placement) print(profile.Placement) rot_mat_2 = profile.Placement.toMatrix().inverse() profile.Placement.Base -= translation rot_mat_1 = App.Matrix() rot_mat_1.rotateZ(np.deg2rad(self.Object.Rotation.Value)) placement = rot_mat.multiply(rot_mat_1.multiply(rot_mat_2)) profile.Placement = App.Placement(placement).multiply( profile.Placement) return profile
def testMatrixPlacementMatrix(self): # Example taken from https://forum.freecadweb.org/viewtopic.php?f=3&t=61000 mat = FreeCAD.Matrix(-0.470847778020266, 0.8150598976807029, 0.3376088628746235, -11.25290913640202, -0.8822144756796808, -0.4350066260577338, -0.180185641360483, -2876.45492562325, 1.955470978815492e-9, -0.3826834326750831, 0.923879538425552, 941.3822018176414) plm = FreeCAD.Placement(mat) mat = plm.toMatrix() self.assertEqual(mat.hasScale(), FreeCAD.ScaleType.NoScaling)
def get_preset_door_shape(self, obj): import Part if (not 'OpeningWidth' in obj.PropertiesList or not 'OpeningHeight' in obj.PropertiesList): return None f = Part.makeBox(obj.OpeningWidth, 60, obj.OpeningHeight) m = App.Matrix() m.move(-obj.OpeningWidth / 2, 0, 0) f = f.transformGeometry(m) return f
def createGeometry(self, fp): import FreeCAD, Part, math, sys #tangle = -twist #openscad uses degrees clockwise if fp.Base and fp.Angle and fp.Height and \ fp.Base.Shape.isValid(): #wire=fp.Base.Shape.Wires[0].transformGeometry(fp.Base.Placement.toMatrix()) solids = [] for faceb in fp.Base.Shape.Faces: #fp.Base.Shape.Faces[0].check() #faceb=fp.Base.Shape.Faces[0] #faceb=fp.Base.Shape.removeSplitter().Faces[0] faceu = faceb.copy() facetransform = FreeCAD.Matrix() facetransform.rotateZ(math.radians(fp.Angle.Value)) facetransform.move(FreeCAD.Vector(0, 0, fp.Height.Value)) faceu.transformShape(facetransform) step = 2 + abs(int( fp.Angle.Value // 90)) #resolution in z direction # print abs(int(fp.Angle.Value // 90)) #resolution in z direction # print step zinc = fp.Height.Value / (step - 1.0) angleinc = math.radians(fp.Angle.Value) / (step - 1.0) spine = Part.makePolygon([(0,0,i*zinc) \ for i in range(step)]) auxspine = Part.makePolygon([(math.cos(i*angleinc),\ math.sin(i*angleinc),i*fp.Height.Value/(step-1)) \ for i in range(step)]) faces = [faceb, faceu] for wire in faceb.Wires: pipeshell = Part.BRepOffsetAPI.MakePipeShell(spine) pipeshell.setSpineSupport(spine) pipeshell.add(wire) # Was before function change # pipeshell.setAuxiliarySpine(auxspine,True,False) if sys.version_info.major < 3: pipeshell.setAuxiliarySpine(auxspine, True, long(0)) else: pipeshell.setAuxiliarySpine(auxspine, True, 0) print(pipeshell.getStatus()) assert (pipeshell.isReady()) #fp.Shape=pipeshell.makeSolid() pipeshell.build() faces.extend(pipeshell.shape().Faces) try: fullshell = Part.Shell(faces) solid = Part.Solid(fullshell) if solid.Volume < 0: solid.reverse() assert (solid.Volume >= 0) solids.append(solid) except Part.OCCError: solids.append(Part.Compound(faces)) fp.Shape = Part.Compound(solids)
def get_placement(self, space): """Retrieve object placement""" space_geom = ifcopenshell.geom.create_shape(BREP_SETTINGS, space) # IfcOpenShell matrix values FreeCAD matrix values are transposed ios_matrix = space_geom.transformation.matrix.data m_l = list() for i in range(3): line = list(ios_matrix[i::3]) line[-1] *= self.fc_scale m_l.extend(line) return FreeCAD.Matrix(*m_l)
def accept(self): Th = self.form.Thickness.value() Ref = self.form.Reflectivity.value() SX = self.form.SX.value() SY = self.form.SY.value() X = self.form.Xpos.value() Y = self.form.Ypos.value() Z = self.form.Zpos.value() Xrot = self.form.Xrot.value() Yrot = self.form.Yrot.value() Zrot = self.form.Zrot.value() matcat = self.form.Catalog.currentText() if matcat == "Value": matref = str(self.form.Value.value()) else: matref = self.form.Reference.currentText() Ang = self.form.Angle.value() GP = self.form.Gp.value() M = [] if self.form.O3n.isChecked(): M.append(-3) if self.form.O2n.isChecked(): M.append(-2) if self.form.O1n.isChecked(): M.append(-1) if self.form.O0.isChecked(): M.append(0) if self.form.O1.isChecked(): M.append(1) if self.form.O2.isChecked(): M.append(2) if self.form.O3.isChecked(): M.append(3) obj = InsertDiffG(Ref, Th, SX, SY, Ang, GP, M, ID="G1", matcat=matcat, matref=matref) m = FreeCAD.Matrix() m.rotateX(radians(Xrot)) m.rotateY(radians(Yrot)) m.rotateZ(radians(Zrot)) m.move((X, Y, Z)) p1 = FreeCAD.Placement(m) obj.Placement = p1 FreeCADGui.Control.closeDialog()
def getShape(obj,objid): "gets a shape from an IfcOpenShell object" #print "retrieving shape from obj ",objid import Part sh=Part.Shape() brep_data = None if IOC_ADVANCED: try: brep_data = IfcImport.create_shape(obj) except: print "Unable to retrieve shape data" else: brep_data = obj.mesh.brep_data if brep_data: try: if MAKETEMPFILES: import tempfile tf = tempfile.mkstemp(suffix=".brp")[1] of = pyopen(tf,"wb") of.write(brep_data) of.close() sh = Part.read(tf) os.remove(tf) else: sh.importBrepFromString(brep_data) except: print "Error: malformed shape" return None if not sh.Solids: # try to extract a solid shape if sh.Faces: try: if DEBUG: print "Malformed solid. Attempting to fix..." shell = Part.makeShell(sh.Faces) if shell: solid = Part.makeSolid(shell) if solid: sh = solid except: if DEBUG: print "failed to retrieve solid from object ",objid else: if DEBUG: print "object ", objid, " doesn't contain any geometry" if not IOC_ADVANCED: m = obj.matrix mat = FreeCAD.Matrix(m[0], m[3], m[6], m[9], m[1], m[4], m[7], m[10], m[2], m[5], m[8], m[11], 0, 0, 0, 1) sh.Placement = FreeCAD.Placement(mat) # if DEBUG: print "getting Shape from ",obj #print "getting shape: ",sh,sh.Solids,sh.Volume,sh.isValid(),sh.isNull() #for v in sh.Vertexes: print v.Point return sh
def Translation(x, y=None, z=None): """Homogeneous matrix for translation""" #-- Function overloading. x is mandatory if y == None and z == None: #-- the first argument is an App.Vector v = x else: #-- The three components are given v = FreeCAD.Vector(x, y, z) return FreeCAD.Matrix(1, 0, 0, v.x, 0, 1, 0, v.y, 0, 0, 1, v.z, 0, 0, 0, 1)
def polygonstr(r, pcount): import math v = FreeCAD.Vector(r, 0, 0) m = FreeCAD.Matrix() m.rotateZ(2 * math.pi / pcount) points = [] for i in range(pcount): points.append(v) v = m.multiply(v) points.append(v) return ' '.join('%s %s %s'%(f2s(v.x),f2s(v.y),f2s(v.z)) \ for v in points)
def createGeometry(self, fp): import FreeCAD, Part, math, sys if fp.Base and fp.Height and fp.Base.Shape.isValid(): solids = [] for lower_face in fp.Base.Shape.Faces: upper_face = lower_face.copy() face_transform = FreeCAD.Matrix() face_transform.rotateZ(math.radians(fp.Angle.Value)) face_transform.scale(fp.Scale[0], fp.Scale[1], 1.0) face_transform.move(FreeCAD.Vector(0, 0, fp.Height.Value)) upper_face.transformShape( face_transform, False, True) # True to check for non-uniform scaling spine = Part.makePolygon([(0, 0, 0), (0, 0, fp.Height.Value)]) if fp.Angle.Value == 0.0: auxiliary_spine = Part.makePolygon([ (1, 1, 0), (fp.Scale[0], fp.Scale[1], fp.Height.Value) ]) else: num_revolutions = abs(fp.Angle.Value) / 360.0 pitch = fp.Height.Value / num_revolutions height = fp.Height.Value radius = 1.0 if fp.Angle.Value < 0.0: left_handed = True else: left_handed = False auxiliary_spine = Part.makeHelix(pitch, height, radius, 0.0, left_handed) faces = [lower_face, upper_face] for wire1, wire2 in zip(lower_face.Wires, upper_face.Wires): pipe_shell = Part.BRepOffsetAPI.MakePipeShell(spine) pipe_shell.setSpineSupport(spine) pipe_shell.add(wire1) pipe_shell.add(wire2) pipe_shell.setAuxiliarySpine(auxiliary_spine, True, 0) print(pipe_shell.getStatus()) assert (pipe_shell.isReady()) pipe_shell.build() faces.extend(pipe_shell.shape().Faces) try: fullshell = Part.Shell(faces) solid = Part.Solid(fullshell) if solid.Volume < 0: solid.reverse() assert (solid.Volume >= 0) solids.append(solid) except Part.OCCError: solids.append(Part.Compound(faces)) fp.Shape = Part.Compound(solids)
def onChanged(self, fp, prop): "Do something when a property has changed" if (prop != 'Length'): return FreeCAD.Console.PrintMessage("Change property: " + str(prop) + "\n") if (fp.Length <= 0 or fp.Length == self.Wire.BoundBox.XLength): return scalefactor = fp.Length / self.Wire.BoundBox.XLength mat = FreeCAD.Matrix() mat.scale(scalefactor, scalefactor, 0) self.Wire = fp.Shape.Wires[0].transformGeometry(mat) fp.Shape = self.Wire
def execute(self, fp): fp.gear.z = fp.teeth fp.gear.module = fp.module.Value fp.gear.pressure_angle = (90 - fp.pressure_angle.Value) * np.pi / 180. fp.gear.pitch_angle = fp.pitch_angle.Value * np.pi / 180 fp.gear.backlash = fp.backlash.Value scale = fp.module.Value * fp.gear.z / 2 / \ np.tan(fp.pitch_angle.Value * np.pi / 180) fp.gear.clearance = fp.clearance / scale fp.gear._update() pts = list(fp.gear.points(num=fp.numpoints)) rot = rotation3D(2 * np.pi / fp.teeth) # if fp.beta.Value != 0: # pts = [np.array([self.spherical_rot(j, fp.beta.Value * np.pi / 180.) for j in i]) for i in pts] rotated_pts = pts for i in range(fp.gear.z - 1): rotated_pts = list(map(rot, rotated_pts)) pts.append(np.array([pts[-1][-1], rotated_pts[0][0]])) pts += rotated_pts pts.append(np.array([pts[-1][-1], pts[0][0]])) wires = [] if not "version" in fp.PropertiesList: scale_0 = scale - fp.height.Value / 2 scale_1 = scale + fp.height.Value / 2 else: # starting with version 0.0.2 scale_0 = scale - fp.height.Value scale_1 = scale if fp.beta.Value == 0: wires.append(make_bspline_wire([scale_0 * p for p in pts])) wires.append(make_bspline_wire([scale_1 * p for p in pts])) else: for scale_i in np.linspace(scale_0, scale_1, 20): # beta_i = (scale_i - scale_0) * fp.beta.Value * np.pi / 180 # rot = rotation3D(beta_i) # points = [rot(pt) * scale_i for pt in pts] angle = fp.beta.Value * np.pi / 180. * \ np.sin(np.pi / 4) / \ np.sin(fp.pitch_angle.Value * np.pi / 180.) points = [ np.array( [self.spherical_rot(p, angle) for p in scale_i * pt]) for pt in pts ] wires.append(make_bspline_wire(points)) shape = makeLoft(wires, True) if fp.reset_origin: mat = App.Matrix() mat.A33 = -1 mat.move(fcvec([0, 0, scale_1])) shape = shape.transformGeometry(mat) fp.Shape = shape
def mirror_job(src_job, tgt_job, origin, norm): if origin == None or norm == None: raise Exception( "Need to have a well-defined flip line in order to create mirrored stock" ) tgt_job.Label = "Reverse{0}".format(src_job.Label) R = App.Matrix() R.unity() T = App.Matrix() T.unity() # Flip along norm T.A14 = -origin.x T.A24 = -origin.y T.A34 = -origin.z R.A11 = 2 * norm.x * norm.x - 1 R.A12 = 2 * norm.x * norm.y R.A13 = 2 * norm.x * norm.z R.A21 = 2 * norm.x * norm.y R.A22 = 2 * norm.y * norm.y - 1 R.A23 = 2 * norm.y * norm.z R.A31 = 2 * norm.z * norm.x R.A32 = 2 * norm.z * norm.y R.A33 = 2 * norm.z * norm.z - 1 Ti = T.inverse() for (i, obj) in enumerate(tgt_job.Model.OutList): obj.Placement.Matrix = Ti * R * T * src_job.Model.OutList[ i].Placement.Matrix tgt_job.Stock.Placement.Matrix = Ti * R * T * src_job.Stock.Placement.Matrix tgt_job.recompute()
def getPlacement(self, rotated=False): "returns the placement of the working plane" if rotated: m = FreeCAD.Matrix(self.u.x, self.axis.x, -self.v.x, self.position.x, self.u.y, self.axis.y, -self.v.y, self.position.y, self.u.z, self.axis.z, -self.v.z, self.position.z, 0.0, 0.0, 0.0, 1.0) else: m = FreeCAD.Matrix(self.u.x, self.v.x, self.axis.x, self.position.x, self.u.y, self.v.y, self.axis.y, self.position.y, self.u.z, self.v.z, self.axis.z, self.position.z, 0.0, 0.0, 0.0, 1.0) p = FreeCAD.Placement(m) # Arch active container if based on App Part #if FreeCAD.GuiUp: # import FreeCADGui # a = FreeCADGui.ActiveDocument.ActiveView.getActiveObject("Arch") # if a: # p = a.Placement.inverse().multiply(p) return p
def __processObjects(self, objs, matrix=None, processInvisible=False, processPartChildren=False): if matrix is None: matrix = FreeCAD.Matrix() for obj in objs: process = True if not processPartChildren: for parent in obj.InList: if parent.TypeId == "App::Part": process = False if not processInvisible: if not obj.ViewObject.isVisible(): process = False # if processInvisible or obj.ViewObject.isVisible(): if process: if obj.TypeId == "Part::Compound": m = matrix.multiply(obj.Placement.toMatrix()) self.__processObjects(obj.OutList, m, True) elif obj.TypeId=="Part::FeaturePython" \ and hasattr(obj,"sourceFile"): m = matrix.multiply(obj.Placement.toMatrix()) other = self.__getDocumentByFileName(obj.sourceFile) self.__processObjects(other.Objects, m) elif obj.TypeId.split("::")[0] in ["Part", "PartDesign"]: o = self.__target.addObject("Part::FeaturePython", obj.Label) DupShape(o, obj.Shape) ViewProviderDupShape(o.ViewObject) o.ViewObject.ShapeColor = obj.ViewObject.ShapeColor o.Placement = FreeCAD.Placement( matrix.multiply(obj.Placement.toMatrix())) elif obj.TypeId.split("::")[0] == "Mesh": o = self.__target.addObject("Mesh::Feature") o.Mesh = obj.Mesh o.ViewObject.ShapeColor = obj.ViewObject.ShapeColor elif obj.TypeId == "App::Part": m = matrix.multiply(obj.Placement.toMatrix()) self.__processObjects(obj.Group, m, processPartChildren=True)
def ios_to_fc_matrix(ios_matrix): """Convert a FreeCAD 4x4 matrix from an IfcOpenShell 4x3 matrix. IfcOpenShell matrix values is a tuple of 4 consecutive vector's xyz - format : (v1.x, v1.y, v1.z, v2.x, v2.y … , v4.z). FreeCAD matrix constructor takes up to 16 float. 4 vectors grouped by x, y, z values optionnally followed by 0, 0, 0, 1 (0 = direction, 1 = location). - format : (v1.x, v2.x, v3.x, v4.x, v1.y, … , v4.z, 0, 0, 0, 1) In consequence values needs to be transposed""" m_l = list() for i in range(3): line = list(ios_matrix[i::3]) line[-1] *= SCALE m_l.extend(line) return FreeCAD.Matrix(*m_l)
def testPower(self): mat = FreeCAD.Matrix(2,0,0,0, 0,1,0,0, 0,0,2,0, 0,0,0,-1) with self.assertRaises(NotImplementedError): mat ** "string" mat2 = mat ** 0 self.assertTrue(mat2.isUnity()) self.assertEqual(mat ** -1, mat.inverse()) self.assertEqual(mat ** 1, mat) self.assertEqual(mat ** 2, mat * mat) self.assertEqual(mat ** 3, mat * mat * mat) mat.nullify() with self.assertRaises(RuntimeError): mat ** -1