Пример #1
1
Файл: hex.py Проект: phonx/BOLTS
def hex1(params, document):
    key = params["key"]
    d1 = params["d1"]
    k = params["k"]
    s = params["s"]
    h = params["h"]
    if h is None:
        h = 0.0
    l = params["l"]
    name = params["name"]

    part = document.addObject("Part::Feature", name)

    # head
    a = s / math.tan(math.pi / 3.0)
    box1 = makeBox(a, s, k)
    box1.translate(Vector(-0.5 * a, -0.5 * s, 0))
    box1.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 30)
    box2 = makeBox(a, s, k)
    box2.translate(Vector(-0.5 * a, -0.5 * s, 0))
    box2.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 150)
    box3 = makeBox(a, s, k)
    box3.translate(Vector(-0.5 * a, -0.5 * s, 0))
    box3.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 270)
    head = box1.fuse(box2).fuse(box3)

    shaft_unthreaded = Part.makeCylinder(0.5 * d1, h + k)
    shaft_threaded = Part.makeCylinder(0.5 * d1, l - h)
    shaft_threaded.translate(Vector(0, 0, h + k))
    part.Shape = head.fuse(shaft_unthreaded).fuse(shaft_threaded).removeSplitter()
Пример #2
0
def linesFromPoints(points, closed=False):
    lines = []
    for i in range(0, len(points) - 1):
        lines.append(Part.makeLine(points[i], points[(i + 1) % len(points)]))
    if closed:
        lines.append(Part.makeLine(points[len(points) - 1], points[0]))
    return lines
Пример #3
0
def mainFrameCoeff(ship, draft):
	""" Calculate main frame coefficient.
	@param ship Selected ship instance
	@param draft Draft.
	@return Main frame coefficient
	"""
	cm	 = 0.0
	maxY = 0.0
	minY = 0.0
	# We will take a duplicate of ship shape in order to place it
	shape = ship.Shape.copy()
	shape.translate(Vector(0.0,0.0,-draft))
	x	 = 0.0
	area = 0.0
	# Now we need to know the x range of values
	bbox = shape.BoundBox
	xmin = bbox.XMin
	xmax = bbox.XMax
	# Create the box
	L = xmax - xmin
	B = bbox.YMax - bbox.YMin
	p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
	box = Part.makeBox(1.5*L + x, 3.0*B, - bbox.ZMin + 1.0, p)
	maxY = bbox.YMin
	minY = bbox.YMax
	# Compute common part with ship
	for s in shape.Solids:
		# Get solids intersection
		try:
			common = box.common(s)
		except:
			continue
		if common.Volume == 0.0:
			continue
		# Recompute object adding it to the scene, when we have
		# computed desired data we can remove it.
		try:
			Part.show(common)
		except:
			continue
		# Divide by faces and compute only section placed ones
		faces  = common.Faces
		for f in faces:
			faceBounds = f.BoundBox
			# Orientation filter
			if faceBounds.XMax - faceBounds.XMin > 0.00001:
				continue
			# Place filter
			if abs(faceBounds.XMax - x) > 0.00001:
				continue
			# Valid face, compute area
			area = area + f.Area
			maxY = max(maxY, faceBounds.YMax)
			minY = min(minY, faceBounds.YMin)
		# Destroy last object generated
		App.ActiveDocument.removeObject(App.ActiveDocument.Objects[-1].Name)
	dy = maxY - minY
	if dy*draft > 0.0:
		cm = area / (dy*draft)
	return cm
Пример #4
0
def FilletFlange(innerdia = 10,filletdia = 5,filletthick=10):
	ff = Part.makeCylinder(innerdia/2 + filletdia/2,filletthick)
	fi = Part.makeCylinder(innerdia/2,filletthick+filletdia)
	fi.translate(Vector(0,0,-filletdia/2))
	ff=ff.fuse(fi)
	ff=ff.fuse(ff.makeFillet(filletdia/2-0.01,[ff.Edges[3],ff.Edges[5]]))
	return ff
Пример #5
0
def makeRef(p1, p2, p3, border):
        p4 = p1 + (p3 - p2)

        lines = linesFromPoints([p1, p2, p3, p4], True)
        w = Part.Wire(lines)
        p = w.extrude(border)
        Part.show(p)
Пример #6
0
def getShapeFromMesh(mesh):
    import Part, MeshPart
    if mesh.isSolid() and (mesh.countComponents() == 1):
        # use the best method
        faces = []
        for f in mesh.Facets:
            p=f.Points+[f.Points[0]]
            pts = []
            for pp in p:
                pts.append(FreeCAD.Vector(pp[0],pp[1],pp[2]))
            faces.append(Part.Face(Part.makePolygon(pts)))
        shell = Part.makeShell(faces)
        solid = Part.Solid(shell)
        solid = solid.removeSplitter()
        return solid

    faces = []  
    segments = mesh.getPlanarSegments(0.001) # use rather strict tolerance here
    for i in segments:
        if len(i) > 0:
            wires = MeshPart.wireFromSegment(mesh, i)
            if wires:
                faces.append(makeFace(wires))
    try:
        se = Part.makeShell(faces)
    except:
        return None
    else:
        try:
            solid = Part.Solid(se)
        except:
            return se
        else:
            return solid
Пример #7
0
def p_polyhedron_action(p) :
    '''polyhedron_action : polyhedron LPAREN points EQ OSQUARE points_list_3d ESQUARE COMMA faces EQ OSQUARE path_set ESQUARE COMMA keywordargument_list RPAREN SEMICOL
                      | polyhedron LPAREN points EQ OSQUARE points_list_3d ESQUARE COMMA triangles EQ OSQUARE points_list_3d ESQUARE COMMA keywordargument_list RPAREN SEMICOL'''
    if printverbose: print("Polyhedron Points")
    v = []
    for i in p[6] :
        if printverbose: print(i)
        v.append(FreeCAD.Vector(float(i[0]),float(i[1]),float(i[2])))
    if printverbose:
        print(v)
        print ("Polyhedron "+p[9])
        print (p[12])
    faces_list = []    
    mypolyhed = doc.addObject('Part::Feature',p[1])
    for i in p[12] :
        if printverbose: print(i)
        v2 = FreeCAD.Vector
        pp =[v2(v[k]) for k in i]
        # Add first point to end of list to close polygon
        pp.append(pp[0])
        print(pp)
        w = Part.makePolygon(pp)
        f = Part.Face(w)
        #f = make_face(v[int(i[0])],v[int(i[1])],v[int(i[2])])
        faces_list.append(f)
    shell=Part.makeShell(faces_list)
    solid=Part.Solid(shell).removeSplitter()
    if solid.Volume < 0:
        solid.reverse()
    mypolyhed.Shape=solid
    p[0] = [mypolyhed]
Пример #8
0
	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
Пример #9
0
Файл: hex.py Проект: phonx/BOLTS
def hex2(params, document):
    key = params["key"]
    d1 = params["d1"]
    k = params["k"]
    s = params["s"]
    b1 = params["b1"]
    b2 = params["b2"]
    b3 = params["b3"]
    l = params["l"]
    b = b3
    if l < 125:
        b = b1
    elif l < 200:
        b = b2
    name = params["name"]

    part = document.addObject("Part::Feature", name)

    # head
    a = s / math.tan(math.pi / 3.0)
    box1 = makeBox(a, s, k)
    box1.translate(Vector(-0.5 * a, -0.5 * s, 0))
    box1.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 30)
    box2 = makeBox(a, s, k)
    box2.translate(Vector(-0.5 * a, -0.5 * s, 0))
    box2.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 150)
    box3 = makeBox(a, s, k)
    box3.translate(Vector(-0.5 * a, -0.5 * s, 0))
    box3.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 270)
    head = box1.fuse(box2).fuse(box3)

    shaft_unthreaded = Part.makeCylinder(0.5 * d1, l - b + k)
    shaft_threaded = Part.makeCylinder(0.5 * d1, b)
    shaft_threaded.translate(Vector(0, 0, l - b + k))
    part.Shape = head.fuse(shaft_unthreaded).fuse(shaft_threaded).removeSplitter()
Пример #10
0
    def areaOpShapes(self, obj):
        '''areaOpShapes(obj) ... return shapes representing the solids to be removed.'''
        PathLog.track()

        if obj.Base:
            PathLog.debug("base items exist.  Processing...")
            removalshapes = []
            for b in obj.Base:
                PathLog.debug("Base item: {}".format(b))
                for sub in b[1]:
                    if "Face" in sub:
                        shape = Part.makeCompound([getattr(b[0].Shape, sub)])
                    else:
                        edges = [getattr(b[0].Shape, sub) for sub in b[1]]
                        shape = Part.makeFace(edges, 'Part::FaceMakerSimple')

                    env = PathUtils.getEnvelope(self.baseobject.Shape, subshape=shape, depthparams=self.depthparams)
                    obj.removalshape = env.cut(self.baseobject.Shape)
                    removalshapes.append((obj.removalshape, False))
        else:  # process the job base object as a whole
            PathLog.debug("processing the whole job base object")

            env = PathUtils.getEnvelope(self.baseobject.Shape, subshape=None, depthparams=self.depthparams)
            obj.removalshape = env.cut(self.baseobject.Shape)
            removalshapes = [(obj.removalshape, False)]
        return removalshapes
Пример #11
0
 def update(self, draft, trim, ship):
     """ Update free surface 3D view
     @param traft Draft.
     @param trim Trim in degrees.
     """
     # Destroy old object if exist
     self.clean()
     # Set free surface bounds
     bbox = ship.Shape.BoundBox
     L = 1.5 * bbox.XLength
     B = 3.0 * bbox.YLength
     # Create plane
     x = - 0.5 * L
     y = - 0.5 * B
     point = Base.Vector(x,y,0.0)
     plane = Part.makePlane(L,B, point, Base.Vector(0,0,1))
     # Set position
     plane.rotate(Base.Vector(0,0,0), Base.Vector(0,1,0), trim)
     plane.translate(Base.Vector(0,0,draft))
     # Create the FreeCAD object
     Part.show(plane)
     objs = FreeCAD.ActiveDocument.Objects
     self.obj = objs[len(objs)-1]
     self.obj.Label = 'FreeSurface'
     # Set properties of object
     guiObj = FreeCADGui.ActiveDocument.getObject(self.obj.Name)
     guiObj.ShapeColor = (0.4,0.8,0.85)
     guiObj.Transparency = 50
 def execute(self, part):
     data = iso_4014_1979_partial_hex_screw["sizes"][part.size]
     # the calculations are based on the ACII art picture above,
     # with the points starting from the far right point,
     # and ending with the same point to close the polygon
     y_distance = 0.5 * data["s_max"]
     angle = math.pi / 3
     head_radius = y_distance / math.sin(angle)
     x_distance = math.cos(angle) * head_radius
     points = [
         Vector(head_radius, 0, 0),
         Vector(x_distance, y_distance, 0),
         Vector(-x_distance, y_distance, 0),
         Vector(-head_radius, 0, 0),
         Vector(-x_distance, -y_distance, 0),
         Vector(x_distance, -y_distance, 0),
         Vector(head_radius, 0, 0),
     ]
     # create a polygon and transform it to a face too:
     hexagon = Part.Face(Part.makePolygon(points))
     # just an integer won't work here, must use units:
     k = data["k_nom"] * Units.MilliMetre
     head = hexagon.extrude(Vector(0, 0, k))
     shaft = Part.makeCylinder(
         0.5 * data["ds_max"], part.length + k,
         Vector(0, 0, 0), Vector(0, 0, 1)
     )
     part.Shape = head.fuse(shaft)
Пример #13
0
def makeSnapshotWithGui():
	from PyQt4 import QtGui
	import FreeCADGui

	def getMainWindow():
		toplevel = QtGui.qApp.topLevelWidgets()
		for i in toplevel:
			if i.metaObject().className() == "Gui::MainWindow":
				return i
		raise Exception("No main window found")

	mw=getMainWindow()
	mw.hide()
	#mw.showMinimized()

	# Create a test geometry and add it to the document
	obj=Part.makeCone(10,8,10)
	doc = FreeCAD.newDocument()
	Part.show(obj)

	# switch off animation so that the camera is moved to the final position immediately
	view = FreeCADGui.getDocument(doc.Name).activeView()
	view.setAnimationEnabled(False)
	view.viewAxometric()
	view.fitAll()
	view.saveImage('crystal.png',800,600,'Current')
	FreeCAD.closeDocument(doc.Name)
	# close the application
	QtGui.qApp.quit()
Пример #14
0
def servo():
    """servo"""
    data = servo_data

    # approximate the servo
    body = Part.makeBox(data['x'], data['y'], data['z'])

    maintien1 = Part.makeBox(data['maintien x'], data['maintien y'], data['maintien z'])
    maintien1.translate(Vector(data['x'], 0, data['maintien offset z']))
    maintien2 = Part.makeBox(data['maintien x'], data['maintien y'], data['maintien z'])
    maintien2.translate(Vector(-data['maintien x'], 0, data['maintien offset z']))

    cylindre = Part.makeCylinder(data['cylindre r'], data['cylindre h'])
    cylindre.translate(Vector(data['cylindre offset x'], data['y'] / 2, data['cylindre offset z']))

    taquet = Part.makeBox(data['taquet x'], data['taquet y'], data['taquet z'])
    taquet.translate(Vector(-data['taquet y'] / 2, -data['taquet y'] / 2, 0))
    taquet.rotate(Vector(0, 0, 0), Vector(0, 0, 1), -90)
    taquet.translate(Vector(data['cylindre offset x'], data['y'] / 2, data['z'] + data['cylindre h']))

    obj = body.fuse(maintien1)
    obj = obj.fuse(maintien2)
    obj = obj.fuse(cylindre)
    obj = obj.fuse(taquet)
    obj.translate(Vector(-data['x'] / 2, -data['y'] / 2, -data['z'] / 2))

    return obj
Пример #15
0
 def getArea(self,obj):
     "returns the horizontal area at the center of the space"
     import Part,DraftGeomUtils
     if not hasattr(obj.Shape,"CenterOfMass"):
         return 0
     try:
         pl = Part.makePlane(1,1)
         pl.translate(obj.Shape.CenterOfMass)
         sh = obj.Shape.copy()
         cutplane,v1,v2 = ArchCommands.getCutVolume(pl,sh)
         e = sh.section(cutplane)
         e = Part.__sortEdges__(e.Edges)
         w = Part.Wire(e)
         f = Part.Face(w)
     except Part.OCCError:
         return 0
     else:
         if hasattr(obj,"PerimeterLength"):
             if w.Length != obj.PerimeterLength.Value:
                 obj.PerimeterLength = w.Length
         if hasattr(obj,"VerticalArea"):
             a = 0
             for f in sh.Faces:
                 ang = f.normalAt(0,0).getAngle(FreeCAD.Vector(0,0,1))
                 if (ang > 1.57) and (ang < 1.571):
                     a += f.Area
                 if a != obj.VerticalArea.Value:
                     obj.VerticalArea = a
         #print "area of ",obj.Label," : ",f.Area
         return f.Area
Пример #16
0
def arma8ptos(fi,recubrN,sepFi,radDobl,pto1,pto2,pto3,pto4,pto5,pto6,pto7,pto8,gap1,gap2):
    recubrG=recubrN+float(fi)/1000/2.0
    v=pto6.sub(pto2)
    recArmPlano=(v.Length-2*recubrG-int((v.Length-2.0*recubrG)/sepFi)*sepFi)/2.0
    v1=GeomUtils.vectorUnitario(pto2,pto1)
    v2=GeomUtils.vectorUnitario(pto2,pto3)
    v3=GeomUtils.vectorUnitario(pto3,pto4)
    v4=GeomUtils.vectorUnitario(pto2,pto6)
    v5=GeomUtils.vectorUnitario(pto3,pto7)
    v6=GeomUtils.vectorUnitario(pto6,pto5)
    v7=GeomUtils.vectorUnitario(pto6,pto7)
    v8=GeomUtils.vectorUnitario(pto7,pto8)
    pto1a=pto1.add(GeomUtils.escalarPorVector(recArmPlano,v4)).add(GeomUtils.escalarPorVector(recubrG,v2)).add(GeomUtils.escalarPorVector(gap1,v1))
    pto2a=pto2.add(GeomUtils.escalarPorVector(recArmPlano,v4)).add(GeomUtils.escalarPorVector(recubrG,v2)).add(GeomUtils.escalarPorVector(recubrG,v1))
    pto3a=pto3.add(GeomUtils.escalarPorVector(recArmPlano,v5)).sub(GeomUtils.escalarPorVector(recubrG,v2)).add(GeomUtils.escalarPorVector(recubrG,v3))
    pto4a=pto4.add(GeomUtils.escalarPorVector(recArmPlano,v5)).sub(GeomUtils.escalarPorVector(recubrG,v2)).add(GeomUtils.escalarPorVector(gap2,v3))
    pto5a=pto5.sub(GeomUtils.escalarPorVector(recArmPlano,v4)).add(GeomUtils.escalarPorVector(recubrG,v7)).add(GeomUtils.escalarPorVector(gap1,v6))
    pto6a=pto6.sub(GeomUtils.escalarPorVector(recArmPlano,v4)).add(GeomUtils.escalarPorVector(recubrG,v7)).add(GeomUtils.escalarPorVector(recubrG,v6))
    pto7a=pto7.sub(GeomUtils.escalarPorVector(recArmPlano,v5)).sub(GeomUtils.escalarPorVector(recubrG,v7)).add(GeomUtils.escalarPorVector(recubrG,v8))
    pto8a=pto8.sub(GeomUtils.escalarPorVector(recArmPlano,v5)).sub(GeomUtils.escalarPorVector(recubrG,v7)).add(GeomUtils.escalarPorVector(gap2,v8))
    cara1=Part.Face(Part.makePolygon([pto1a,pto2a,pto6a,pto5a,pto1a]))
    cara2=Part.Face(Part.makePolygon([pto2a,pto6a,pto7a,pto3a,pto2a]))
    cara3=Part.Face(Part.makePolygon([pto3a,pto4a,pto8a,pto7a,pto3a]))
    arma=cara1.fuse(cara2.fuse(cara3))
    armadura=arma.makeFillet(radDobl,arma.Edges)
    return armadura
Пример #17
0
 def make_extrusion(self, name, points, invert_order):
     print 'make_extrusion', name, invert_order
     wires = []
     for section in points:
         pts = []
         if len(section) < 3:
             print "warning: cross section in make_extrusion() < 3 points"
             print "length:", len(section)
             continue
         if not invert_order:
             for pt in section:
                 # print "%.2f %.2f %.2f" % (pt[0], pt[1], pt[2])
                 pts.append( Base.Vector(pt[0], pt[1], pt[2]) )
             pt = section[0]
             pts.append( Base.Vector(pt[0], pt[1], pt[2]) )
         else:
             for pt in section:
                 # print "%.2f %.2f %.2f" % (pt[0], pt[1], pt[2])
                 pts.append( Base.Vector(pt[0], pt[1], pt[2]) )
             pt = section[0]
             pts.append( Base.Vector(pt[0], pt[1], pt[2]) )
             #pt = section[0]
             #Base.Vector(pt[0], pt[1], pt[2])
             #for pt in reversed(section):
                 # print "%.2f %.2f %.2f" % (pt[0], pt[1], pt[2])
                 #pts.append( Base.Vector(pt[0], pt[1], pt[2]) )
   
         wire = Part.makePolygon(pts)
         wires.append(wire)
     loft = Part.makeLoft(wires, False)
     return loft
Пример #18
0
def gen_haus(le,wi,hiall,hi,ang,midx=0.7,wx=0.5,midy=0.5,wy=0):
	h=gen_haus0(le,wi,hiall,hi,midx,wx,midy,wy)
	print h
	Part.show(h)
	p=FreeCAD.ActiveDocument.ActiveObject
	p.Placement.Rotation.Angle=ang*math.pi/180
	return p
Пример #19
0
 def projectFace(self,face):
     "projects a single face on the WP"
     #print "VRM: projectFace start: ",len(face[0].Vertexes)," verts, ",len(face[0].Edges)," edges"
     wires = []
     if not face[0].Wires:
         if DEBUG: print "Error: Unable to project face on the WP"
         return None
     norm = face[0].normalAt(0,0)
     for w in face[0].Wires:
         verts = []
         edges = Part.__sortEdges__(w.Edges)
         #print len(edges)," edges after sorting"
         for e in edges:
             v = e.Vertexes[0].Point
             #print v
             v = self.wp.getLocalCoords(v)
             verts.append(v)
         verts.append(verts[0])
         if len(verts) > 2:
             #print "new wire with ",len(verts)
             wires.append(Part.makePolygon(verts))
     try:
         sh = ArchCommands.makeFace(wires)
     except:
         if DEBUG: print "Error: Unable to project face on the WP"
         return None
     else:
         # restoring flipped normals
         vnorm = self.wp.getLocalCoords(norm)
         if vnorm.getAngle(sh.normalAt(0,0)) > 1:
             sh.reverse()
         #print "VRM: projectFace end: ",len(sh.Vertexes)," verts"
         return [sh]+face[1:]
Пример #20
0
 def make_surfaceShelves(self):
     
     # shelf for left work surface
     
     shelf_width = self.pos_support1[0]-self.pos_supportMini1[0]+self.thickness
     shelf_depth = self.depth - self.pos_support1[1]
     shelf_height = self.underside_height / 2.
     
     shelf = Part.makeBox(shelf_width, shelf_depth, self.thickness, self.pos_supportMini1 + Base.Vector(-self.thickness, 0, 0)) 
     shelf = shelf.cut(self.parts_left['support1'])
     
     self.parts_left['shelf'] = shelf
     
     
    
    
    # shelf for right work surface
     shelf_width = self.pos_support3[0]-self.pos_supportMini2[0]+self.thickness
     shelf_depth = self.depth - self.pos_support3[1]
     shelf_height = self.underside_height / 2.
     
     shelf = Part.makeBox(shelf_width, shelf_depth, self.thickness, self.pos_supportMini2 + Base.Vector(-self.thickness, 0, 0)) 
     shelf = shelf.cut(self.parts_right['support3'])
     
     self.parts_right['shelf'] = shelf
Пример #21
0
    def __init__(self, doc, name='integ2'):
        self.data = {
            'len lo': 20., # mm
            'len hi': 100., # mm
            'ext diameter': 36., # mm
            'int diameter': 30., # mm
        }

        int_diam = self.data['int diameter']
        ext_diam = self.data['ext diameter']
        len_hi = self.data['len hi']
        len_lo = self.data['len lo']

        cone = Part.makeCone(int_diam / 2, ext_diam / 2, len_lo)

        trunk = Part.makeCylinder(ext_diam / 2, len_hi)
        trunk.translate(Vector(0, 0, len_lo))

        comp = cone.fuse(trunk)

        cutter = Part.makeBox(ext_diam, ext_diam, len_hi + len_lo)
        cutter.translate(Vector(0, -ext_diam / 2, 0))
        cutter.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 180)

        comp = comp.common(cutter)

        MecaComponent.__init__(self, doc, comp, name, (1., 1., 0.))
Пример #22
0
    def __init__(self, doc, tube, name='aero_clutch'):
        self.data = {
            'len': 20., # mm
            'width' : 15., # mm
        }
        data = self.data
        data['thick'] = tube['thick'] # mm
        data['ext diameter'] = tube['int diameter'] - tube['thick'] # mm
        data['int diameter'] = tube['int diameter'] - 3 * tube['thick'] # mm

        # rebuild a tube
        int_part = Part.makeCylinder(data['int diameter'] / 2, data['len'])
        ext_part = Part.makeCylinder(data['ext diameter'] / 2, data['len'])
        part = ext_part.cut(int_part)

        # cut the external shape
        shape = Part.makeBox(2 * data['ext diameter'], 2 * data['ext diameter'], data['len'])
        shape.translate(Vector(-data['ext diameter'], -data['ext diameter'], 0))

        comp = part.common(shape)

        # cut the nerves
        nerv = Part.makeBox(data['ext diameter'] / 2 - 2 * data['thick'], 3., data['len'] / 2)
        nerv.translate(Vector(-data['ext diameter'] / 2 + data['thick'] / 2, -3. / 2, 0))

        comp = comp.cut(nerv)

        MecaComponent.__init__(self, doc, comp, name, (1., 1., 0.))
Пример #23
0
    def areaOpShapes(self, obj):
        '''areaOpShapes(obj) ... return top face'''
        # Facing is done either against base objects
        if obj.Base:
            PathLog.debug("obj.Base: {}".format(obj.Base))
            faces = []
            for b in obj.Base:
                for sub in b[1]:
                    shape = getattr(b[0].Shape, sub)
                    if isinstance(shape, Part.Face):
                        faces.append(shape)
                    else:
                        PathLog.debug('The base subobject is not a face')
                        return
            planeshape = Part.makeCompound(faces)
            PathLog.debug("Working on a collection of faces {}".format(faces))

        # If no base object, do planing of top surface of entire model
        else:
            planeshape = self.baseobject.Shape
            PathLog.debug("Working on a shape {}".format(self.baseobject.Name))

        # Find the correct shape depending on Boundary shape.
        PathLog.debug("Boundary Shape: {}".format(obj.BoundaryShape))
        bb = planeshape.BoundBox
        if obj.BoundaryShape == 'Boundbox':
            bbperim = Part.makeBox(bb.XLength, bb.YLength, 1, FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin), FreeCAD.Vector(0, 0, 1))
            env = PathUtils.getEnvelope(partshape=bbperim, depthparams=self.depthparams)
        elif obj.BoundaryShape == 'Stock':
            stock = PathUtils.findParentJob(obj).Stock.Shape
            env = stock
        else:
            env = PathUtils.getEnvelope(partshape=planeshape, depthparams=self.depthparams)

        return [(env, False)]
Пример #24
0
def makeSurfaceVolume(filename):
    import FreeCAD,Part
    f1=open(filename)
    coords=[]
    miny=1
    for line in f1.readlines():
        sline=line.strip()
        if sline and not sline.startswith('#'):
            ycoord=len(coords)
            lcoords=[]
            for xcoord, num in enumerate(sline.split()):
                fnum=float(num)
                lcoords.append(FreeCAD.Vector(float(xcoord),float(ycoord),fnum))
                miny=min(fnum,miny)
            coords.append(lcoords)
    s=Part.BSplineSurface()
    s.interpolate(coords)
    plane=Part.makePlane(len(coords[0])-1,len(coords)-1,FreeCAD.Vector(0,0,miny-1))
    l1=Part.makeLine(plane.Vertexes[0].Point,s.value(0,0))
    l2=Part.makeLine(plane.Vertexes[1].Point,s.value(1,0))
    l3=Part.makeLine(plane.Vertexes[2].Point,s.value(0,1))
    l4=Part.makeLine(plane.Vertexes[3].Point,s.value(1,1))
    f0=plane.Faces[0]
    f0.reverse()
    f1=Part.Face(Part.Wire([plane.Edges[0],l1.Edges[0],s.vIso(0).toShape(),l2.Edges[0]]))
    f2=Part.Face(Part.Wire([plane.Edges[1],l3.Edges[0],s.uIso(0).toShape(),l1.Edges[0]]))
    f3=Part.Face(Part.Wire([plane.Edges[2],l4.Edges[0],s.vIso(1).toShape(),l3.Edges[0]]))
    f4=Part.Face(Part.Wire([plane.Edges[3],l2.Edges[0],s.uIso(1).toShape(),l4.Edges[0]]))
    f5=s.toShape().Faces[0]
    solid=Part.Solid(Part.Shell([f0,f1,f2,f3,f4,f5]))
    return solid,(len(coords[0])-1)/2.0,(len(coords)-1)/2.0
Пример #25
0
def makeTube(outerRadius, innerRadius, height):
    outer_cylinder = Part.makeCylinder(outerRadius, height)
    shape = outer_cylinder
    if innerRadius > 0 and innerRadius < outerRadius:
        inner_cylinder = Part.makeCylinder(innerRadius, height)
        shape = outer_cylinder.cut(inner_cylinder)
    return shape
Пример #26
0
def ruled_surface(e1,e2):
    """ creates a ruled surface between 2 edges, with automatic orientation."""
    # Automatic orientation
    # /src/Mod/Part/App/PartFeatures.cpp#171
    p1 = e1.valueAt(e1.FirstParameter)
    p2 = e1.valueAt(e1.LastParameter)
    p3 = e2.valueAt(e2.FirstParameter)
    p4 = e2.valueAt(e2.LastParameter)
    if e1.Orientation == 'Reversed':
        p = p1
        p1 = p2
        p2 = p
    if e2.Orientation == 'Reversed':
        p = p3
        p3 = p4
        p4 = p
    v1 = p2 - p1
    v2 = p3 - p1
    n1 = v1.cross(v2)
    v3 = p3 - p4
    v4 = p2 - p4
    n2 = v3.cross(v4)
    if (n1.dot(n2) < 0):
        e = e2.copy()
        e.reverse()
        return(Part.makeRuledSurface(e1,e))
    else:
        return(Part.makeRuledSurface(e1,e2))
Пример #27
0
 def createGeometry(self,fp):
     if all((fp.Radius1,fp.Radius2,fp.FacesNumber,fp.Height)):
         import math
         import FreeCAD,Part
         #from draftlibs import fcgeo
         plm = fp.Placement
         wires=[]
         faces=[]
         for ir,r in enumerate((fp.Radius1,fp.Radius2)):
             angle = (math.pi*2)/fp.FacesNumber
             pts = [FreeCAD.Vector(r.Value,0,ir*fp.Height.Value)]
             for i in range(fp.FacesNumber-1):
                 ang = (i+1)*angle
                 pts.append(FreeCAD.Vector(r.Value*math.cos(ang),\
                         r.Value*math.sin(ang),ir*fp.Height.Value))
             pts.append(pts[0])
             shape = Part.makePolygon(pts)
             face = Part.Face(shape)
             if ir==1: #top face
                 face.reverse()
             wires.append(shape)
             faces.append(face)
         #shellperi=Part.makeRuledSurface(*wires)
         shellperi=Part.makeLoft(wires)
         shell=Part.Shell(shellperi.Faces+faces)
         fp.Shape = Part.Solid(shell)
         fp.Placement = plm
Пример #28
0
	def execute(self, obj):
		"""Build the object"""

		#-- When length l is given, a vector with length = l and
		#-- orientation v is created
		if obj.l == 0:
			l = obj.v.Length
		else:
			l = obj.l.Value

		#-- Correct the length
		if (l < obj.arrow_l):
			arrow_l = l/2.
		else:
			arrow_l = obj.arrow_l.Value

		#--- Create the base vector
		base_vect = FreeCAD.Vector(obj.v)
		base_vect.Length = l - arrow_l

		#-- Build the object
		vectz = Part.makeCylinder(obj.d / 2.0, base_vect.Length,
							    Vector(0,0,0), obj.v)
		base = Part.makeSphere(obj.d / 2.0)
		arrow = Part.makeCone(obj.d/2. + 2/3. * obj.d, 0.05, arrow_l,
							  base_vect, base_vect)

		#-- Create the union of all the parts
		u = vectz.fuse(base)
		u = u.fuse(arrow)

		#-- Asign the shape
		obj.Shape = u
Пример #29
0
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
Пример #30
0
    def __init__(self, doc, name='helix'):
        self.data = {
            'len lo': 70., # mm
            'len up': 120., # mm
            'int diameter': 36., # mm
            'thick': 1., # mm
        }

        len_lo = self.data['len lo']

        # blocking thread (pas de vis de blocage)
        radius = self.data['int diameter'] / 2

        helix = Part.makeHelix(4., 16., radius)

        p0 = (radius, 0, 0)
        p1 = (radius, 0, 3)
        p2 = (radius - 1, 0, 2)
        p3 = (radius - 1, 0, 1)

        e0 = Part.makeLine(p0, p1)
        e1 = Part.makeLine(p1, p2)
        e2 = Part.makeLine(p2, p3)
        e3 = Part.makeLine(p3, p0)
        section = Part.Wire([e0, e1, e2, e3])
        helix = Part.Wire(helix).makePipeShell([section], 1, 1)
        helix.translate(Vector(0, 0, len_lo - 20))

        helix = helix.fuse(helix)

        comp = helix

        MecaComponent.__init__(self, doc, comp, name, (1., 1., 0.))
Пример #31
0
    def recompute(self):

        if self.bezcurve:
            for seg in self.bezcurve:
                self.sep.removeChild(seg)
                seg = None

        self.bezcurve = []

        if (len(self.points) >= 2):

            if self.degree:

                poles = self.points[1:]

                segpoleslst = [
                    poles[x:x + self.degree]
                    for x in range(0, len(poles), (self.degree or 1))
                ]
            else:
                segpoleslst = [self.points]

            startpoint = self.points[0]

            for segpoles in segpoleslst:
                c = Part.BezierCurve()  #last segment may have lower degree
                c.increase(len(segpoles))
                c.setPoles([startpoint] + segpoles)
                c = c.toShape()
                startpoint = segpoles[-1]

                buf = c.writeInventor(2, 0.01)
                #fp=open("spline.iv","w")
                #fp.write(buf)
                #fp.close()
                try:
                    ivin = coin.SoInput()
                    ivin.setBuffer(buf)
                    ivob = coin.SoDB.readAll(ivin)
                except:
                    # workaround for pivy SoInput.setBuffer() bug
                    import re
                    buf = buf.replace("\n", "")
                    pts = re.findall("point \[(.*?)\]", buf)[0]
                    pts = pts.split(",")
                    pc = []
                    for p in pts:
                        v = p.strip().split()
                        pc.append([float(v[0]), float(v[1]), float(v[2])])
                    coords = coin.SoCoordinate3()
                    coords.point.setValues(0, len(pc), pc)
                    line = coin.SoLineSet()
                    line.numVertices.setValue(-1)
                    bezcurveseg = coin.SoSeparator()
                    bezcurveseg.addChild(coords)
                    bezcurveseg.addChild(line)
                    self.sep.addChild(bezcurveseg)
                else:
                    if ivob and ivob.getNumChildren() > 1:
                        bezcurveseg = ivob.getChild(1).getChild(0)
                        bezcurveseg.removeChild(bezcurveseg.getChild(0))
                        bezcurveseg.removeChild(bezcurveseg.getChild(0))
                        self.sep.addChild(bezcurveseg)
                    else:
                        FreeCAD.Console.PrintWarning(
                            "bezcurveTracker.recompute() failed to read-in Inventor string\n"
                        )
                self.bezcurve.append(bezcurveseg)
Пример #32
0
    def update_object_from_edit_points(self,
                                       obj,
                                       node_idx,
                                       v,
                                       alt_edit_mode=0):
        if obj.FirstAngle == obj.LastAngle:
            # object is a circle
            if node_idx == 0:
                obj.Placement.Base = obj.Placement.multVec(v)
            elif node_idx == 1:
                obj.Radius = v.Length

        else:
            # obj is an arc
            if alt_edit_mode == 0:
                import Part
                if node_idx == 0:
                    # center point
                    p1 = self.getArcStart(obj)
                    p2 = self.getArcEnd(obj)
                    p0 = DraftVecUtils.project(v, self.getArcMid(obj))
                    obj.Radius = p1.sub(p0).Length
                    obj.FirstAngle = -math.degrees(
                        DraftVecUtils.angle(p1.sub(p0)))
                    obj.LastAngle = -math.degrees(
                        DraftVecUtils.angle(p2.sub(p0)))
                    obj.Placement.Base = obj.Placement.multVec(p0)

                else:
                    """ Edit arc by 3 points.
                    """
                    v = obj.Placement.multVec(v)
                    p1 = obj.Placement.multVec(self.getArcStart(obj))
                    p2 = obj.Placement.multVec(self.getArcMid(obj))
                    p3 = obj.Placement.multVec(self.getArcEnd(obj))

                    if node_idx == 1:  # first point
                        p1 = v
                    elif node_idx == 3:  # midpoint
                        p2 = v
                    elif node_idx == 2:  # second point
                        p3 = v

                    arc = Part.ArcOfCircle(p1, p2, p3)
                    import Part
                    s = arc.toShape()
                    # Part.show(s) DEBUG
                    p0 = arc.Location
                    obj.Placement.Base = p0
                    obj.Radius = arc.Radius

                    delta = s.Vertexes[0].Point
                    obj.FirstAngle = -math.degrees(
                        DraftVecUtils.angle(p1.sub(p0)))
                    delta = s.Vertexes[1].Point
                    obj.LastAngle = -math.degrees(
                        DraftVecUtils.angle(p3.sub(p0)))

            elif alt_edit_mode == 1:
                # edit arc by center radius FirstAngle LastAngle
                if node_idx == 0:
                    obj.Placement.Base = obj.Placement.multVec(v)
                else:
                    dangle = math.degrees(math.atan2(v[1], v[0]))
                    if node_idx == 1:
                        obj.FirstAngle = dangle
                    elif node_idx == 2:
                        obj.LastAngle = dangle
                    elif node_idx == 3:
                        obj.Radius = v.Length
Пример #33
0
def superWireReverse(debuglist,closed=False):
    '''superWireReverse(debuglist,[closed]): forces a wire between edges
    that don't necessarily have coincident endpoints. If closed=True, wire
    will always be closed. debuglist has a tuple for every edge.The first
    entry is the edge, the second is the flag 'does not nedd to be inverted'
    '''
    #taken from draftlibs
    def median(v1,v2):
        vd = v2.sub(v1)
        vd.scale(.5,.5,.5)
        return v1.add(vd)
    try:
        from DraftGeomUtils import findMidpoint
    except ImportError: #workaround for Version 0.12
        from draftlibs.fcgeo import findMidpoint #workaround for Version 0.12
    import Part
    #edges = sortEdges(edgeslist)
    print debuglist
    newedges = []
    for i in range(len(debuglist)):
        curr = debuglist[i]
        if i == 0:
            if closed:
                prev = debuglist[-1]
            else:
                prev = None
        else:
            prev = debuglist[i-1]
        if i == (len(debuglist)-1):
            if closed:
                nexte = debuglist[0]
            else:
                nexte = None
        else:
            nexte = debuglist[i+1]
        print i,prev,curr,nexte
        if prev:
            if curr[0].Vertexes[-1*(not curr[1])].Point == \
                    prev[0].Vertexes[-1*prev[1]].Point:
                p1 = curr[0].Vertexes[-1*(not curr[1])].Point
            else:
                p1 = median(curr[0].Vertexes[-1*(not curr[1])].Point,\
                        prev[0].Vertexes[-1*prev[1]].Point)
        else:
            p1 = curr[0].Vertexes[-1*(not curr[1])].Point
        if nexte:
            if curr[0].Vertexes[-1*curr[1]].Point == \
                nexte[0].Vertexes[-1*(not nexte[1])].Point:
                p2 = nexte[0].Vertexes[-1*(not nexte[1])].Point
            else:
                p2 = median(curr[0].Vertexes[-1*(curr[1])].Point,\
                        nexte[0].Vertexes[-1*(not nexte[1])].Point)
        else:
            p2 = curr[0].Vertexes[-1*(curr[1])].Point
        if isinstance(curr[0].Curve,(Part.LineSegment, Part.Line)):
            print "line",p1,p2
            newedges.append(Part.LineSegment(p1,p2).toShape())
        elif isinstance(curr[0].Curve,Part.Circle):
            p3 = findMidpoint(curr[0])
            print "arc",p1,p3,p2
            newedges.append(Part.Arc(p1,p3,p2).toShape())
        else:
            print "Cannot superWire edges that are not lines or arcs"
            return None
    print newedges
    return Part.Wire(newedges)
Пример #34
0
    def getCurveSet(ent):
        result = []
        if ent.is_a() in ["IfcGeometricCurveSet", "IfcGeometricSet"]:
            elts = ent.Elements
        elif ent.is_a() in [
                "IfcLine", "IfcPolyline", "IfcCircle", "IfcTrimmedCurve",
                "IfcRectangleProfileDef"
        ]:
            elts = [ent]
        else:
            print("getCurveSet: unhandled entity: ", ent)
            return []

        for el in elts:
            if el.is_a("IfcPolyline"):
                result.append(getPolyline(el))
            elif el.is_a("IfcRectangleProfileDef"):
                result.append(getRectangle(el))
            elif el.is_a("IfcLine"):
                result.append(getLine(el))
            elif el.is_a("IfcCircle"):
                result.append(getCircle(el))
            elif el.is_a("IfcTrimmedCurve"):
                base = el.BasisCurve
                t1 = el.Trim1[0].wrappedValue
                t2 = el.Trim2[0].wrappedValue
                if not el.SenseAgreement:
                    t1, t2 = t2, t1
                if base.is_a("IfcPolyline"):
                    bc = getPolyline(base)
                    result.append(bc)
                elif base.is_a("IfcCircle"):
                    bc = getCircle(base)
                    e = Part.ArcOfCircle(bc.Curve, math.radians(t1),
                                         math.radians(t2)).toShape()
                    d = base.Position.RefDirection.DirectionRatios
                    v = FreeCAD.Vector(d[0], d[1], d[2] if len(d) > 2 else 0)
                    a = -DraftVecUtils.angle(v)
                    e.rotate(bc.Curve.Center, FreeCAD.Vector(0, 0, 1),
                             math.degrees(a))
                    result.append(e)
            elif el.is_a("IfcCompositeCurve"):
                for base in el.Segments:
                    if base.ParentCurve.is_a("IfcPolyline"):
                        bc = getPolyline(base.ParentCurve)
                        result.append(bc)
                    elif base.ParentCurve.is_a("IfcCircle"):
                        bc = getCircle(base.ParentCurve)
                        e = Part.ArcOfCircle(bc.Curve, math.radians(t1),
                                             math.radians(t2)).toShape()
                        d = base.Position.RefDirection.DirectionRatios
                        v = FreeCAD.Vector(d[0], d[1],
                                           d[2] if len(d) > 2 else 0)
                        a = -DraftVecUtils.angle(v)
                        e.rotate(bc.Curve.Center, FreeCAD.Vector(0, 0, 1),
                                 math.degrees(a))
                        result.append(e)
            elif el.is_a("IfcIndexedPolyCurve"):
                coords = el.Points.CoordList

                def index2points(segment):
                    pts = []
                    for i in segment.wrappedValue:
                        c = coords[i - 1]
                        c = FreeCAD.Vector(c[0], c[1],
                                           c[2] if len(c) > 2 else 0)
                        c.multiply(scaling)
                        pts.append(c)
                    return pts

                for s in el.Segments:
                    if s.is_a("IfcLineIndex"):
                        result.append(Part.makePolygon(index2points(s)))
                    elif s.is_a("IfcArcIndex"):
                        [p1, p2, p3] = index2points(s)
                        result.append(Part.Arc(p1, p2, p3))
                    else:
                        raise RuntimeError(
                            "Illegal IfcIndexedPolyCurve segment")
            else:
                print("getCurveSet: unhandled element: ", el)

        return result
Пример #35
0
 def getCircle(ent):
     c = ent.Position.Location.Coordinates
     c = FreeCAD.Vector(c[0], c[1], c[2] if len(c) > 2 else 0)
     c.multiply(scaling)
     r = ent.Radius * scaling
     return Part.makeCircle(r, c)
Пример #36
0
 def getRectangle(ent):
     return Part.makePlane(ent.XDim, ent.YDim)
Пример #37
0
def createAnnotation(annotation, doc, ifcscale, preferences):
    """creates an annotation object"""

    anno = None
    if annotation.is_a("IfcGrid"):
        axes = []
        uvwaxes = ()
        if annotation.UAxes:
            uvwaxes = annotation.UAxes
        if annotation.VAxes:
            uvwaxes = uvwaxes + annotation.VAxes
        if annotation.WAxes:
            uvwaxes = uvwaxes + annotation.WAxes
        for axis in uvwaxes:
            if axis.AxisCurve:
                sh = get2DShape(axis.AxisCurve, ifcscale)
                if sh and (len(sh[0].Vertexes)
                           == 2):  # currently only straight axes are supported
                    sh = sh[0]
                    l = sh.Length
                    pl = FreeCAD.Placement()
                    pl.Base = sh.Vertexes[0].Point
                    pl.Rotation = FreeCAD.Rotation(
                        FreeCAD.Vector(0, 1, 0),
                        sh.Vertexes[-1].Point.sub(sh.Vertexes[0].Point))
                    o = Arch.makeAxis(1, l)
                    o.Length = l
                    o.Placement = pl
                    o.CustomNumber = axis.AxisTag
                    axes.append(o)
        if axes:
            name = "Grid"
            grid_placement = None
            if annotation.Name:
                name = annotation.Name
                if six.PY2:
                    name = name.encode("utf8")
            if annotation.ObjectPlacement:
                # https://forum.freecadweb.org/viewtopic.php?f=39&t=40027
                grid_placement = getPlacement(annotation.ObjectPlacement,
                                              scaling=1)
            if preferences['PREFIX_NUMBERS']:
                name = "ID" + str(aid) + " " + name
            anno = Arch.makeAxisSystem(axes, name)
            if grid_placement:
                anno.Placement = grid_placement
        print(" axis")
    else:
        name = "Annotation"
        if annotation.Name:
            name = annotation.Name
            if six.PY2:
                name = name.encode("utf8")
        if "annotation" not in name.lower():
            name = "Annotation " + name
        if preferences['PREFIX_NUMBERS']: name = "ID" + str(aid) + " " + name
        shapes2d = []
        for rep in annotation.Representation.Representations:
            if rep.RepresentationIdentifier in [
                    "Annotation", "FootPrint", "Axis"
            ]:
                sh = get2DShape(rep, ifcscale)
                if sh in doc.Objects:
                    # dirty hack: get2DShape might return an object directly if non-shape based (texts for ex)
                    anno = sh
                else:
                    shapes2d.extend(sh)
        if shapes2d:
            import Part
            sh = Part.makeCompound(shapes2d)
            #if preferences['DEBUG']: print(" shape")
            anno = doc.addObject("Part::Feature", name)
            anno.Shape = sh
            p = getPlacement(annotation.ObjectPlacement, ifcscale)
            if p:  # and annotation.is_a("IfcAnnotation"):
                anno.Placement = p
        #else:
        #if preferences['DEBUG']: print(" no shape")

    return anno
Пример #38
0
    def execute(self,obj):

        if self.clone(obj):
            return
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return
        if not obj.Diameter.Value:
            return
        if not obj.Amount:
            return
        father = obj.Host
        fathershape = None
        if not father:
            # support for old-style rebars
            if obj.InList:
                if hasattr(obj.InList[0],"Armatures"):
                    if obj in obj.InList[0].Armatures:
                        father = obj.InList[0]
        if father:
            if father.isDerivedFrom("Part::Feature"):
                fathershape = father.Shape

        wire = obj.Base.Shape.Wires[0]
        if hasattr(obj,"Rounding"):
            #print(obj.Rounding)
            if obj.Rounding:
                radius = obj.Rounding * obj.Diameter.Value
                import DraftGeomUtils
                wire = DraftGeomUtils.filletWire(wire,radius)
        bpoint, bvec = self.getBaseAndAxis(wire)
        if not bpoint:
            return
        axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,0,-1))
        if fathershape:
            size = (ArchCommands.projectToVector(fathershape.copy(),axis)).Length
        else:
            size = 1
        if hasattr(obj,"Direction"):
            if not DraftVecUtils.isNull(obj.Direction):
                axis = FreeCAD.Vector(obj.Direction)
                axis.normalize()
                if fathershape:
                    size = (ArchCommands.projectToVector(fathershape.copy(),axis)).Length
                else:
                    size = 1
        if hasattr(obj,"Distance"):
            if obj.Distance.Value:
                size = obj.Distance.Value
        #print(axis)
        #print(size)
        spacinglist = None
        if hasattr(obj, "CustomSpacing"):
            if obj.CustomSpacing:
                spacinglist = strprocessOfCustomSpacing(obj.CustomSpacing)
                influenceArea = sum(spacinglist) - spacinglist[0] / 2 - spacinglist[-1] / 2
        if (obj.OffsetStart.Value + obj.OffsetEnd.Value) > size:
            return
        # all tests ok!
        pl = obj.Placement
        import Part
        circle = Part.makeCircle(obj.Diameter.Value/2,bpoint,bvec)
        circle = Part.Wire(circle)
        try:
            bar = wire.makePipeShell([circle],True,False,2)
        except Part.OCCError:
            print("Arch: error sweeping rebar profile along the base sketch")
            return
        # building final shape
        shapes = []
        placementlist = []
        if father:
            rot = father.Placement.Rotation
        else:
            rot = FreeCAD.Rotation()
        if obj.Amount == 1:
            barplacement = CalculatePlacement(obj.Amount, 1, size, axis, rot, obj.OffsetStart.Value, obj.OffsetEnd.Value)
            placementlist.append(barplacement)
            if hasattr(obj,"Spacing"):
                obj.Spacing = 0
        else:
            if obj.OffsetStart.Value:
                baseoffset = DraftVecUtils.scaleTo(axis,obj.OffsetStart.Value)
            else:
                baseoffset = None
            interval = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            interval = interval / (obj.Amount - 1)
            for i in range(obj.Amount):
                barplacement = CalculatePlacement(obj.Amount, i+1, size, axis, rot, obj.OffsetStart.Value, obj.OffsetEnd.Value)
                placementlist.append(barplacement)
            if hasattr(obj,"Spacing"):
                obj.Spacing = interval
        # Calculate placement of bars from custom spacing.
        if spacinglist:
            placementlist[:] = []
            reqInfluenceArea = size - (obj.OffsetStart.Value + obj.OffsetEnd.Value)
            if influenceArea > reqInfluenceArea:
                return FreeCAD.Console.PrintError("Influence area of rebars is greater than "+ str(reqInfluenceArea) + ".\n")
            elif influenceArea < reqInfluenceArea:
                FreeCAD.Console.PrintWarning("Last span is greater that end offset.\n")
            for i in range(len(spacinglist)):
                if i == 0:
                    barplacement = CustomSpacingPlacement(spacinglist, 1, axis, father.Placement.Rotation, obj.OffsetStart.Value, obj.OffsetEnd.Value)
                    placementlist.append(barplacement)
                else:
                    barplacement = CustomSpacingPlacement(spacinglist, i+1, axis, father.Placement.Rotation, obj.OffsetStart.Value, obj.OffsetEnd.Value)
                    placementlist.append(barplacement)
            obj.Amount = len(spacinglist)
            obj.Spacing = 0
        obj.PlacementList = placementlist
        for i in range(len(obj.PlacementList)):
            if i == 0:
                bar.Placement = obj.PlacementList[i]
                shapes.append(bar)
            else:
                bar = bar.copy()
                bar.Placement = obj.PlacementList[i]
                shapes.append(bar)
        if shapes:
            obj.Shape = Part.makeCompound(shapes)
            obj.Placement = pl
 def Activated(self):
     document = App.ActiveDocument
     if not document:
         document = App.newDocument()
     box = Box.make()
     Part.show(box)
Пример #40
0
def positioning_test1():
  """ test the place_plank function
  """
  # test place_plank()
  #pp0 = test_plank()
  #Part.show(pp0)
  pp1 = place_plank(test_plank(), 20,4,2, 'i', 'xy', 300,0,0)
  Part.show(pp1)
  pp2 = place_plank(test_plank(), 20,4,2, 'x', 'xy', 300,30,0)
  Part.show(pp2)
  pp3 = place_plank(test_plank(), 20,4,2, 'y', 'xy', 300,60,0)
  Part.show(pp3)
  pp4 = place_plank(test_plank(), 20,4,2, 'z', 'xy', 300,90,0)
  Part.show(pp4)
  #pp4 = place_plank(test_plank(), 20,4,2, 'u', 'xy', 300,30,0)
  pp21 = place_plank(test_plank(), 20,4,2, 'i', 'xy', 350,0,0)
  Part.show(pp21)
  pp22 = place_plank(test_plank(), 20,4,2, 'i', 'xz', 350,30,0)
  Part.show(pp22)
  pp23 = place_plank(test_plank(), 20,4,2, 'i', 'yx', 350,60,0)
  Part.show(pp23)
  pp24 = place_plank(test_plank(), 20,4,2, 'i', 'yz', 350,90,0)
  Part.show(pp24)
  pp25 = place_plank(test_plank(), 20,4,2, 'i', 'zx', 350,120,0)
  Part.show(pp25)
  pp26 = place_plank(test_plank(), 20,4,2, 'i', 'zy', 350,150,0)
  Part.show(pp26)
  #pp27 = place_plank(test_plank(), 20,4,2, 'i', 'xx', 350,180,0)
  ##Part.show(pp1)
  r_test = 1
  return(r_test)
Пример #41
0
    def getCoG(self,
               fp,
               vol,
               roll=Units.parseQuantity("0 deg"),
               trim=Units.parseQuantity("0 deg")):
        """Return the fluid volume center of gravity, provided the volume of
        fluid inside the tank.

        The returned center of gravity is referred to the untransformed ship.

        Keyword arguments:
        fp -- Part::FeaturePython object affected.
        vol -- Volume of fluid.
        roll -- Ship roll angle.
        trim -- Ship trim angle.

        If the fluid volume is bigger than the total tank one, it will be
        conveniently clamped.
        """
        # Change the units of the volume, and clamp the value
        if vol <= 0.0:
            return Vector()
        if vol >= fp.Shape.Volume:
            vol = 0.0
            for solid in fp.Shape.Solids:
                vol += solid.Volume
                sCoG = solid.CenterOfMass
                cog.x = cog.x + sCoG.x * solid.Volume
                cog.y = cog.y + sCoG.y * solid.Volume
                cog.z = cog.z + sCoG.z * solid.Volume
            cog.x = cog.x / vol
            cog.y = cog.y / vol
            cog.z = cog.z / vol
            return cog

        # Get a first estimation of the level
        level = vol.Value / fp.Shape.Volume

        # Transform the tank shape
        current_placement = fp.Placement
        m = current_placement.toMatrix()
        m.rotateX(roll.getValueAs("rad"))
        m.rotateY(-trim.getValueAs("rad"))
        fp.Placement = Placement(m)

        # Iterate to find the fluid shape
        for i in range(COMMON_BOOLEAN_ITERATIONS):
            shape = self.getVolume(fp, level, return_shape=True)
            error = (vol.Value - shape.Volume) / fp.Shape.Volume
            if abs(error) < 0.01:
                break
            level += error

        # Get the center of gravity
        vol = 0.0
        cog = Vector()
        if len(shape.Solids) > 0:
            for solid in shape.Solids:
                vol += solid.Volume
                sCoG = solid.CenterOfMass
                cog.x = cog.x + sCoG.x * solid.Volume
                cog.y = cog.y + sCoG.y * solid.Volume
                cog.z = cog.z + sCoG.z * solid.Volume
            cog.x = cog.x / vol
            cog.y = cog.y / vol
            cog.z = cog.z / vol

        # Untransform the object to retrieve the original position
        fp.Placement = current_placement
        p = Part.Point(cog)
        m = Matrix()
        m.rotateY(trim.getValueAs("rad"))
        m.rotateX(-roll.getValueAs("rad"))
        p.rotate(Placement(m))

        return Vector(p.X, p.Y, p.Z)
Пример #42
0
    def getVolume(self, fp, level, return_shape=False):
        """Return the fluid volume inside the tank, provided the filling level.

        Keyword arguments:
        fp -- Part::FeaturePython object affected.
        level -- Percentage of filling level (interval [0, 1]).
        return_shape -- False if the tool should return the fluid volume value,
        True if the tool should return the volume shape.
        """
        if level <= 0.0:
            if return_shape:
                return Part.Vertex()
            return Units.Quantity(0.0, Units.Volume)
        if level >= 1.0:
            if return_shape:
                return fp.Shape.copy()
            return Units.Quantity(fp.Shape.Volume, Units.Volume)

        # Build up the cutting box
        bbox = fp.Shape.BoundBox
        dx = bbox.XMax - bbox.XMin
        dy = bbox.YMax - bbox.YMin
        dz = bbox.ZMax - bbox.ZMin

        box = App.ActiveDocument.addObject("Part::Box", "Box")
        length_format = USys.getLengthFormat()
        box.Placement = Placement(
            Vector(bbox.XMin - dx, bbox.YMin - dy, bbox.ZMin - dz),
            Rotation(App.Vector(0, 0, 1), 0))
        box.Length = length_format.format(3.0 * dx)
        box.Width = length_format.format(3.0 * dy)
        box.Height = length_format.format((1.0 + level) * dz)

        # Create a new object on top of a copy of the tank shape
        Part.show(fp.Shape.copy())
        tank = App.ActiveDocument.Objects[-1]

        # Compute the common boolean operation
        App.ActiveDocument.recompute()
        common = App.activeDocument().addObject("Part::MultiCommon",
                                                "TankVolHelper")
        common.Shapes = [tank, box]
        App.ActiveDocument.recompute()
        if len(common.Shape.Solids) == 0:
            # The common operation is failing, let's try moving a bit the free
            # surface
            msg = QtGui.QApplication.translate(
                "ship_console",
                "Tank volume operation failed. The tool is retrying that"
                " slightly moving the free surface position", None)
            App.Console.PrintWarning(msg + '\n')
            rand_bounds = 0.01 * dz
            i = 0
            while len(common.Shape.Solids
                      ) == 0 and i < COMMON_BOOLEAN_ITERATIONS:
                i += 1
                box.Height = length_format.format(
                    (1.0 + level) * dz +
                    random.uniform(-random_bounds, random_bounds))
                App.ActiveDocument.recompute()

        if return_shape:
            ret_value = common.Shape.copy()
        else:
            ret_value = Units.Quantity(common.Shape.Volume, Units.Volume)

        App.ActiveDocument.removeObject(common.Name)
        App.ActiveDocument.removeObject(tank.Name)
        App.ActiveDocument.removeObject(box.Name)
        App.ActiveDocument.recompute()

        return ret_value
Пример #43
0
    def draw(self):

        try:
            Gui.getDocument(self.name)
            Gui.getDocument(self.name).resetEdit()
            App.getDocument(self.name).recompute()
            App.closeDocument(self.name)
            App.setActiveDocument("")
            App.ActiveDocument = None
            Gui.ActiveDocument = None
        except:
            pass

        #make document
        App.newDocument(self.name)
        App.setActiveDocument(self.name)
        App.ActiveDocument = App.getDocument(self.name)
        Gui.ActiveDocument = Gui.getDocument(self.name)

        #Make profile of angle and extrude it
        p1x = -gv.extruderMountPlateWidth / 2
        p1y = 0
        p2x = p1x
        p2y = gv.extruderDepth
        p3x = -p1x
        p3y = p2y
        p4x = p3x
        p4y = p1y

        #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.000000, 0.000000, 0.000000, 1.000000))
        Gui.activeDocument().activeView().setCamera(
            '#Inventor V2.1 ascii \n OrthographicCamera {\n viewportMapping ADJUST_CAMERA \n position 0 0 87 \n orientation 0 0 1  0 \n nearDistance -112.88701 \n farDistance 287.28702 \n aspectRatio 1 \n focalDistance 87 \n height 143.52005 }'
        )
        #		Gui.activeDocument().setEdit('Sketch')
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p4x, p4y, 0)))
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p3x, p3y, 0)))
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p2x, p2y, 0)))
        App.ActiveDocument.Sketch.addGeometry(
            Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p1x, p1y, 0)))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 0, 2, 1, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 1, 2, 2, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 2, 2, 3, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Coincident', 3, 2, 0, 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Horizontal', 0))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Horizontal', 2))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Vertical', 1))
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Vertical', 3))
        App.ActiveDocument.recompute()

        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('PointOnObject', 0, 1, -1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('Symmetric', 0, 2, 0, 1, -1, 1))
        App.ActiveDocument.recompute()

        #Add dimensions
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('DistanceY', 1, gv.extruderDepth))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch.addConstraint(
            Sketcher.Constraint('DistanceX', 0, gv.extruderMountPlateWidth))
        App.ActiveDocument.recompute()
        #		Gui.getDocument(self.name).resetEdit()
        App.getDocument(self.name).recompute()

        #Pad extruderMountPlate
        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.extruderMountPlateThickness
        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()
        #		Gui.activeDocument().resetEdit()

        #Make holes for mounting plate to angle
        #Sketch Points
        p1x = gv.extruderMountPlateWidth
        p1y = (gv.extruderMountAngleWidth + gv.extruderMountAngleThickness) / 2
        p2x = -gv.xCarriageWidth / 2 + gv.xCarriageMountHoleHorizOffset
        p2y = p1y
        p3x = -p2x
        p3y = p1y
        p4x = -p1x
        p4y = p1y

        App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch001')
        App.activeDocument().Sketch001.Support = uf.getFace(
            App.ActiveDocument.Pad, None, None, None, None,
            gv.extruderMountPlateThickness,
            0)  #(App.ActiveDocument.Pad,["Face6"])
        App.activeDocument().recompute()
        #		Gui.activeDocument().setEdit('Sketch001')
        #		App.ActiveDocument.Sketch001.addExternal("Pad","Edge12")
        App.ActiveDocument.Sketch001.addExternal(
            "Pad",
            uf.getEdge(App.ActiveDocument.Pad, -gv.extruderMountPlateWidth / 2,
                       0, None, None, gv.extruderMountPlateThickness, 0))

        App.ActiveDocument.Sketch001.addExternal(
            "Pad",
            uf.getEdge(App.ActiveDocument.Pad, gv.extruderMountPlateWidth / 2,
                       0, None, None, gv.extruderMountPlateThickness, 0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addGeometry(
            Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0)))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('PointOnObject', 0, 1, -3))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Horizontal', 0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addGeometry(
            Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p3x, p3y, 0)))
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Coincident', 0, 2, 1, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Horizontal', 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addGeometry(
            Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p4x, p4y, 0)))
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Coincident', 1, 2, 2, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('PointOnObject', 2, 2, -4))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Horizontal', 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Equal', 2, 0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.toggleConstruction(0)
        App.ActiveDocument.Sketch001.toggleConstruction(1)
        App.ActiveDocument.Sketch001.toggleConstruction(2)
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addGeometry(
            Part.Circle(App.Vector(p2x, p2y, 0), App.Vector(0, 0, 1),
                        gv.mountToPrintedDia / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Coincident', 3, 3, 0, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addGeometry(
            Part.Circle(App.Vector(p3x, p3y, 0), App.Vector(0, 0, 1),
                        gv.mountToPrintedDia / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Coincident', 4, 3, 1, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Equal', 4, 3))
        App.ActiveDocument.recompute()

        #Add dimensions
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint('Radius', 4, gv.mountToPrintedDia / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint(
                'DistanceX', 0, 2, 0, 1,
                -(gv.extruderMountPlateWidth / 2 - gv.xCarriageWidth / 2 +
                  gv.xCarriageMountHoleHorizOffset)))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch001.addConstraint(
            Sketcher.Constraint(
                'DistanceY', -1, 1, 0, 2,
                (gv.extruderMountAngleWidth + gv.extruderMountAngleThickness) /
                2))
        App.ActiveDocument.recompute()
        #		Gui.getDocument(self.name).resetEdit()
        App.getDocument(self.name).recompute()

        #Cut the holes
        App.activeDocument().addObject("PartDesign::Pocket", "Pocket")
        App.activeDocument().Pocket.Sketch = App.activeDocument().Sketch001
        App.activeDocument().Pocket.Length = 5.0
        App.ActiveDocument.recompute()
        Gui.activeDocument().hide("Sketch001")
        Gui.activeDocument().hide("Pad")
        #		Gui.activeDocument().setEdit('Pocket')
        #		Gui.ActiveDocument.Pocket.ShapeColor=Gui.ActiveDocument.Pad.ShapeColor
        #		Gui.ActiveDocument.Pocket.LineColor=Gui.ActiveDocument.Pad.LineColor
        #		Gui.ActiveDocument.Pocket.PointColor=Gui.ActiveDocument.Pad.PointColor
        App.ActiveDocument.Pocket.Length = 5.000000
        App.ActiveDocument.Pocket.Type = 1
        App.ActiveDocument.Pocket.UpToFace = None
        App.ActiveDocument.recompute()
        #		Gui.activeDocument().resetEdit()

        #make holes for mounting the extruder
        #Sketch Points
        p1x = -gv.extruderMountPlateWidth / 2
        p1y = gv.extruderDepth - gv.extruderEdgeToCenterLine
        p2x = -gv.extruderMountHoleSpacing / 2
        p2y = p1y
        p3x = 0
        p3y = p1y
        p4x = -p2x
        p4y = p1y
        p5x = -p1x
        p5y = p1y

        #Make Sketch
        App.activeDocument().addObject('Sketcher::SketchObject', 'Sketch002')
        App.activeDocument().Sketch002.Support = uf.getFace(
            App.ActiveDocument.Pocket, None, None, None, None,
            gv.extruderMountPlateThickness,
            0)  #(App.ActiveDocument.Pocket,["Face5"])
        App.activeDocument().recompute()
        #		Gui.activeDocument().setEdit('Sketch002')

        App.ActiveDocument.Sketch002.addExternal(
            "Pocket",
            uf.getEdge(App.ActiveDocument.Pocket,
                       -gv.extruderMountPlateWidth / 2, 0, None, None,
                       gv.extruderMountPlateThickness, 0))

        App.ActiveDocument.Sketch002.addExternal(
            "Pocket",
            uf.getEdge(App.ActiveDocument.Pocket,
                       gv.extruderMountPlateWidth / 2, 0, None, None,
                       gv.extruderMountPlateThickness, 0))
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0)))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('PointOnObject', 0, 1, -3))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Horizontal', 0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Line(App.Vector(p2x, p2y, 0), App.Vector(p3x, p3y, 0)))
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Coincident', 0, 2, 1, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('PointOnObject', 1, 2, -2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Horizontal', 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Line(App.Vector(p3x, p3y, 0), App.Vector(p4x, p4y, 0)))
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Coincident', 1, 2, 2, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Horizontal', 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Line(App.Vector(p4x, p4y, 0), App.Vector(p5x, p5y, 0)))
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Coincident', 2, 2, 3, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('PointOnObject', 3, 2, -4))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Horizontal', 3))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Equal', 3, 0))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Equal', 2, 1))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.toggleConstruction(0)
        App.ActiveDocument.Sketch002.toggleConstruction(1)
        App.ActiveDocument.Sketch002.toggleConstruction(2)
        App.ActiveDocument.Sketch002.toggleConstruction(3)
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Circle(App.Vector(p2x, p2y, 0), App.Vector(0, 0, 1),
                        gv.extruderMountHoleDia / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Coincident', 4, 3, 0, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Circle(App.Vector(p4x, p4y, 0), App.Vector(0, 0, 1),
                        gv.extruderMountHoleDia / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Coincident', 5, 3, 2, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addGeometry(
            Part.Circle(App.Vector(p3x, p3y, 0), App.Vector(0, 0, 1),
                        gv.extruderFilamentHoleDia / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Coincident', 6, 3, 1, 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Equal', 4, 5))
        App.ActiveDocument.recompute()

        #Add Dimensions
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('DistanceX', 0, 2, 2, 2,
                                gv.extruderMountHoleSpacing))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('DistanceY', 3, 2, -4, 2,
                                gv.extruderEdgeToCenterLine))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Radius', 4, gv.extruderMountHoleDia / 2))
        App.ActiveDocument.recompute()
        App.ActiveDocument.Sketch002.addConstraint(
            Sketcher.Constraint('Radius', 6, gv.extruderFilamentHoleDia / 2))
        App.ActiveDocument.recompute()
        #		Gui.getDocument(self.name).resetEdit()
        App.getDocument(self.name).recompute()

        #Cut holes through all
        App.activeDocument().addObject("PartDesign::Pocket", "Pocket001")
        App.activeDocument().Pocket001.Sketch = App.activeDocument().Sketch002
        App.activeDocument().Pocket001.Length = 5.0
        App.ActiveDocument.recompute()
        Gui.activeDocument().hide("Sketch002")
        Gui.activeDocument().hide("Pocket")
        #		Gui.ActiveDocument.Pocket001.ShapeColor=Gui.ActiveDocument.Pocket.ShapeColor
        #		Gui.ActiveDocument.Pocket001.LineColor=Gui.ActiveDocument.Pocket.LineColor
        #		Gui.ActiveDocument.Pocket001.PointColor=Gui.ActiveDocument.Pocket.PointColor
        App.ActiveDocument.Pocket001.Length = 5.000000
        App.ActiveDocument.Pocket001.Type = 1
        App.ActiveDocument.Pocket001.UpToFace = None
        App.ActiveDocument.recompute()
        #		Gui.activeDocument().resetEdit()

        #Cut holes for hot end mount if needed.
        if self.hotEndMountHoles:
            #Sketch Points
            p1x = -gv.hotEndMountHoleSpacing / 2
            p1y = gv.extruderDepth - gv.extruderEdgeToCenterLine
            p2x = -p1x
            p2y = p1y

            #Make Sketch
            App.activeDocument().addObject('Sketcher::SketchObject',
                                           'Sketch003')
            App.activeDocument().Sketch003.Support = uf.getFace(
                App.ActiveDocument.Pocket001, None, None, None, None,
                gv.extruderMountPlateThickness,
                0)  #(App.ActiveDocument.Pocket001,["Face5"])
            App.activeDocument().recompute()
            #		Gui.activeDocument().setEdit('Sketch003')
            App.ActiveDocument.Sketch003.addGeometry(
                Part.Line(App.Vector(p1x, p1y, 0), App.Vector(p2x, p2y, 0)))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('Horizontal', 0))
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('Symmetric', 0, 1, 0, 2, -2))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.toggleConstruction(0)
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addGeometry(
                Part.Circle(App.Vector(p1x, p1y, 0), App.Vector(0, 0, 1),
                            gv.hotEndMountHoleDia / 2))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('Coincident', 1, 3, 0, 1))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addGeometry(
                Part.Circle(App.Vector(p2x, p2y, 0), App.Vector(0, 0, 1),
                            gv.hotEndMountHoleDia / 2))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('Coincident', 2, 3, 0, 2))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('Equal', 1, 2))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('Radius', 2, gv.hotEndMountHoleDia / 2))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('DistanceX', 0, gv.hotEndMountHoleSpacing))
            App.ActiveDocument.recompute()
            App.ActiveDocument.Sketch003.addConstraint(
                Sketcher.Constraint('Distance', -1, 1, 0, p1y))

            #		Gui.getDocument(self.name).resetEdit()
            App.getDocument(self.name).recompute()

            #Cut hole Through All
            App.activeDocument().addObject("PartDesign::Pocket", "Pocket002")
            App.activeDocument().Pocket002.Sketch = App.activeDocument(
            ).Sketch003
            App.activeDocument().Pocket002.Length = 5.0
            App.ActiveDocument.recompute()
            Gui.activeDocument().hide("Sketch003")
            Gui.activeDocument().hide("Pocket001")
            #		Gui.ActiveDocument.Pocket002.ShapeColor=Gui.ActiveDocument.Pocket001.ShapeColor
            #		Gui.ActiveDocument.Pocket002.LineColor=Gui.ActiveDocument.Pocket001.LineColor
            #		Gui.ActiveDocument.Pocket002.PointColor=Gui.ActiveDocument.Pocket001.PointColor
            App.ActiveDocument.Pocket002.Length = 5.000000
            App.ActiveDocument.Pocket002.Type = 1
            App.ActiveDocument.Pocket002.UpToFace = None
            App.ActiveDocument.recompute()
Пример #44
0
"""Creates a circuit for testing"""
import Part as part
import RecognitionSite as rs
import GeneticCircuit as gc
import Enzyme as enz

import copy

import unittest

##SETUP
##Create the parts
part1 = part.Part(1, 1)
site1 = rs.RecognitionSite('D', 1)
part2 = part.Part(2, 1)
site2 = rs.RecognitionSite('[', 1)
part3 = part.Part(3, 1)
site3 = rs.RecognitionSite('(', 1)
part4 = part.Part(4,1)
site4 = rs.RecognitionSite('[', -1)
part5 = part.Part(5, 1)
site5 = rs.RecognitionSite('(', 1)
part6 = part.Part(6, 1)
site6 = rs.RecognitionSite('D', -1)
part7 = part.Part(7,1)

##Create the enzymes
enzyme1 = enz.Enzyme('Ara')
enzyme1.addSiteToRecognize('[')
enzyme1.addSiteToRecognize('D')
enzyme2 = enz.Enzyme('ATc')
Пример #45
0
    def execute(self, obj):
        import Part
        # import OpenSCAD2Dgeom
        import os
        if obj.String and obj.FontFile:
            if obj.Placement:
                plm = obj.Placement
            ff8 = obj.FontFile.encode('utf8')  # 1947 accents in filepath
            # TODO: change for Py3?? bytes?
            # Part.makeWireString uses FontFile as char* string
            if sys.version_info.major < 3:
                CharList = Part.makeWireString(obj.String, ff8, obj.Size,
                                               obj.Tracking)
            else:
                CharList = Part.makeWireString(obj.String, obj.FontFile,
                                               obj.Size, obj.Tracking)
            if len(CharList) == 0:
                App.Console.PrintWarning(
                    translate("draft", "ShapeString: string has no wires") +
                    "\n")
                return
            SSChars = []

            # test a simple letter to know if we have a sticky font or not
            sticky = False
            if sys.version_info.major < 3:
                testWire = Part.makeWireString("L", ff8, obj.Size,
                                               obj.Tracking)[0][0]
            else:
                testWire = Part.makeWireString("L", obj.FontFile, obj.Size,
                                               obj.Tracking)[0][0]
            if testWire.isClosed:
                try:
                    testFace = Part.Face(testWire)
                except Part.OCCError:
                    sticky = True
                else:
                    if not testFace.isValid():
                        sticky = True
            else:
                sticky = True

            for char in CharList:
                if sticky:
                    for CWire in char:
                        SSChars.append(CWire)
                else:
                    CharFaces = []
                    for CWire in char:
                        f = Part.Face(CWire)
                        if f:
                            CharFaces.append(f)
                    # whitespace (ex: ' ') has no faces. This breaks OpenSCAD2Dgeom...
                    if CharFaces:
                        # s = OpenSCAD2Dgeom.Overlappingfaces(CharFaces).makeshape()
                        # s = self.makeGlyph(CharFaces)
                        s = self.makeFaces(char)
                        SSChars.append(s)
            shape = Part.Compound(SSChars)
            obj.Shape = shape
            if plm:
                obj.Placement = plm
        obj.positionBySupport()
Пример #46
0
 def onChanged(self, vobj, prop):
     if prop == "LineColor":
         l = vobj.LineColor
         self.mat.diffuseColor.setValue([l[0],l[1],l[2]])
     elif prop == "DrawStyle":
         if vobj.DrawStyle == "Solid":
             self.linestyle.linePattern = 0xffff
         elif vobj.DrawStyle == "Dashed":
             self.linestyle.linePattern = 0xf00f
         elif vobj.DrawStyle == "Dotted":
             self.linestyle.linePattern = 0x0f0f
         else:
             self.linestyle.linePattern = 0xff88
     elif prop == "LineWidth":
             self.linestyle.lineWidth = vobj.LineWidth
     elif prop in ["BubbleSize","BubblePosition","FontName","FontSize"]:
         if hasattr(self,"bubbleset"):
             if self.bubbles:
                 self.bubbleset.removeChild(self.bubbles)
                 self.bubbles = None
             if vobj.Object.Shape:
                 if vobj.Object.Shape.Edges:
                     self.bubbles = coin.SoSeparator()
                     self.bubblestyle = coin.SoDrawStyle()
                     self.bubblestyle.linePattern = 0xffff
                     self.bubbles.addChild(self.bubblestyle)
                     import Part,Draft
                     self.bubbletexts = []
                     pos = ["Start"]
                     if hasattr(vobj,"BubblePosition"):
                         if vobj.BubblePosition == "Both":
                             pos = ["Start","End"]
                         else:
                             pos = [vobj.BubblePosition]
                     for i in range(len(vobj.Object.Shape.Edges)):
                         for p in pos:
                             verts = vobj.Object.Shape.Edges[i].Vertexes
                             if p == "Start":
                                 p1 = verts[0].Point
                                 p2 = verts[1].Point
                             else:
                                 p1 = verts[1].Point
                                 p2 = verts[0].Point
                             dv = p2.sub(p1)
                             dv.normalize()
                             if hasattr(vobj.BubbleSize,"Value"):
                                 rad = vobj.BubbleSize.Value/2
                             else:
                                 rad = vobj.BubbleSize/2
                             center = p2.add(dv.scale(rad,rad,rad))
                             buf = Part.makeCircle(rad,center).writeInventor()
                             try:
                                 cin = coin.SoInput()
                                 cin.setBuffer(buf)
                                 cob = coin.SoDB.readAll(cin)
                             except:
                                 import re
                                 # workaround for pivy SoInput.setBuffer() bug
                                 buf = buf.replace("\n","")
                                 pts = re.findall("point \[(.*?)\]",buf)[0]
                                 pts = pts.split(",")
                                 pc = []
                                 for p in pts:
                                     v = p.strip().split()
                                     pc.append([float(v[0]),float(v[1]),float(v[2])])
                                 coords = coin.SoCoordinate3()
                                 coords.point.setValues(0,len(pc),pc)
                                 line = coin.SoLineSet()
                                 line.numVertices.setValue(-1)
                             else:
                                 coords = cob.getChild(1).getChild(0).getChild(2)
                                 line = cob.getChild(1).getChild(0).getChild(3)
                             self.bubbles.addChild(coords)
                             self.bubbles.addChild(line)
                             st = coin.SoSeparator()
                             tr = coin.SoTransform()
                             fs = rad*1.5
                             if hasattr(vobj,"FontSize"):
                                 fs = vobj.FontSize.Value
                             tr.translation.setValue((center.x,center.y-fs/2.5,center.z))
                             fo = coin.SoFont()
                             fn = Draft.getParam("textfont","Arial,Sans")
                             if hasattr(vobj,"FontName"):
                                 if vobj.FontName:
                                     try:
                                         fn = str(vobj.FontName)
                                     except:
                                         pass
                             fo.name = fn
                             fo.size = fs
                             tx = coin.SoAsciiText()
                             tx.justification = coin.SoText2.CENTER
                             self.bubbletexts.append(tx)
                             st.addChild(tr)
                             st.addChild(fo)
                             st.addChild(tx)
                             self.bubbles.addChild(st)
                     self.bubbleset.addChild(self.bubbles)
                     self.onChanged(vobj,"NumberingStyle")
     elif prop in ["NumberingStyle","StartNumber"]:
         if hasattr(self,"bubbletexts"):
             chars = "abcdefghijklmnopqrstuvwxyz"
             roman=(('M',1000),('CM',900),('D',500),('CD',400),
                    ('C',100),('XC',90),('L',50),('XL',40),
                    ('X',10),('IX',9),('V',5),('IV',4),('I',1))
             num = 0
             if hasattr(vobj,"StartNumber"):
                 if vobj.StartNumber > 1:
                     num = vobj.StartNumber-1
             alt = False
             for t in self.bubbletexts:
                 if hasattr(vobj,"NumberingStyle"):
                     if vobj.NumberingStyle == "1,2,3":
                         t.string = str(num+1)
                     elif vobj.NumberingStyle == "01,02,03":
                         t.string = str(num+1).zfill(2)
                     elif vobj.NumberingStyle == "001,002,003":
                         t.string = str(num+1).zfill(3)
                     elif vobj.NumberingStyle == "A,B,C":
                         result = ""
                         base = num/26
                         if base:
                             result += chars[base].upper()
                         remainder = num % 26
                         result += chars[remainder].upper()
                         t.string = result
                     elif vobj.NumberingStyle == "a,b,c":
                         result = ""
                         base = num/26
                         if base:
                             result += chars[base]
                         remainder = num % 26
                         result += chars[remainder]
                         t.string = result
                     elif vobj.NumberingStyle == "I,II,III":
                         result = ""
                         n = num
                         n += 1
                         for numeral, integer in roman:
                             while n >= integer:
                                 result += numeral
                                 n -= integer
                         t.string = result
                     elif vobj.NumberingStyle == "L0,L1,L2":
                         t.string = "L"+str(num)
                 else:
                     t.string = str(num+1)
                 num += 1
                 if hasattr(vobj,"BubblePosition"):
                     if vobj.BubblePosition == "Both":
                         if not alt:
                             num -= 1
                 alt = not alt
Пример #47
0
def getSVG(section,
           allOn=False,
           renderMode="Wireframe",
           showHidden=False,
           showFill=False,
           scale=1,
           linewidth=1,
           fontsize=1):
    """getSVG(section,[allOn,renderMode,showHidden,showFill,scale,linewidth,fontsize]) : 
    returns an SVG fragment from an Arch section plane. If
    allOn is True, all cut objects are shown, regardless if they are visible or not.
    renderMode can be Wireframe (default) or Solid to use the Arch solid renderer. If
    showHidden is True, the hidden geometry above the section plane is shown in dashed line.
    If showFill is True, the cut areas get filled with a pattern"""

    if not section.Objects:
        return
    import DraftGeomUtils
    p = FreeCAD.Placement(section.Placement)
    direction = p.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    objs = Draft.getGroupContents(section.Objects, walls=True, addgroups=True)
    if not allOn:
        objs = Draft.removeHidden(objs)
    # separate spaces
    spaces = []
    nonspaces = []
    for o in objs:
        if Draft.getType(o) == "Space":
            spaces.append(o)
        else:
            nonspaces.append(o)
    objs = nonspaces
    svg = ''
    fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
    fillpattern += ' x="0" y="0" width="10" height="10">'
    fillpattern += '<g>'
    fillpattern += '<rect width="10" height="10" style="stroke:none; fill:#ffffff" /><path style="stroke:#000000; stroke-width:1" d="M0,0 l10,10" /></g></pattern>'

    # generating SVG
    if renderMode == "Solid":
        # render using the Arch Vector Renderer
        import ArchVRM, WorkingPlane
        wp = WorkingPlane.plane()
        wp.setFromPlacement(section.Placement)
        #wp.inverse()
        render = ArchVRM.Renderer()
        render.setWorkingPlane(wp)
        render.addObjects(objs)
        if showHidden:
            render.cut(section.Shape, showHidden)
        else:
            render.cut(section.Shape)
        svg += '<g transform="scale(1,-1)">\n'
        svg += render.getViewSVG(linewidth="LWPlaceholder")
        svg += fillpattern
        svg += render.getSectionSVG(linewidth="SWPlaceholder",
                                    fillpattern="sectionfill")
        if showHidden:
            svg += render.getHiddenSVG(linewidth="LWPlaceholder")
        svg += '</g>\n'
        # print render.info()

    else:
        # render using the Drawing module
        import Drawing, Part
        shapes = []
        hshapes = []
        sshapes = []
        for o in objs:
            if o.isDerivedFrom("Part::Feature"):
                if o.Shape.isNull():
                    pass
                elif o.Shape.isValid():
                    if section.OnlySolids:
                        shapes.extend(o.Shape.Solids)
                    else:
                        shapes.append(o.Shape)
                else:
                    print section.Label, ": Skipping invalid object:", o.Label
        cutface, cutvolume, invcutvolume = ArchCommands.getCutVolume(
            section.Shape.copy(), shapes)
        if cutvolume:
            nsh = []
            for sh in shapes:
                for sol in sh.Solids:
                    if sol.Volume < 0:
                        sol.reverse()
                    c = sol.cut(cutvolume)
                    s = sol.section(cutface)
                    try:
                        wires = DraftGeomUtils.findWires(s.Edges)
                        for w in wires:
                            f = Part.Face(w)
                            sshapes.append(f)
                        #s = Part.Wire(s.Edges)
                        #s = Part.Face(s)
                    except Part.OCCError:
                        #print "ArchDrawingView: unable to get a face"
                        sshapes.append(s)
                    nsh.extend(c.Solids)
                    #sshapes.append(s)
                    if showHidden:
                        c = sol.cut(invcutvolume)
                        hshapes.append(c)
            shapes = nsh
        if shapes:
            baseshape = Part.makeCompound(shapes)
            svgf = Drawing.projectToSVG(baseshape, direction)
            if svgf:
                svgf = svgf.replace('stroke-width="0.35"',
                                    'stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width="1"',
                                    'stroke-width="LWPlaceholder"')
                svgf = svgf.replace('stroke-width:0.01',
                                    'stroke-width:LWPlaceholder')
                svg += svgf
        if hshapes:
            hshapes = Part.makeCompound(hshapes)
            svgh = Drawing.projectToSVG(hshapes, direction)
            if svgh:
                svgh = svgh.replace('stroke-width="0.35"',
                                    'stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width="1"',
                                    'stroke-width="LWPlaceholder"')
                svgh = svgh.replace('stroke-width:0.01',
                                    'stroke-width:LWPlaceholder')
                svgh = svgh.replace(
                    'fill="none"',
                    'fill="none"\nstroke-dasharray="DAPlaceholder"')
                svg += svgh
        if sshapes:
            svgs = ""
            if showFill:
                svgs += fillpattern
                svgs += '<g transform="rotate(180)">\n'
                for s in sshapes:
                    if s.Edges:
                        f = Draft.getSVG(s,
                                         direction=direction.negative(),
                                         linewidth=0,
                                         fillstyle="sectionfill",
                                         color=(0, 0, 0))
                        svgs += f
                svgs += "</g>\n"
            sshapes = Part.makeCompound(sshapes)
            svgs += Drawing.projectToSVG(sshapes, direction)
            if svgs:
                svgs = svgs.replace('stroke-width="0.35"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width="1"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.01',
                                    'stroke-width:SWPlaceholder')
                svgs = svgs.replace('stroke-width="0.35 px"',
                                    'stroke-width="SWPlaceholder"')
                svgs = svgs.replace('stroke-width:0.35',
                                    'stroke-width:SWPlaceholder')
                svg += svgs

    linewidth = linewidth / scale
    st = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch").GetFloat(
            "CutLineThickness", 2)
    da = FreeCAD.ParamGet(
        "User parameter:BaseApp/Preferences/Mod/Arch").GetString(
            "archHiddenPattern", "30,10")
    da = da.replace(" ", "")
    svg = svg.replace('LWPlaceholder', str(linewidth) + 'px')
    svg = svg.replace('SWPlaceholder', str(linewidth * st) + 'px')
    svg = svg.replace('DAPlaceholder', str(da))
    if spaces and round(
            direction.getAngle(FreeCAD.Vector(0, 0, 1)),
            Draft.precision()) in [0, round(math.pi, Draft.precision())]:
        svg += '<g transform="scale(1,-1)">'
        for s in spaces:
            svg += Draft.getSVG(s,
                                scale=scale,
                                fontsize=fontsize,
                                direction=direction)
        svg += '</g>'
    # print "complete node:",svg
    return svg
Пример #48
0
 def getDeviation(self):
     """returns a deviation vector that represents the base of the circle"""
     import Part
     c = Part.makeCircle(1, Vector(0, 0, 0), self.normal)
     return c.Vertexes[0].Point
Пример #49
0
 def asEdge(self):
     return Part.Edge(self.asLine())
def export_mesh(filename,
                meshobj=None,
                isDiel=False,
                showNormals=False,
                folder=DEF_FOLDER):
    '''export mesh in FasterCap format as conductor or dielectric interface
    
    'filename' is the name of the export file
    'meshobj' must be a Mesh::Feature object
    'isDiel' specifies if the mesh is a dielectric, so the function will add 
        a reference point to each panel to indicate which is the external side (outside)
    'showNormals' will add a compound object composed by a set of arrows showing the 
        normal direction for each panel
    'folder' is the folder in which 'filename' will be saved
    
    Example:
    mymeshGui = Gui.ActiveDocument.Mesh
    mymeshObj = mymeshGui.Object
    export_mesh("mymesh.txt", meshobj=mymeshObj, folder="C:/temp")
'''

    # if no valid mesh was passed
    if meshobj == None:
        return
    elif meshobj.TypeId != "Mesh::Feature":
        FreeCAD.Console.PrintMessage(
            "Error: 'meshobj' is not an object of type 'Mesh::Feature'")
        return

    if not os.path.isdir(folder):
        os.mkdir(folder)

    with open(folder + os.sep + filename, 'w') as fid:
        # write the preamble
        if isDiel == True:
            fid.write("0 dielectric definition file for mesh '" +
                      meshobj.Label)
        else:
            fid.write("0 conductor definition file for mesh '" + meshobj.Label)
        fid.write("' created using FreeCAD's ElectroMagnetic workbench\n")
        fid.write(
            "* see http://www.freecad.org and http://www.fastfieldsolvers.com\n"
        )
        fid.write("\n")
        # export facets
        arrows = []
        condName = meshobj.Label.replace(" ", "_")
        for facet in meshobj.Mesh.Facets:
            if len(facet.Points) == 3:
                fid.write("T " + condName)
            elif len(facet.Points) == 4:
                fid.write("Q " + condName)
            else:
                FreeCAD.Console.PrintMessage(
                    "Unforseen number of mesh facet points: " +
                    len(facet.Points) + ", skipping facet")
                continue
            center = Vector(0.0, 0.0, 0.0)
            avgSideLen = 0.0
            for j, point in enumerate(facet.Points):
                fid.write(" ")
                for i in range(3):
                    fid.write(" " + str(point[i]))
                if isDiel == True or showNormals == True:
                    # 'point' is a tuple, transform in vector
                    center = center + Vector(point)
                    # get side length
                    side = Vector(facet.Points[(j + 1) % 3]) - Vector(point)
                    avgSideLen += side.Length
            if isDiel == True or showNormals == True:
                # calculate the reference point
                # (there should be a better way to divide a vector by a scalar..)
                center.multiply(1.0 / len(facet.Points))
                # and now move along the normal, proportional to the average facet dimension
                scaledNormal = Vector(facet.Normal)
                scaledNormal.multiply(avgSideLen / len(facet.Points))
                refpoint = center + scaledNormal
                if isDiel == True:
                    fid.write(" ")
                    for i in range(3):
                        fid.write(" " + str(refpoint[i]))
            fid.write("\n")
            if showNormals == True:
                arrows.append(make_arrow(center, refpoint))

        if showNormals == True:
            # add the vector normals visualization to the view
            # Note: could also use Part.show(normals) but in this case we could
            # not give the (permanent) name to the object, only change the label afterwards
            normals = Part.makeCompound(arrows)
            normalobj = FreeCAD.ActiveDocument.addObject(
                "Part::Feature", "Normals")
            normalobj.Shape = normals

    fid.closed
Пример #51
0
 def GetFace(self):
     self.edges.append(Part.makeLine(self.lastPoint, self.firstPoint))
     w = Part.Wire(self.edges)
     return Part.Face(w)
Пример #52
0
 def generateHob(baseRadius,addendumRadius,dedendumRadius,angularSeperation,\
                 clearance,filletRadius,sign,status):
     CLOSED = True
     OPEN = False
     FACE = True
     WIRE_FRAME = False
     PLACEMENT = None
     DELETE = True
     status.updateStatus("Setting precision to 0.001 mm")
     PRECISION = 0.001
     status.updateStatus("Calculating range for involute function")
     addendumRadius *= 1.01
     ratioAddendum = addendumRadius / baseRadius
     ratioDedendum = dedendumRadius / baseRadius
     t=numpy.arange(InvoluteProfile.calculateRange(ratioDedendum),\
                     InvoluteProfile.calculateRange(ratioAddendum),PRECISION)
     status.updateStatus("Defining involute curves")
     xInvLeft = baseRadius * (numpy.cos(-t - angularSeperation) -
                              t * numpy.sin(-t - angularSeperation))
     yInvLeft = baseRadius * (numpy.sin(-t - angularSeperation) +
                              t * numpy.cos(-t - angularSeperation))
     xInvRight = baseRadius * (numpy.cos(t + angularSeperation) +
                               t * numpy.sin(t + angularSeperation))
     yInvRight = baseRadius * (numpy.sin(t + angularSeperation) -
                               t * numpy.cos(t + angularSeperation))
     InvLeftVector = []
     InvRightVector = []
     status.updateStatus("Defining vectors for involute curves")
     for i in range(len(t)):
         InvLeftVector.append(FreeCAD.Vector(xInvLeft[i], yInvLeft[i], 0))
         InvRightVector.append(FreeCAD.Vector(xInvRight[i], yInvRight[i],
                                              0))
     status.updateStatus("Drafting involute curves")
     InvLeft = Draft.makeBSpline(Part.makePolygon(InvLeftVector), OPEN,
                                 WIRE_FRAME)
     InvRight = Draft.makeBSpline(Part.makePolygon(InvRightVector), OPEN,
                                  WIRE_FRAME)
     status.updateStatus("Defining clearance lines")
     clearanceLeftX = FreeCAD.Vector(xInvLeft[0] - clearance + filletRadius,
                                     yInvLeft[0], 0)
     clearanceRightX = FreeCAD.Vector(
         xInvRight[0] - clearance + filletRadius, yInvRight[0], 0)
     status.updateStatus("Drafting clearance lines")
     lineLeft = Draft.makeLine(InvLeftVector[0], clearanceLeftX)
     lineRight = Draft.makeLine(InvRightVector[0], clearanceRightX)
     status.updateStatus("Defining root line")
     clearanceLeftY = FreeCAD.Vector(xInvLeft[0] - clearance,
                                     yInvLeft[0] + filletRadius, 0)
     clearanceRightY = FreeCAD.Vector(xInvRight[0] - clearance,
                                      yInvRight[0] - filletRadius, 0)
     status.updateStatus("Drafting root line")
     lineClearance = Draft.makeLine(clearanceLeftY, clearanceRightY)
     status.updateStatus("Defining fillet curves")
     filletLeftCenter = FreeCAD.Placement()
     filletRightCenter = FreeCAD.Placement()
     filletLeftCenter.move(FreeCAD.Vector(xInvLeft[0]-clearance+filletRadius,\
                             yInvLeft[0]+filletRadius,0))
     filletRightCenter.move(FreeCAD.Vector(xInvRight[0]-clearance+filletRadius,\
                             yInvRight[0]-filletRadius,0))
     startangle = 180
     endangle = 270
     status.updateStatus("Drafting fillet curves")
     filletLeft = Draft.makeCircle(filletRadius, filletLeftCenter,
                                   WIRE_FRAME, startangle, endangle)
     startangle = 90
     endangle = 180
     filletRight = Draft.makeCircle(filletRadius, filletRightCenter,
                                    WIRE_FRAME, startangle, endangle)
     radius = math.sqrt(xInvLeft[len(xInvLeft) - 1]**2 +
                        yInvLeft[len(xInvLeft) - 1]**2)
     status.updateStatus("Defining addendum arc")
     arcAngle = sign * (math.atan(
         yInvLeft[len(xInvLeft) - 1] / xInvLeft[len(xInvLeft) - 1]) * 180 /
                        math.pi)
     startangle = arcAngle
     endangle = -arcAngle
     status.updateStatus("Drafting addendum arc")
     arc = Draft.makeCircle(radius, PLACEMENT, WIRE_FRAME, startangle,
                            endangle)
     status.updateStatus("Generating hob geometry")
     hobWire, deletedFeatures=Draft.upgrade([arc,lineRight,lineLeft,lineClearance,\
                                             InvRight,InvLeft,filletRight,filletLeft],DELETE)
     status.updateStatus("Generating hob face")
     hobFace, deletedFeatures = Draft.upgrade(hobWire, DELETE)
     return hobFace[0]
Пример #53
0
#You run this example by typing the following in the FreeCAD python console, making sure to change
#the path to this example, and the name of the example appropriately.
#import sys
#sys.path.append('/home/user/Downloads/cadquery/examples/FreeCAD')
#import Ex015_Rotated_Workplanes

#If you need to reload the part after making a change, you can use the following lines within the FreeCAD console.
#reload(Ex015_Rotated_Workplanes)

#You'll need to delete the original shape that was created, and the new shape should be named sequentially (Shape001, etc).

#You can also tie these blocks of code to macros, buttons, and keybindings in FreeCAD for quicker access.
#You can get a more information on this example at http://parametricparts.com/docs/examples.html#an-extruded-prismatic-solid

import cadquery
from cadquery import Vector
import Part

#Create a rotated workplane and put holes in each corner of a rectangle on that workplane, producing angled holes in the face
result = cadquery.Workplane("front").box(4.0,4.0,0.25).faces(">Z").workplane()  \
     .transformed(offset=Vector(0,-1.5,1.0),rotate=Vector(60,0,0)) \
     .rect(1.5,1.5,forConstruction=True).vertices().hole(0.25)

#Get a cadquery solid object
solid = result.val()

#Use the wrapped property of a cadquery primitive to get a FreeCAD solid
Part.show(solid.wrapped)

#Would like to zoom to fit the part here, but FreeCAD doesn't seem to have that scripting functionality
def export_faces(filename,
                 isDiel=False,
                 name="",
                 showNormals=False,
                 folder=DEF_FOLDER):
    '''export faces in FasterCap format as conductor or dielectric interface
    
    The function operates on the selection. The selection can be a face, a compound or a solid.
    'filename' is the name of the export file
    'isDiel' specifies if the mesh is a dielectric, so the function will add 
        a reference point to each panel to indicate which is the external side (outside)
    'name' is the name of the conductor created in the file. If not specified, defaults
        to the label of the first element in the selection set
    'showNormals' will add a compound object composed by a set of arrows showing the 
        normal direction for each panel
    'folder' is the folder in which 'filename' will be saved
    
    Example:
    export_faces("mymesh.txt", folder="C:/temp")
'''
    # get selection
    sel = FreeCADGui.Selection.getSelection()
    # if no valid mesh was passed
    if sel == None:
        return

    if name == "":
        condName = sel[0].Label.replace(" ", "_")
    else:
        condName = name

    # scan objects in selection and extract all faces
    faces = []
    facets = []
    for obj in sel:
        if obj.TypeId == "Mesh::Feature":
            facets.extend(obj.Mesh.Facets)
        else:
            if obj.Shape.ShapeType == "Face":
                faces.append(obj.Shape)
            elif obj.Shape.ShapeType == "Compound" or obj.Shape.ShapeType == "Solid":
                faces.extend(obj.Shape.Faces)
    # scan faces and find out which faces have more than 4 vertexes
    # TBD warning: should mesh also curve faces
    facesComplex = [x for x in faces if len(x.Vertexes) >= 5]
    facesSimple = [x for x in faces if len(x.Vertexes) < 5]
    # mesh complex faces
    doc = FreeCAD.ActiveDocument
    for face in facesComplex:
        mesh = doc.addObject("Mesh::Feature", "Mesh")
        mesh.Mesh = MeshPart.meshFromShape(Shape=face,
                                           Fineness=0,
                                           SecondOrder=0,
                                           Optimize=1,
                                           AllowQuad=0)
        facets.extend(mesh.Mesh.Facets)
    # now we have faces and facets. Uniform all
    panels = []
    for face in facesSimple:
        sortEdges = DraftGeomUtils.sortEdges(face.Edges)
        # Point of a Vertex is a Vector, as well as Face.normalAt()
        points = [x.Vertexes[0].Point for x in sortEdges]
        panels.append([points, face.normalAt(0, 0)])
    for facet in facets:
        points = [Vector(x) for x in facet.Points]
        panels.append([points, Vector(facet.Normal)])

    if not os.path.isdir(folder):
        os.mkdir(folder)

    with open(folder + os.sep + filename, 'w') as fid:
        # write the preamble
        if isDiel == True:
            fid.write(
                "0 dielectric definition file for the following objects\n")
        else:
            fid.write(
                "0 conductor definition file for the following objects\n")
        for obj in sel:
            fid.write("* - " + obj.Label + "\n")
        fid.write("* created using FreeCAD's ElectroMagnetic workbench\n")
        fid.write(
            "* see http://www.freecad.org and http://www.fastfieldsolvers.com\n\n"
        )

        arrows = []
        # export faces
        for panel in panels:
            pointsNum = len(panel[0])
            if pointsNum == 3:
                fid.write("T " + condName)
            elif pointsNum == 4:
                fid.write("Q " + condName)
            else:
                FreeCAD.Console.PrintMessage(
                    "Unforseen number of panel vertexes: " + pointsNum +
                    ", skipping panel")
                continue
            center = Vector(0.0, 0.0, 0.0)
            avgSideLen = 0.0
            for j, vertex in enumerate(panel[0]):
                fid.write(" ")
                for i in range(3):
                    fid.write(" " + str(vertex[i]))
                if isDiel == True or showNormals == True:
                    # 'point' is a tuple, transform in vector
                    center = center + vertex
                    # get side length
                    side = panel[0][(j + 1) % 3] - vertex
                    avgSideLen += side.Length
            if isDiel == True or showNormals == True:
                # calculate the reference point
                # (there should be a better way to divide a vector by a scalar..)
                center.multiply(1.0 / pointsNum)
                # and now move along the normal, proportional to the average facet dimension
                scaledNormal = panel[1]
                scaledNormal.multiply(avgSideLen / pointsNum)
                refpoint = center + scaledNormal
                if isDiel == True:
                    fid.write(" ")
                    for i in range(3):
                        fid.write(" " + str(refpoint[i]))
            fid.write("\n")
            if showNormals == True:
                arrows.append(make_arrow(center, refpoint))

    fid.closed

    if showNormals == True:
        # add the vector normals visualization to the view
        # Note: could also use Part.show(normals) but in this case we could
        # not give the (permanent) name to the object, only change the label afterwards
        normals = Part.makeCompound(arrows)
        normalobj = FreeCAD.ActiveDocument.addObject("Part::Feature",
                                                     "Normals")
        normalobj.Shape = normals
Пример #55
0
    FreeCAD.newDocument(DOC_NAME)
    FreeCAD.setActiveDocument(DOC_NAME)
    DOC = FreeCAD.activeDocument()
else:
    clear_doc()

# EPS= tolerance to use to cut the parts
EPS = 0.10
EPS_C = EPS * -0.5

# part_steel_box_tube_for_support_horizontal_generator
h = 50
l = 50
L = 420 + 350 + 293 + 257
e = 3
part_steel_box_tube_for_support_horizontal_generator = Part.makeBox(L, h, l)

# Cut part_steel_box_tube_for_support_horizontal_generator by box_1
box_1 = Part.makeBox(L, h - e*2, l - e*2)
box_1_vector = FreeCAD.Vector(0, e, e)
box_1.translate(box_1_vector)
part_steel_box_tube_for_support_horizontal_generator = part_steel_box_tube_for_support_horizontal_generator.cut(box_1)

Part.show(part_steel_box_tube_for_support_horizontal_generator)

DOC.recompute()

__objs__ = []

__objs__.append(FreeCAD.getDocument("part_steel_box_tube_for_support_horizontal_generator").getObject("Shape"))
Пример #56
0
 def AddArc(self, x1, z1, x2, z2):
     midPoint = FreeCAD.Base.Vector(x1, 0, z1)
     endPoint = FreeCAD.Base.Vector(x2, 0, z2)
     self.edges.append(
         Part.Arc(self.lastPoint, midPoint, endPoint).toShape())
     self.lastPoint = endPoint
Пример #57
0
 def asLine(self):
     return Part.LineSegment(self.Start, self.End)
Пример #58
0
def makeUShapeRebar(f_cover,
                    b_cover,
                    r_cover,
                    l_cover,
                    diameter,
                    t_cover,
                    rounding,
                    amount_spacing_check,
                    amount_spacing_value,
                    orientation="Bottom",
                    structure=None,
                    facename=None):
    """ makeUShapeRebar(FrontCover, BottomCover, RightCover, LeftCover, Diameter, Topcover, Rounding, AmountSpacingCheck, AmountSpacingValue,
    Orientation, Structure, Facename): Adds the U-Shape reinforcement bar to the selected structural object.
    It takes four different types of orientations as input i.e 'Bottom', 'Top', 'Right', 'Left'.
    """
    if not structure and not facename:
        selected_obj = FreeCADGui.Selection.getSelectionEx()[0]
        structure = selected_obj.Object
        facename = selected_obj.SubElementNames[0]
    face = structure.Shape.Faces[getFaceNumber(facename) - 1]
    #StructurePRM = getTrueParametersOfStructure(structure)
    FacePRM = getParametersOfFace(structure, facename)
    if not FacePRM:
        FreeCAD.Console.PrintError(
            "Cannot identified shape or from which base object sturctural element is derived\n"
        )
        return
    # Get points of U-Shape rebar
    points = getpointsOfUShapeRebar(FacePRM, r_cover, l_cover, b_cover,
                                    t_cover, orientation)
    import Part
    import Arch
    sketch = FreeCAD.activeDocument().addObject('Sketcher::SketchObject',
                                                'Sketch')
    sketch.MapMode = "FlatFace"
    sketch.Support = [(structure, facename)]
    FreeCAD.ActiveDocument.recompute()
    sketch.addGeometry(Part.LineSegment(points[0], points[1]), False)
    sketch.addGeometry(Part.LineSegment(points[1], points[2]), False)
    import Sketcher
    sketch.addGeometry(Part.LineSegment(points[2], points[3]), False)
    if amount_spacing_check:
        rebar = Arch.makeRebar(structure, sketch, diameter,
                               amount_spacing_value, f_cover)
        FreeCAD.ActiveDocument.recompute()
    else:
        size = (ArchCommands.projectToVector(structure.Shape.copy(),
                                             face.normalAt(0, 0))).Length
        rebar = Arch.makeRebar(structure, sketch, diameter,
                               int((size - diameter) / amount_spacing_value),
                               f_cover)
    rebar.Rounding = rounding
    # Adds properties to the rebar object
    rebar.ViewObject.addProperty(
        "App::PropertyString", "RebarShape", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Shape of rebar")).RebarShape = "UShapeRebar"
    rebar.ViewObject.setEditorMode("RebarShape", 2)
    rebar.addProperty(
        "App::PropertyDistance", "FrontCover", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Front cover of rebar")).FrontCover = f_cover
    rebar.setEditorMode("FrontCover", 2)
    rebar.addProperty(
        "App::PropertyDistance", "RightCover", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Right Side cover of rebar")).RightCover = r_cover
    rebar.setEditorMode("RightCover", 2)
    rebar.addProperty(
        "App::PropertyDistance", "LeftCover", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Left Side cover of rebar")).LeftCover = l_cover
    rebar.setEditorMode("LeftCover", 2)
    rebar.addProperty(
        "App::PropertyDistance", "BottomCover", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Bottom cover of rebar")).BottomCover = b_cover
    rebar.setEditorMode("BottomCover", 2)
    rebar.addProperty(
        "App::PropertyBool", "AmountCheck", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Amount radio button is checked")).AmountCheck
    rebar.setEditorMode("AmountCheck", 2)
    rebar.addProperty(
        "App::PropertyDistance", "TopCover", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Top cover of rebar")).TopCover = t_cover
    rebar.setEditorMode("TopCover", 2)
    rebar.addProperty(
        "App::PropertyDistance", "TrueSpacing", "RebarDialog",
        QT_TRANSLATE_NOOP(
            "App::Property",
            "Spacing between of rebars")).TrueSpacing = amount_spacing_value
    rebar.setEditorMode("TrueSpacing", 2)
    rebar.addProperty(
        "App::PropertyString", "Orientation", "RebarDialog",
        QT_TRANSLATE_NOOP("App::Property",
                          "Shape of rebar")).Orientation = orientation
    rebar.setEditorMode("Orientation", 2)
    if amount_spacing_check:
        rebar.AmountCheck = True
    else:
        rebar.AmountCheck = False
        rebar.TrueSpacing = amount_spacing_value
    rebar.Label = "UShapeRebar"
    FreeCAD.ActiveDocument.recompute()
    return rebar
Пример #59
0
    def getShape(self, obj):

        "computes a shape from a base shape and/or bounday faces"
        import Part
        shape = None
        faces = []

        pl = obj.Placement

        #print("starting compute")
        # 1: if we have a base shape, we use it

        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.Solids:
                    shape = obj.Base.Shape.copy()
                    shape = shape.removeSplitter()

        # 2: if not, add all bounding boxes of considered objects and build a first shape
        if shape:
            #print("got shape from base object")
            bb = shape.BoundBox
        else:
            bb = None
            for b in obj.Boundaries:
                if b[0].isDerivedFrom("Part::Feature"):
                    if not bb:
                        bb = b[0].Shape.BoundBox
                    else:
                        bb.add(b[0].Shape.BoundBox)
            if not bb:
                return
            shape = Part.makeBox(bb.XLength, bb.YLength, bb.ZLength,
                                 FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin))
            #print("created shape from boundbox")

        # 3: identifying boundary faces
        goodfaces = []
        for b in obj.Boundaries:
            if b[0].isDerivedFrom("Part::Feature"):
                for sub in b[1]:
                    if "Face" in sub:
                        fn = int(sub[4:]) - 1
                        faces.append(b[0].Shape.Faces[fn])
                        #print("adding face ",fn," of object ",b[0].Name)

        #print("total: ", len(faces), " faces")

        # 4: get cutvolumes from faces
        cutvolumes = []
        for f in faces:
            f = f.copy()
            f.reverse()
            cutface, cutvolume, invcutvolume = ArchCommands.getCutVolume(
                f, shape)
            if cutvolume:
                #print("generated 1 cutvolume")
                cutvolumes.append(cutvolume.copy())
                #Part.show(cutvolume)
        for v in cutvolumes:
            #print("cutting")
            shape = shape.cut(v)

        # 5: get the final shape
        if shape:
            if shape.Solids:
                #print("setting objects shape")
                shape = shape.Solids[0]
                obj.Shape = shape
                pl = pl.multiply(obj.Placement)
                obj.Placement = pl
                if hasattr(obj.Area, "Value"):
                    a = self.getArea(obj)
                    if obj.Area.Value != a:
                        obj.Area = a
                return

        print("Arch: error computing space boundary")
Пример #60
0
    def smoothChordCommands(self, bone, inChord, outChord, edge, wire, corner, smooth, color = None):
        if smooth == 0:
            PathLog.info(" No smoothing requested")
            return [ bone.lastCommand, outChord.g1Command() ]

        d = 'in'
        refPoint = inChord.Start
        if smooth == Smooth.Out:
            d = 'out'
            refPoint = outChord.End

        if DraftGeomUtils.areColinear(inChord.asEdge(), outChord.asEdge()):
            PathLog.info(" straight edge %s" % d)
            return [ outChord.g1Command() ]

        pivot = None
        pivotDistance = 0

        PathLog.info("smooth:  (%.2f, %.2f)-(%.2f, %.2f)" % (edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y))
        for e in wire.Edges:
            self.dbg.append(e)
            if type(e.Curve) == Part.LineSegment or type(e.Curve) == Part.Line:
                PathLog.debug("         (%.2f, %.2f)-(%.2f, %.2f)" % (e.Vertexes[0].Point.x, e.Vertexes[0].Point.y, e.Vertexes[1].Point.x, e.Vertexes[1].Point.y))
            else:
                PathLog.debug("         (%.2f, %.2f)^%.2f" % (e.Curve.Center.x, e.Curve.Center.y, e.Curve.Radius))
            for pt in DraftGeomUtils.findIntersection(edge, e, True, findAll=True):
                if not PathGeom.pointsCoincide(pt, corner) and self.pointIsOnEdge(pt, e):
                    #debugMarker(pt, "candidate-%d-%s" % (self.boneId, d), color, 0.05)
                    PathLog.debug("         -> candidate")
                    distance = (pt - refPoint).Length
                    if not pivot or pivotDistance > distance:
                        pivot = pt
                        pivotDistance = distance
                else:
                    PathLog.debug("         -> corner intersect")

        if pivot:
            #debugCircle(pivot, self.toolRadius, "pivot.%d-%s" % (self.boneId, d), color)

            pivotEdge = Part.Edge(Part.Circle(pivot, FreeCAD.Vector(0,0,1), self.toolRadius))
            t1 = self.findPivotIntersection(pivot, pivotEdge, inChord.asEdge(), inChord.End, d, color)
            t2 = self.findPivotIntersection(pivot, pivotEdge, outChord.asEdge(), inChord.End, d, color)

            commands = []
            if not PathGeom.pointsCoincide(t1, inChord.Start):
                PathLog.debug("  add lead in")
                commands.append(Chord(inChord.Start, t1).g1Command())
            if bone.obj.Side == Side.Left:
                PathLog.debug("  add g3 command")
                commands.append(Chord(t1, t2).g3Command(pivot))
            else:
                PathLog.debug("  add g2 command center=(%.2f, %.2f) -> from (%2f, %.2f) to (%.2f, %.2f" % (pivot.x, pivot.y, t1.x, t1.y, t2.x, t2.y))
                commands.append(Chord(t1, t2).g2Command(pivot))
            if not PathGeom.pointsCoincide(t2, outChord.End):
                PathLog.debug("  add lead out")
                commands.append(Chord(t2, outChord.End).g1Command())

            #debugMarker(pivot, "pivot.%d-%s"     % (self.boneId, d), color, 0.2)
            #debugMarker(t1,    "pivot.%d-%s.in"  % (self.boneId, d), color, 0.1)
            #debugMarker(t2,    "pivot.%d-%s.out" % (self.boneId, d), color, 0.1)

            return commands

        PathLog.info(" no pivot found - straight command")
        return [ inChord.g1Command(), outChord.g1Command() ]