def create_y_grid(sketch, ycoord, text, i, XMIN, XMAX, x1, x2, x3, x4, xc): text = str(text) if FreeCAD.ParamGet( "User parameter:BaseApp/Preferences/Mod/Civil").GetBool( "extend_grid", True): g = Part.makeLine(FreeCAD.Vector(XMIN, ycoord, 0), FreeCAD.Vector(XMAX, ycoord, 0)) # # g.DrawStyle = "Dashdot" Part.show(g) # x_grid_group.addObject(g0) g1 = sketch.addGeometry( Part.LineSegment(FreeCAD.Vector(x1, ycoord, 0), FreeCAD.Vector(x2, ycoord, 0))) g2 = sketch.addGeometry( Part.LineSegment(FreeCAD.Vector(x2, ycoord, 0), FreeCAD.Vector(x3, ycoord, 0))) g3 = sketch.addGeometry( Part.LineSegment(FreeCAD.Vector(x3, ycoord, 0), FreeCAD.Vector(x4, ycoord, 0))) g4 = sketch.addGeometry( Part.Circle(FreeCAD.Vector(xc, ycoord, 0), FreeCAD.Vector(0, 0, 1), r), False) t = Draft.makeText(text, FreeCAD.Vector(xc, ycoord, 0)) t.ViewObject.FontSize = font_size t.ViewObject.Justification = 'Center' # x_grid_group.addObject(t) sketch.addConstraint(Sketcher.Constraint('DistanceY', g1, 1, ycoord)) sketch.addConstraint(Sketcher.Constraint('DistanceX', g1, 1, x1)) sketch.addConstraint(Sketcher.Constraint('Coincident', g1, 2, g2, 1)) sketch.addConstraint(Sketcher.Constraint('Coincident', g2, 2, g3, 1)) sketch.addConstraint(Sketcher.Constraint('Horizontal', g1)) sketch.addConstraint(Sketcher.Constraint('Horizontal', g3)) sketch.addConstraint(Sketcher.Constraint('Radius', g4, r)) sketch.addConstraint(Sketcher.Constraint('PointOnObject', g3, 2, g4)) sketch.addConstraint(Sketcher.Constraint('Perpendicular', g4, g3)) const_num = sketch.addConstraint( Sketcher.Constraint('DistanceY', -1, 1, g4, 3, ycoord)) sketch.renameConstraint(const_num, f'y_{text}') sketch.toggleDriving(const_num) const_num = sketch.addConstraint( Sketcher.Constraint('DistanceX', -1, 1, g4, 3, xc)) sketch.renameConstraint(const_num, f'x_{text}') sketch.toggleDriving(const_num) t.setExpression('Placement.Base.x', f'{sketch.Name}.Constraints.x_{text}') t.setExpression('Placement.Base.y', f'{sketch.Name}.Constraints.y_{text}') if not i == no_of_edge_in_on_axis - 1: sketch.addConstraint( Sketcher.Constraint('DistanceX', g4, 3, g4 - no_of_edge_in_on_axis, 3, 0)) sketch.addConstraint( Sketcher.Constraint('DistanceX', g1, 2, g1 - no_of_edge_in_on_axis, 2, 0))
def generate_key_sketch(parameters,add_clearence,sketch,Offset=0): key_radius,key_flat = generate_slot_size(parameters,add_clearence) arc = sketch.addGeometry(Part.ArcOfCircle(Part.Circle(Base.Vector(Offset,0,0),Base.Vector(0,0,1),key_radius),2,1),False) sketch.addConstraint(Sketcher.Constraint('Coincident',arc,3,-1,1)) c = sketch.addConstraint(Sketcher.Constraint('Radius',arc,key_radius)) l = sketch.addGeometry(Part.LineSegment(Base.Vector(-2,key_flat,0),Base.Vector(2,key_flat/3,0)),False) #print(arc,l) sketch.addConstraint(Sketcher.Constraint('Coincident',l,1,arc,1)) sketch.addConstraint(Sketcher.Constraint('Coincident',l,2,arc,2)) sketch.addConstraint(Sketcher.Constraint('Horizontal',l)) vc = sketch.addConstraint(Sketcher.Constraint('DistanceY',0,3,l,1,key_flat))
def makeRegularPolygon( sketchName, sides, centerPoint=App.Vector(0,0,0), firstCornerPoint=App.Vector(-20.00,34.64,0), construction=False): if not sketchName: App.Console.PrintError("No sketch specified in 'makeRegularPolygon'") return if sides < 3: App.Console.PrintError("Number of sides must be at least 3 in 'makeRegularPolygon'") return sketch = App.ActiveDocument.getObject(sketchName) diffVec = firstCornerPoint - centerPoint diffVec.z = 0 angular_diff = 2*math.pi/sides pointList = [] for i in range(0,sides): cos_v = math.cos( angular_diff * i ) sin_v = math.sin( angular_diff * i ) pointList.append( centerPoint+ App.Vector( cos_v * diffVec.x - sin_v * diffVec.y, cos_v * diffVec.y + sin_v * diffVec.x, 0 )) geoList = [] for i in range(0,sides-1): geoList.append(Part.LineSegment(pointList[i],pointList[i+1])) geoList.append(Part.LineSegment(pointList[sides-1],pointList[0])) geoList.append(Part.Circle(centerPoint,App.Vector(0,0,1),diffVec.Length)) geoIndices = sketch.addGeometry(geoList,construction) sketch.setConstruction(geoIndices[-1],True) conList = [] for i in range(0,sides-1): conList.append(Sketcher.Constraint( 'Coincident', geoIndices[i],2, geoIndices[i+1],1)) conList.append(Sketcher.Constraint( 'Coincident', geoIndices[sides-1],2, geoIndices[0],1)) for i in range(0,sides-1): conList.append(Sketcher.Constraint('Equal',geoIndices[0],geoIndices[i+1])) for i in range(0,sides): conList.append(Sketcher.Constraint('PointOnObject',geoIndices[i],2,geoIndices[-1])) sketch.addConstraint(conList) return
def _createCoildEnd(self, fp, a): pathEdges = [] if (fp.EndTransit): m = fp.Profile.Shape.BoundBox.Center # Center of the profile circleEnd = Part.Circle(fp.Center, fp.Axis, radiusEnd) radius = m.distanceToLine(fp.Center, fp.Center + fp.Axis) radius -= fp.Height * sin(radians(fp.Angle)) if (fp.EndSegue > 0): # Tangent connection between helical and flat part. b = a + radians(fp.EndSegue) edge = Part.makeBSpline(points) a = b pathEdges.append(edge) if (fp.EndFlat > 0): b = a + radians(fp.EndFlat) edge = Part.ArcOfCircle( Part.Circle(fp.Center, fp.Axis, radius), a, b) a = b profileEdges.append(edge) return pathEdges
def PointOnObject(SketchFeature): # Square with the upper right corner touching the edge of a circle top_edge = int(SketchFeature.GeometryCount) right_edge = top_edge + 1 CreateRectangleSketch(SketchFeature, [0, 0], [2, 2]) circle = int(SketchFeature.GeometryCount) SketchFeature.addGeometry( Part.Circle(App.Vector(12, 3, 0), App.Vector(0, 0, 1), 1), False) SketchFeature.addConstraint(Sketcher.Constraint('Radius', circle, 1)) SketchFeature.addConstraint( Sketcher.Constraint('PointOnObject', top_edge, 2, circle)) SketchFeature.fillet(top_edge, 2, 0.25, True, True)
def execute(self, obj): ''' this method is mandatory. It is called on Document.recompute() ''' # create a shape corresponding to the type of hole shape = None if obj.Type == "Point": # set the shape as a Vertex at relative position obj.X, obj.Y, obj.Z # The shape will then be adjusted according to the object Placement ver = FreeCAD.Version() # need to work-around a pesky bug in FreeCAD 0.17(.13541 at the time of writing) # that impacts the save/reload when there is a shape with a single Vertex. # In this case, the .brep file inside the .FCStd file does NOT contain any # placement information. So the object Placement is restored from the # Document.xml but then it is overwritten by the Shape placement that # is then zero. This bug is not affecting FreeCAD version 0.18(.15593 at the time of writing). # As the shape is anyway recreated at recompute() time, the following w/a is valid # also between 0.17 and 0.18. if (int(ver[0]) > 0) or (int(ver[0]) == 0 and int(ver[1]) > 17): shape = Part.Vertex(self.getRelCoord()) else: shape1 = Part.Vertex(self.getRelCoord()) shape = Part.makeCompound([shape1]) elif obj.Type == "Rect": if obj.Length <= 0 or obj.Width <= 0: FreeCAD.Console.PrintWarning( translate( "EM", "Cannot create a FHPlaneHole rectangular hole with zero length or width" )) else: v0 = self.getRelCoord() v1 = v0 + Vector(obj.Length, 0, 0) v2 = v0 + Vector(obj.Length, obj.Width, 0) v3 = v0 + Vector(0, obj.Width, 0) # and create the rectangle poly = Part.makePolygon([v0, v1, v2, v3, v0]) shape = Part.Face(poly) elif obj.Type == "Circle": if obj.Radius <= 0: FreeCAD.Console.PrintWarning( translate( "EM", "Cannot create a FHPlaneHole circular hole with zero radius" )) else: # create a circle in the x,y plane (axis is along z) circle = Part.Circle(self.getRelCoord(), Vector(0, 0, 1), obj.Radius) edge = circle.toShape() wire = Part.Wire(edge) shape = Part.Face(wire) if shape: obj.Shape = shape
def getProfile(self,obj): import Part if obj.Profile: if not obj.Profile.getLinkedObject().isDerivedFrom("Part::Part2DObject"): FreeCAD.Console.PrintError(translate("Arch","The profile is not a 2D Part")+"\n") return if not obj.Profile.Shape.Wires[0].isClosed(): FreeCAD.Console.PrintError(translate("Arch","The profile is not closed")+"\n") return p = obj.Profile.Shape.Wires[0] else: if obj.Diameter.Value == 0: return p = Part.Wire([Part.Circle(FreeCAD.Vector(0,0,0),FreeCAD.Vector(0,0,1),obj.Diameter.Value/2).toShape()]) if obj.WallThickness.Value and (obj.WallThickness.Value < obj.Diameter.Value/2): p2 = Part.Wire([Part.Circle(FreeCAD.Vector(0,0,0),FreeCAD.Vector(0,0,1),(obj.Diameter.Value/2-obj.WallThickness.Value)).toShape()]) p = Part.Face(p) p2 = Part.Face(p2) p = p.cut(p2) return p
def otv1(offsetY, cLENGTH): offsetX = 5. P0 = Base.Vector(0. + offsetX, 0. + offsetY, 0) P1 = Base.Vector(0. + offsetX, cHEIGHT + offsetY, 0) P2 = Base.Vector(cLENGTH + offsetX, cHEIGHT + offsetY, 0) P3 = Base.Vector(cLENGTH + offsetX, 0. + offsetY, 0) # P4 = Base.Vector(0. + offsetX - cRADIUSdx, cHdiv2 + offsetY, 0) P5 = Base.Vector(cLENGTH - cRADIUSdx + offsetX, cHdiv2 + offsetY, 0) # ls0 = Part.LineSegment(P1, P2) gm0 = AS.addGeometry(ls0, False) AS.addConstraint(Sketcher.Constraint('Horizontal', gm0)) cnx0 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm0, 1, offsetX)) AS.setVirtualSpace(cnx0, True) cny0 = AS.addConstraint( Sketcher.Constraint('DistanceY', gm0, 1, cHEIGHT + offsetY)) AS.setVirtualSpace(cny0, True) cnl0 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm0, 1, gm0, 2, cLENGTH)) # dx0 AS.setVirtualSpace(cnl0, True) # ls1 = Part.LineSegment(P0, P3) gm1 = AS.addGeometry(ls1, False) AS.addConstraint(Sketcher.Constraint('Horizontal', gm1)) cnx1 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm1, 1, offsetX)) AS.setVirtualSpace(cnx1, True) cny1 = AS.addConstraint( Sketcher.Constraint('DistanceY', gm1, 1, offsetY)) AS.setVirtualSpace(cny1, True) cnx2 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm1, 1, gm1, 2, cLENGTH)) # dx1 AS.setVirtualSpace(cnx2, True) # ls2 = Part.LineSegment(P1, P0) gm2 = AS.addGeometry(ls2, False) # cr2 = Part.ArcOfCircle(Part.Circle(P5, App.Vector(0, 0, 1), cRADIUS), -0.627014, 0.643501) gm3 = AS.addGeometry(cr2, False) # AS.addConstraint(Sketcher.Constraint('Coincident', gm0, 1, gm2, 2)) # c1 AS.addConstraint(Sketcher.Constraint('Coincident', gm1, 1, gm2, 1)) # c2 AS.addConstraint(Sketcher.Constraint('Coincident', gm0, 2, gm3, 2)) AS.addConstraint(Sketcher.Constraint('Coincident', gm1, 2, gm3, 1)) # App.ActiveDocument.recompute()
def otv2(offsetX, offsetY, cLENGTH): P0 = Base.Vector(0. + offsetX, 0. + offsetY, 0) P1 = Base.Vector(0. + offsetX, cHEIGHT + offsetY, 0) P2 = Base.Vector(cLENGTH + offsetX, cHEIGHT + offsetY, 0) P3 = Base.Vector(cLENGTH + offsetX, 0. + offsetY, 0) # P4 = Base.Vector(0. + offsetX - cRADIUSdx, cHdiv2 + offsetY, 0) P5 = Base.Vector(cLENGTH - cRADIUSdx + offsetX, cHdiv2 + offsetY, 0) # ls0 = Part.LineSegment(P1, P2) gm0 = AS.addGeometry(ls0, False) AS.addConstraint(Sketcher.Constraint('Horizontal', gm0)) cnz0 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm0, 1, offsetX)) AS.setVirtualSpace(cnz0, True) cnz1 = AS.addConstraint( Sketcher.Constraint('DistanceY', gm0, 1, cHEIGHT + offsetY)) AS.setVirtualSpace(cnz1, True) cnz2 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm0, 1, gm0, 2, cLENGTH)) # dx0 AS.setVirtualSpace(cnz2, True) # ls1 = Part.LineSegment(P0, P3) gm1 = AS.addGeometry(ls1, False) cnz3 = AS.addConstraint(Sketcher.Constraint('Horizontal', gm1)) AS.setVirtualSpace(cnz3, True) cnz4 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm1, 1, offsetX)) AS.setVirtualSpace(cnz4, True) cnz5 = AS.addConstraint( Sketcher.Constraint('DistanceY', gm1, 1, offsetY)) AS.setVirtualSpace(cnz5, True) cnz6 = AS.addConstraint( Sketcher.Constraint('DistanceX', gm1, 1, gm1, 2, cLENGTH)) # dx1 AS.setVirtualSpace(cnz6, True) # cr1 = Part.ArcOfCircle(Part.Circle(P4, App.Vector(0, 0, 1), cRADIUS), -0.627014, 0.643501) gm2 = AS.addGeometry(cr1, False) # ls3 = Part.LineSegment(P2, P3) gm3 = AS.addGeometry(ls3, False) # AS.addConstraint(Sketcher.Constraint('Coincident', gm0, 1, gm2, 2)) # c1 AS.addConstraint(Sketcher.Constraint('Coincident', gm1, 1, gm2, 1)) # c2 # AS.addConstraint(Sketcher.Constraint('Coincident', gm0, 2, gm3, 2)) AS.addConstraint(Sketcher.Constraint('Coincident', gm1, 2, gm3, 1)) # App.ActiveDocument.recompute()
def makeHexagonSketch(sketchName): #would use the polygon tool, but is buggy and sometimes creates squares instead of hexagons, so the manual way sketch = App.ActiveDocument.getObject(sketchName) #we just place the vertices any old where and then constrain them into place later sketch.addGeometry( Part.LineSegment(App.Vector(-2.000000, 1.448548, 0), App.Vector(0.500515, 2.469759, 0)), False) sketch.addGeometry( Part.LineSegment(App.Vector(0.500515, 2.469759, 0), App.Vector(2.000000, 1.696951, 0)), False) sketch.addConstraint(Sketcher.Constraint('Coincident', 0, 2, 1, 1)) sketch.addGeometry( Part.LineSegment(App.Vector(2.000000, 1.696951, 0), App.Vector(2.736140, -0.676675, 0)), False) sketch.addConstraint(Sketcher.Constraint('Coincident', 1, 2, 2, 1)) sketch.addGeometry( Part.LineSegment(App.Vector(2.736140, -0.676675, 0), App.Vector(1.000000, -2.415493, 0)), False) sketch.addConstraint(Sketcher.Constraint('Coincident', 2, 2, 3, 1)) sketch.addGeometry( Part.LineSegment(App.Vector(1.000000, -2.415493, 0), App.Vector(-3.000000, -1.000000, 0)), False) sketch.addConstraint(Sketcher.Constraint('Coincident', 3, 2, 4, 1)) sketch.addGeometry( Part.LineSegment(App.Vector(-3.000000, -1.000000, 0), App.Vector(-2.000000, 1.365748, 0)), False) sketch.addConstraint(Sketcher.Constraint('Coincident', 4, 2, 5, 1)) sketch.addConstraint(Sketcher.Constraint('Coincident', 5, 2, 0, 1)) sketch.addGeometry( Part.Circle(App.Vector(0.000000, 0.000000, 0), App.Vector(0, 0, 1), 3.535498), False) #construction circle sketch.addConstraint(Sketcher.Constraint('Coincident', 6, 3, -1, 1)) sketch.addConstraint(Sketcher.Constraint('Radius', 6, 3.535498)) sketch.setDatum(7, App.Units.Quantity('2.000000 mm')) sketch.addConstraint( Sketcher.Constraint('PointOnObject', 4, 2, 6)) #constrain all vertices to the circumference sketch.addConstraint(Sketcher.Constraint('PointOnObject', 0, 1, 6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject', 0, 2, 6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject', 1, 2, 6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject', 2, 2, 6)) sketch.addConstraint(Sketcher.Constraint('PointOnObject', 3, 2, 6)) sketch.toggleConstruction(6) sketch.addConstraint(Sketcher.Constraint('Equal', 5, 0)) #set all lines equal sketch.addConstraint(Sketcher.Constraint('Equal', 0, 1)) sketch.addConstraint(Sketcher.Constraint('Equal', 1, 2)) sketch.addConstraint(Sketcher.Constraint('Equal', 2, 3)) sketch.addConstraint(Sketcher.Constraint('Equal', 3, 4)) sketch.addConstraint(Sketcher.Constraint('Horizontal', 0)) #make one of them horizontal sketch.setExpression('Constraints[7]', u'EditMe.radius')
def circleFrom2LinesRadius(edge1, edge2, radius): """circleFrom2LinesRadius(edge,edge,radius)""" int = findIntersection(edge1, edge2, True, True) if not int: return None int = int[0] bis12 = angleBisection(edge1, edge2) bis21 = Part.LineSegment(bis12.Vertexes[0].Point, DraftVecUtils.rotate(vec(bis12), math.pi / 2.0)) ang12 = abs(DraftVecUtils.angle(vec(edge1), vec(edge2))) ang21 = math.pi - ang12 dist12 = radius / math.sin(ang12 * 0.5) dist21 = radius / math.sin(ang21 * 0.5) circles = [] cen = Vector.add(int, vec(bis12).multiply(dist12)) circles.append(Part.Circle(cen, NORM, radius)) cen = Vector.add(int, vec(bis12).multiply(-dist12)) circles.append(Part.Circle(cen, NORM, radius)) cen = Vector.add(int, vec(bis21).multiply(dist21)) circles.append(Part.Circle(cen, NORM, radius)) cen = Vector.add(int, vec(bis21).multiply(-dist21)) circles.append(Part.Circle(cen, NORM, radius)) return circles
def draw(self): try: Gui.getDocument('xRodTop') Gui.getDocument('xRodTop').resetEdit() App.getDocument('xRodTop').recompute() App.closeDocument("xRodTop") App.setActiveDocument("") App.ActiveDocument = None Gui.ActiveDocument = None except: pass #make document App.newDocument("xRodTop") App.setActiveDocument("xRodTop") App.ActiveDocument = App.getDocument("xRodTop") Gui.ActiveDocument = Gui.getDocument("xRodTop") #make sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch') App.activeDocument().Sketch.Placement = App.Placement( App.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.500000, 0.500000, 0.500000, 0.500000)) # Gui.activeDocument().activeView().setCamera('#Inventor V2.1 ascii \n OrthographicCamera {\n viewportMapping ADJUST_CAMERA\n position 87 0 0 \n orientation 0.57735026 0.57735026 0.57735026 2.0943952 \n nearDistance -112.887\n farDistance 287.28699\n aspectRatio 1\n focalDistance 87\n height 143.52005\n\n}') # Gui.activeDocument().setEdit('Sketch') App.ActiveDocument.Sketch.addGeometry( Part.Circle(App.Vector(50, 50, 0), App.Vector(0, 0, 1), gv.xRodDiaTop / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 0, 3, -1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Radius', 0, gv.xRodDiaTop / 2)) App.ActiveDocument.recompute() # Gui.getDocument('xRodTop').resetEdit() App.getDocument('xRodTop').recompute() #Pad sketch App.activeDocument().addObject("PartDesign::Pad", "Pad") App.activeDocument().Pad.Sketch = App.activeDocument().Sketch App.activeDocument().Pad.Length = 10.0 App.ActiveDocument.recompute() Gui.activeDocument().hide("Sketch") App.ActiveDocument.Pad.Length = gv.xRodLength App.ActiveDocument.Pad.Reversed = 0 App.ActiveDocument.Pad.Midplane = 0 App.ActiveDocument.Pad.Length2 = 100.000000 App.ActiveDocument.Pad.Type = 0 App.ActiveDocument.Pad.UpToFace = None App.ActiveDocument.recompute()
def makeSplineFoilSketch(sketch, length, height_top, height_bottom, back_width=0): print(sketch.Label) sketch.Placement = FreeCAD.Placement( FreeCAD.Vector(0.000000, 0.000000, 0.000000), FreeCAD.Rotation(0.5, 0.5, 0.5, 0.5)) sketch.MapMode = "Deactivated" points = [] conList = [] points.append(FreeCAD.Vector(length, back_width, 0)) points.append(FreeCAD.Vector(length * 0.75, height_top * 0.55, 0)) points.append(FreeCAD.Vector(length * 0.57, height_top * 0.75, 0)) points.append(FreeCAD.Vector(length * 0.29, height_top * 1, 0)) points.append(FreeCAD.Vector(length * 0.03, height_top * 0.6, 0)) points.append(FreeCAD.Vector(0, height_top * 0.2, 0)) points.append(FreeCAD.Vector(0, 0, 0)) points.append(FreeCAD.Vector(0, height_bottom * -0.2, 0)) points.append(FreeCAD.Vector(length * 0.03, height_bottom * -0.6, 0)) points.append(FreeCAD.Vector(length * 0.29, height_bottom * -1, 0)) points.append(FreeCAD.Vector(length * 0.57, height_bottom * -0.75, 0)) points.append(FreeCAD.Vector(length * 0.75, height_bottom * -0.55, 0)) points.append(FreeCAD.Vector(length, -back_width, 0)) n = 0 for p in points: circle = sketch.addGeometry( Part.Circle(p, FreeCAD.Vector(0, 0, 1), 10), True) sketch.addConstraint(Sketcher.Constraint('Radius', circle, 1)) sketch.addConstraint(Sketcher.Constraint('DistanceX', circle, 3, p.x)) sketch.addConstraint(Sketcher.Constraint('DistanceY', circle, 3, p.y)) conList.append( Sketcher.Constraint( 'InternalAlignment:Sketcher::BSplineControlPoint', circle, 3, 13, n)) n = n + 1 bspline = sketch.addGeometry( Part.BSplineCurve(points, None, None, False, 3, None, False), False) sketch.addConstraint(conList) sketch.exposeInternalGeometry(13) if back_width > 0: line = sketch.addGeometry(Part.LineSegment(points[0], points[12])) sketch.addConstraint( Sketcher.Constraint('Coincident', bspline, 1, line, 1)) sketch.addConstraint( Sketcher.Constraint('Coincident', bspline, 2, line, 2)) return sketch
def draw(self): #import FreeCAD modules import FreeCAD as App import Part import Sketcher #Specific to printer import globalVars as gv try: App.getDocument('xRodTop').recompute() App.closeDocument("xRodTop") App.setActiveDocument("") App.ActiveDocument = None except: pass #make document App.newDocument("xRodTop") App.setActiveDocument("xRodTop") App.ActiveDocument = App.getDocument("xRodTop") #make sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch') App.activeDocument().Sketch.Placement = App.Placement( App.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.500000, 0.500000, 0.500000, 0.500000)) App.ActiveDocument.Sketch.addGeometry( Part.Circle(App.Vector(50, 50, 0), App.Vector(0, 0, 1), gv.xRodDiaTop / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 0, 3, -1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Radius', 0, gv.xRodDiaTop / 2)) App.ActiveDocument.recompute() App.getDocument('xRodTop').recompute() #Pad sketch App.activeDocument().addObject("PartDesign::Pad", "Pad") App.activeDocument().Pad.Sketch = App.activeDocument().Sketch App.activeDocument().Pad.Length = 10.0 App.ActiveDocument.recompute() App.ActiveDocument.Pad.Length = gv.xRodLength App.ActiveDocument.Pad.Reversed = 0 App.ActiveDocument.Pad.Midplane = 0 App.ActiveDocument.Pad.Length2 = 100.000000 App.ActiveDocument.Pad.Type = 0 App.ActiveDocument.Pad.UpToFace = None App.ActiveDocument.recompute()
def circle_to_freecad(circle): center = tuple(circle.center) normal = tuple(circle.normal) vectorx = tuple(circle.vectorx / np.linalg.norm(circle.vectorx)) radius = circle.get_actual_radius() u_min, u_max = circle.get_u_bounds() fc_circle = Part.Circle(Base.Vector(*center), Base.Vector(*normal), radius) if u_min != 0 or u_max != 2 * math.pi: fc_circle.XAxis = Base.Vector(*vectorx) fc_arc = fc_circle.trim(u_min, u_max) return fc_arc else: return fc_circle
def draw(self): self.defineVariables() # import FreeCAD modules import FreeCAD as App import Part import Sketcher try: App.getDocument('xRodBottom').recompute() App.closeDocument("xRodBottom") App.setActiveDocument("") App.ActiveDocument = None except: pass # make document App.newDocument("xRodBottom") App.setActiveDocument("xRodBottom") App.ActiveDocument = App.getDocument("xRodBottom") # make sketch App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch') App.activeDocument().Sketch.Placement = App.Placement( App.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.500000, 0.500000, 0.500000, 0.500000)) App.ActiveDocument.Sketch.addGeometry( Part.Circle(App.Vector(50, 50, 0), App.Vector(0, 0, 1), self.Diameter / 2)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 0, 3, -1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Radius', 0, self.Diameter / 2)) App.ActiveDocument.recompute() App.getDocument('xRodBottom').recompute() # Pad sketch App.activeDocument().addObject("PartDesign::Pad", "Pad") App.activeDocument().Pad.Sketch = App.activeDocument().Sketch App.activeDocument().Pad.Length = 10.0 App.ActiveDocument.recompute() App.ActiveDocument.Pad.Length = self.Length_of_Shorter_X_Rod App.ActiveDocument.Pad.Reversed = 0 App.ActiveDocument.Pad.Midplane = 0 App.ActiveDocument.Pad.Length2 = 100.000000 App.ActiveDocument.Pad.Type = 0 App.ActiveDocument.Pad.UpToFace = None App.ActiveDocument.recompute()
def circleFrom2PointsRadius(p1, p2, radius): """circleFrom2PointsRadiust(Vector, Vector, radius)""" if DraftVecUtils.equals(p1, p2): return None p1_p2 = Part.LineSegment(p1, p2).toShape() dist_p1p2 = DraftVecUtils.dist(p1, p1) mid = findMidpoint(p1_p2) if dist_p1p2 == 2 * radius: circle = Part.Circle(mid, NORM, radius) if circle: return [circle] else: return None dir = vec(p1_p2) dir.normalize() perpDir = dir.cross(Vector(0, 0, 1)) perpDir.normalize() dist = math.sqrt(radius**2 - (dist_p1p2 / 2.0)**2) cen1 = Vector.add(mid, Vector(perpDir).multiply(dist)) cen2 = Vector.add(mid, Vector(perpDir).multiply(-dist)) circles = [] if cen1: circles.append(Part.Circle(cen1, NORM, radius)) if cen2: circles.append(Part.Circle(cen2, NORM, radius)) if circles: return circles else: return None
def drawHexagon(x,y,faceToFace,theta): #Theta is in radians # make an array of points matrix = [[-faceToFace/2, faceToFace*math.tan(math.pi/6)/2], [0, faceToFace/math.cos(math.pi/6)/2], [faceToFace/2, faceToFace*math.tan(math.pi/6)/2], [faceToFace/2, -faceToFace*math.tan(math.pi/6)/2], [0, -faceToFace/math.cos(math.pi/6)/2], [-faceToFace/2, -faceToFace*math.tan(math.pi/6)/2], [0, 0]] rotation = [[math.cos(theta),-math.sin(theta)], [math.sin(theta), math.cos(theta)]] rotated = multiply(matrix,rotation) translated = [[rotated[0][0]+x,rotated[0][1]+y], [rotated[1][0]+x,rotated[1][1]+y], [rotated[2][0]+x,rotated[2][1]+y], [rotated[3][0]+x,rotated[3][1]+y], [rotated[4][0]+x,rotated[4][1]+y], [rotated[5][0]+x,rotated[5][1]+y], [x,y], [faceToFace/math.cos(math.pi/6)/2,0]] count = App.ActiveDocument.ActiveObject.GeometryCount App.ActiveDocument.ActiveObject App.ActiveDocument.ActiveObject.addGeometry(Part.Line(App.Vector(translated[0][0],translated[0][1],0),App.Vector(translated[1][0],translated[1][1],0))) App.ActiveDocument.recompute() App.ActiveDocument.ActiveObject.addGeometry(Part.Line(App.Vector(translated[1][0],translated[1][1],0),App.Vector(translated[2][0],translated[2][1],0))) App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Coincident',count+0,2,count+1,1)) App.ActiveDocument.recompute() App.ActiveDocument.ActiveObject.addGeometry(Part.Line(App.Vector(translated[2][0],translated[2][1],0),App.Vector(translated[3][0],translated[3][1],0))) App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Coincident',count+1,2,count+2,1)) App.ActiveDocument.recompute() App.ActiveDocument.ActiveObject.addGeometry(Part.Line(App.Vector(translated[3][0],translated[3][1],0),App.Vector(translated[4][0],translated[4][1],0))) App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Coincident',count+2,2,count+3,1)) App.ActiveDocument.recompute() App.ActiveDocument.ActiveObject.addGeometry(Part.Line(App.Vector(translated[4][0],translated[4][1],0),App.Vector(translated[5][0],translated[5][1],0))) App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Coincident',count+3,2,count+4,1)) App.ActiveDocument.recompute() App.ActiveDocument.ActiveObject.addGeometry(Part.Line(App.Vector(translated[5][0],translated[5][1],0),App.Vector(translated[0][0],translated[0][1],0))) App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Coincident',count+4,2,count+5,1)) App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Coincident',count+5,2,count+0,1)) App.ActiveDocument.recompute() App.ActiveDocument.ActiveObject.addGeometry(Part.Circle(App.Vector(x,y,0),App.Vector(0,0,1),faceToFace/math.cos(math.pi/6)/2)) App.ActiveDocument.recompute() App.ActiveDocument.ActiveObject.toggleConstruction(count+6) for i in range(5): App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Equal',count+i,count+i+1)) for i in range(6): App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('PointOnObject',count+i,1,count+6)) App.ActiveDocument.ActiveObject.addConstraint(Sketcher.Constraint('Distance',count+2,2,count+5,faceToFace))
def outerSoddyCircle(circle1, circle2, circle3): """Compute the outer soddy circle for three tightly packed circles.""" if (geomType(circle1) == "Circle") and (geomType(circle2) == "Circle") \ and (geomType(circle3) == "Circle"): # Original Java code Copyright (rc) 2008 Werner Randelshofer # Converted to python by Martin Buerbaum 2009 # http://www.randelshofer.ch/treeviz/ # Either Creative Commons Attribution 3.0, the MIT license, or the GNU Lesser General License LGPL. A = circle1.Curve.Center B = circle2.Curve.Center C = circle3.Curve.Center ra = circle1.Curve.Radius rb = circle2.Curve.Radius rc = circle3.Curve.Radius # Solution using Descartes' theorem, as described here: # http://en.wikipedia.org/wiki/Descartes%27_theorem k1 = 1 / ra k2 = 1 / rb k3 = 1 / rc k4 = abs(k1 + k2 + k3 - 2 * math.sqrt(k1 * k2 + k2 * k3 + k3 * k1)) q1 = (k1 + 0j) * (A.x + A.y * 1j) q2 = (k2 + 0j) * (B.x + B.y * 1j) q3 = (k3 + 0j) * (C.x + C.y * 1j) temp = ((q1 * q2) + (q2 * q3) + (q3 * q1)) q4 = q1 + q2 + q3 - ((2 + 0j) * cmath.sqrt(temp)) z = q4 / (k4 + 0j) # If the formula is not solvable, we return no circle. if (not z or not (1 / k4)): return None X = -z.real Y = -z.imag print("Outer Soddy circle: " + str(X) + " " + str(Y) + "\n") # Debug # The Radius of the outer soddy circle can also be calculated with the following formula: # radiusOuter = abs(r1*r2*r3 / (r1*r2 + r1*r3 + r2*r3 - 2 * math.sqrt(r1*r2*r3 * (r1+r2+r3)))) circ = Part.Circle(Vector(X, Y, A.z), norm, 1 / k4) return circ else: print("debug: outerSoddyCircle bad parameters!\n") # FreeCAD.Console.PrintMessage("debug: outerSoddyCircle bad parameters!\n") return None
def flipEdge(edge): '''flipEdge(edge) Flips given edge around so the new Vertexes[0] was the old Vertexes[-1] and vice versa, without changing the shape. Currently only lines, line segments, circles and arcs are supported.''' if Part.Line == type(edge.Curve) and not edge.Vertexes: return Part.Edge( Part.Line(edge.valueAt(edge.LastParameter), edge.valueAt(edge.FirstParameter))) elif Part.Line == type(edge.Curve) or Part.LineSegment == type(edge.Curve): return Part.Edge( Part.LineSegment(edge.Vertexes[-1].Point, edge.Vertexes[0].Point)) elif Part.Circle == type(edge.Curve): # Create an inverted circle circle = Part.Circle(edge.Curve.Center, -edge.Curve.Axis, edge.Curve.Radius) # Rotate the circle appropriately so it starts at edge.valueAt(edge.LastParameter) circle.rotate( FreeCAD.Placement( circle.Center, circle.Axis, 180 - math.degrees(edge.LastParameter + edge.Curve.AngleXU))) # Now the edge always starts at 0 and LastParameter is the value range arc = Part.Edge(circle, 0, edge.LastParameter - edge.FirstParameter) return arc elif Part.BSplineCurve == type(edge.Curve): spline = edge.Curve mults = spline.getMultiplicities() weights = spline.getWeights() knots = spline.getKnots() poles = spline.getPoles() perio = spline.isPeriodic() ratio = spline.isRational() degree = spline.Degree ma = max(knots) mi = min(knots) knots = [ma + mi - k for k in knots] mults.reverse() weights.reverse() poles.reverse() knots.reverse() flipped = Part.BSplineCurve() flipped.buildFromPolesMultsKnots(poles, mults, knots, perio, degree, weights, ratio) return Part.Edge(flipped)
def make_keyhole_aperture(pipe_radius, keyhole_height, keyhole_width): """Creates a wire outline of a circular pipe with a keyhole extension on the side. aperture_height and aperture_width are the full height and width (the same as if it were a rectangle). The end curves are defined as 180 degree arcs. Args: pipe_radius (Base.Unit): Radius of the main beam pipe. keyhole_height (Base.Unit): Total height of the keyhole slot. keyhole_width (Base.Unit): Total width of the keyhole slot. Returns: wire1 (FreeCAD wire definition): An outline description of the shape. face1 (FreeCAD face definition): A surface description of the shape. """ # X intersection of keyhole with pipe. x_intersection = Units.Quantity( sqrt(pipe_radius ** 2 - (keyhole_height / 2.0) ** 2), 1 ) # Create the initial four vertices for the lines. v1 = Base.Vector(0, keyhole_height / 2.0, x_intersection) v2 = Base.Vector( 0, keyhole_height / 2.0, x_intersection + keyhole_width - keyhole_height / 2 ) v3 = Base.Vector( 0, -keyhole_height / 2.0, x_intersection + keyhole_width - keyhole_height / 2 ) v4 = Base.Vector(0, -keyhole_height / 2.0, x_intersection) v5 = Base.Vector(0, 0, x_intersection + keyhole_width) # Create lines line1 = Part.LineSegment(v1, v2) arc2 = Part.Arc(v2, v5, v3) line3 = Part.LineSegment(v3, v4) # angle at which the keyhole intersects the pipe. half_angle = asin(keyhole_height / (2 * pipe_radius)) # Create curves curve1 = Part.Circle(Base.Vector(0, 0, 0), Base.Vector(1, 0, 0), pipe_radius) arc1 = Part.Arc( curve1, half_angle, (2 * pi) - half_angle ) # angles are in radian here # Make a shape shape1 = Part.Shape([arc1, line1, arc2, line3]) # Make a wire outline. wire1 = Part.Wire(shape1.Edges) # Make a face. face1 = Part.Face(wire1) return wire1, face1
def CreateSlotPlateInnerSet(SketchFeature): SketchFeature.addGeometry( Part.Circle(App.Vector(195.055893, 39.562252, 0), App.Vector(0, 0, 1), 29.846098)) SketchFeature.addGeometry( Part.LineSegment(App.Vector(150.319031, 13.449363, 0), App.Vector(36.700474, 13.139774, 0))) SketchFeature.addConstraint(Sketcher.Constraint('Horizontal', 5)) SketchFeature.addGeometry( Part.LineSegment(App.Vector(36.700474, 13.139774, 0), App.Vector(77.566010, 63.292927, 0))) SketchFeature.addConstraint(Sketcher.Constraint('Coincident', 5, 2, 6, 1)) SketchFeature.addGeometry( Part.LineSegment(App.Vector(77.566010, 63.292927, 0), App.Vector(148.151917, 63.602505, 0))) SketchFeature.addConstraint(Sketcher.Constraint('Coincident', 6, 2, 7, 1)) SketchFeature.addConstraint(Sketcher.Constraint('Horizontal', 7)) SketchFeature.addConstraint(Sketcher.Constraint('Parallel', 1, 6)) SketchFeature.addGeometry( Part.ArcOfCircle( Part.Circle(App.Vector(192.422913, 38.216347, 0), App.Vector(0, 0, 1), 45.315174), 2.635158, 3.602228)) SketchFeature.addConstraint(Sketcher.Constraint('Coincident', 7, 2, 8, 1)) SketchFeature.addConstraint(Sketcher.Constraint('Coincident', 8, 2, 5, 1))
def prepareSketch(self, radius, height, saveSketch): sketch = FreeCAD.ActiveDocument.addObject('Sketcher::SketchObject', 'Sketch') if saveSketch: sketch.ViewObject.hide() self.Sketches.append(sketch) radiusWithOffset = radius - 20 heightWithOffset = height + 5 numberOfLinesToDraw = math.floor( radiusWithOffset * 2 / heightWithOffset) + 1 # draw circle sketch.addGeometry( Part.Circle(FreeCAD.Vector(0, radiusWithOffset, 0), FreeCAD.Vector(0, 0, 1), radiusWithOffset)) sketch.addConstraint(Sketcher.Constraint('PointOnObject', 0, 3, -2)) sketch.addConstraint(Sketcher.Constraint('PointOnObject', -1, 1, 0)) sketch.addConstraint(Sketcher.Constraint('Radius', 0, radiusWithOffset)) # draw lines starting from top y = radiusWithOffset + (numberOfLinesToDraw / 2) * heightWithOffset - heightWithOffset / 2 for i in range(numberOfLinesToDraw): geometryIndex = i + 1 sketch.addGeometry( Part.LineSegment(FreeCAD.Vector(-radiusWithOffset, y, 0), FreeCAD.Vector(radiusWithOffset, y, 0))) sketch.addConstraint( Sketcher.Constraint('Horizontal', geometryIndex)) sketch.addConstraint( Sketcher.Constraint('DistanceY', -1, 1, geometryIndex, 2, y)) sketch.addConstraint( Sketcher.Constraint('PointOnObject', geometryIndex, 1, 0)) sketch.addConstraint( Sketcher.Constraint('PointOnObject', geometryIndex, 2, 0)) y -= heightWithOffset sketch.recompute() return sketch
def _mapBMHoleEdges(self): self.BMHoleEdgeMap = dict() for i in [1, 2, 3, 4]: ie = 0 #print ("*** LCDMountingBracket::_mapBMHoleEdges(): self.bracketmh[",i,"] is ",self.bracketmh[i]) for e in self.bracket.Edges: c = e.Curve #print ("*** LCDMountingBracket::_mapBMHoleEdges(): type(c) is ",type(c)) #print ("*** LCDMountingBracket::_mapBMHoleEdges(): type(Part.Circle()) is ",type(Part.Circle())) if type(c) is type(Part.Circle()): #print ("*** LCDMountingBracket::_mapBMHoleEdges(): c.Center is ",c.Center) if c.Center.x == self.bracketmh[i].x and \ c.Center.y == self.bracketmh[i].y and \ c.Center.z == self.bracketmh[i].z: self.BMHoleEdgeMap[i] = ie break ie += 1
def Activated(self): "Do something here when button is clicked" FreeCAD.Console.PrintMessage("Workbench is working!") if Gui.ActiveDocument == None: FreeCAD.newDocument() # view = Gui.activeDocument().activeView() doc = FreeCAD.activeDocument() n = list() c = Part.Circle() c.Radius = 2.0 f = doc.addObject("Part::Feature", "Circle") # create a document with a circle feature f.Shape = c.toShape() # Assign the circle shape to the shape property doc.recompute() return
def draw(self): try: App.getDocument('zRodR').recompute() App.closeDocument("zRodR") App.setActiveDocument("") App.ActiveDocument = None except: pass #make document App.newDocument("zRodR") App.setActiveDocument("zRodR") App.ActiveDocument = App.getDocument("zRodR") #make sketch # sketch = App.activeDocument().addObject('Sketcher::SketchObject','Sketch') App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch') App.activeDocument().Sketch.Placement = App.Placement( App.Vector(0.000000, 0.000000, 0.000000), App.Rotation(0.000000, 0.000000, 0.000000, 1.000000)) App.ActiveDocument.Sketch.addGeometry( Part.Circle(App.Vector(50, 50, 0), App.Vector(0, 0, 1), gv.zRodDiaR)) App.ActiveDocument.recompute() #sketch.addConstraint(Sketcher.Constraint('Coincident',0,3,-1,1)) App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Coincident', 0, 3, -1, 1)) App.ActiveDocument.recompute() App.ActiveDocument.Sketch.addConstraint( Sketcher.Constraint('Radius', 0, gv.zRodDiaR / 2)) App.ActiveDocument.recompute() App.getDocument('zRodR').recompute() #Pad sketch App.activeDocument().addObject("PartDesign::Pad", "Pad") App.activeDocument().Pad.Sketch = App.activeDocument().Sketch App.activeDocument().Pad.Length = 10.0 App.ActiveDocument.recompute() App.ActiveDocument.Pad.Length = gv.zRodLength App.ActiveDocument.Pad.Reversed = 0 App.ActiveDocument.Pad.Midplane = 0 App.ActiveDocument.Pad.Length2 = 100.000000 App.ActiveDocument.Pad.Type = 0 App.ActiveDocument.Pad.UpToFace = None App.ActiveDocument.recompute()
def getarc(data): "turns an OCA arc definition into a FreeCAD Part Edge" print "found arc ", data c = None if (data[0] == "ARC"): # 3-points arc pts = data[1:] verts = [] for p in range(len(pts)): if (pts[p] == "P"): verts.append(getpoint(pts[p:p + 3])) elif (pts[p][0] == "P"): verts.append(getpoint([pts[p]])) if verts[0] and verts[1] and verts[2]: c = Part.Arc(verts[0], verts[1], verts[2]) elif (data[0][0] == "P"): # 2-point circle verts = [] rad = None for p in range(len(data)): if (data[p] == "P"): verts.append(getpoint(data[p:p + 4])) elif (data[p][0] == "P"): verts.append(getpoint([data[p]])) elif (data[p] == "VAL"): rad = float(data[p + 1]) elif (data[p][0] == "L"): lines.append(objects[data[p]]) c = Part.Circle() c.Center = verts[0] if rad: c.Radius = rad else: c.Radius = DraftVecUtils.new(verts[0], verts[1]).Length elif (data[0][0] == "L"): # 2-lines circle lines = [] rad = None for p in range(len(data)): if (data[p] == "VAL"): rad = float(data[p + 1]) elif (data[p][0] == "L"): lines.append(objects[data[p]]) circles = DraftGeomUtils.circleFrom2LinesRadius( lines[0], lines[1], rad) if circles: c = circles[0] if c: return c.toShape()
def execute(self, fp): pitch = fp.Pitch radius = fp.Diameter / 2 height = fp.Height barradius = fp.BarDiameter / 2 myhelix = Part.makeHelix(pitch, height, radius) g = myhelix.Edges[0].Curve c = Part.Circle() c.Center = g.value(0) # start point of the helix c.Axis = (0, 1, 0) c.Radius = barradius p = c.toShape() section = Part.Wire([p]) makeSolid = 1 #change to 1 to make a solid isFrenet = 1 myspring = Part.Wire(myhelix).makePipeShell([section], makeSolid, isFrenet) fp.Shape = myspring
def BoxCircle(SketchFeature): # Square with a circle centered at the upper right corner top_edge = int(SketchFeature.GeometryCount) right_edge = top_edge + 1 CreateRectangleSketch(SketchFeature, [0, 0], [2, 2]) top_midpoint = App.Vector(1, 2, 0) right_midpoint = App.Vector(2, 1, 0) circle = int(SketchFeature.GeometryCount) SketchFeature.addGeometry( Part.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 1), False) SketchFeature.addConstraint(Sketcher.Constraint('Radius', circle, 1)) SketchFeature.addConstraint( Sketcher.Constraint('Coincident', top_edge, 2, circle, 3)) # Since the circle center is coincident with the corner, there are three coincident points # and thus the simpler fillet() call would get confused. Instead we'll need to point at the two # lines and their midpoints SketchFeature.fillet(top_edge, right_edge, top_midpoint, right_midpoint, 0.25, True, True)
def shape(self): path = Part.Wire(self.path3d()) c = Part.Circle(path.Edges[0].valueAt(path.Edges[0].FirstParameter), path.Edges[0].tangentAt(path.Edges[0].FirstParameter), self.wire_diam / 2.0) pro = Part.Wire([c.toShape()]) ps = Part.BRepOffsetAPI.MakePipeShell(path) ps.setFrenetMode(True) #ps.setForceApproxC1(True) ps.setTolerance(1e-2, 1e-2, 0.1) ps.setMaxDegree(5) ps.setMaxSegments(999) ps.add(pro) if ps.isReady(): ps.build() ps.makeSolid() return ps.shape() return None