Example #1
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
def makeCylinder(p1,p2,p3,p4):
	s=Part.makePolygon([p1,p2,p3,p1])
	f=Part.makeFilledFace(s.Edges)
	n=f.Faces[0].normalAt(0,0)
	# Drehung 
	n2=FreeCAD.Vector(0,0,1)
	r=FreeCAD.Rotation(n,n2)


	k1=r.multVec(p1)
	sp1=sympy.point.Point2D(k1.x,k1.y)
	z=k1.z
	sp1
	k2=r.multVec(p2)
	sp2=sympy.point.Point2D(k2.x,k2.y)
	sp2
	k3=r.multVec(p3)
	sp3=sympy.point.Point2D(k3.x,k3.y)
	sp3

	k4=r.multVec(p4)
	sp4=sympy.point.Point2D(k4.x,k4.y)
	sp4

	t=sympy.Triangle(sp1,sp2,sp3)
	rad=t.circumradius.evalf()
	center=t.circumcenter
	print rad
	print center
	x=center.x.evalf()
	y=center.y.evalf()

	circ=Part.makeCircle(rad,FreeCAD.Vector(x,y,z))
	Part.show(circ)
	cb=App.ActiveDocument.ActiveObject


	h=k4.z-k3.z

	# und wieder zurueck
	r2=FreeCAD.Rotation(n2,n)

	ex=App.ActiveDocument.addObject("Part::Extrusion","Extrude")
	ex.Base = cb
	ex.Dir = (0,0,h)
	ex.Solid = (True)
	ex.Placement.Rotation=r2
	ex.ViewObject.Transparency=80

	cb.ViewObject.hide()


	s2=Part.makePolygon([p1,p2,p3,p4])
	Part.show(s2)
	for p in [p1,p2,p3,p4]:
		k1=App.ActiveDocument.addObject("Part::Sphere","Sphere")
		k1.Placement.Base=p
		k1.Radius=0.5
		k1.ViewObject.ShapeColor=(1.0,0.0,0.0)
		App.activeDocument().recompute()
Example #3
0
	def execute(self, fp):
		scale = fp.Radius/1.2247448 
		a = scale * 0.70710678118 #1/sqrt(2)
		f = list()
		for i in (-scale,scale):
			f.append(Part.Face(Part.makePolygon([(0,scale,a), (0,-scale,a), (i,0,-a),(0,scale,a)])))
			f.append(Part.Face(Part.makePolygon([(scale,0,-a), (-scale,0,-a), (0,i,a),(scale,0,-a)])))
		fp.Shape = Part.Solid(Part.Shell(f))
 def make_blinds_top(self, blinds_height):
     
     # Top 1
     V1 = self.parts_left['top'].Vertex3.Point
     V2 = self.parts_left['top'].Vertex11.Point
     alpha = np.arctan(605./560)
     move_x = self.thickness/np.sin(alpha)
     V3 = V2 + Base.Vector(move_x,0,0)
     V4 = V1 + Base.Vector(move_x,0,0)
     
     blind_top1 = Part.makePolygon([V1,V2,V3,V4,V1])
     blind_top1 = Part.Face(blind_top1)
     self.parts_left['blind_top1'] = blind_top1.extrude(Base.Vector(0,0,blinds_height))
     
     
     # Top 2
     V1 = self.parts_left['top'].Vertex16.Point
     V2 = self.parts_left['top'].Vertex13.Point
     V4 = V1 + Base.Vector(move_x,0,0)
     
     gamma = (np.pi-alpha)/2.
     move_x = self.thickness/np.tan(gamma)
     V3 = V2 + Base.Vector(move_x, -self.thickness, 0)
     
     blind_top2 = Part.makePolygon([V1,V2,V3,V4,V1])
     blind_top2 = Part.Face(blind_top2)
     self.parts_left['blind_top2'] = blind_top2.extrude(Base.Vector(0,0,blinds_height))
     
     # Top 3
     V1 = V2
     V4 = V3
     V2 = self.parts_left['top'].Vertex12.Point
     V3 = V2 + Base.Vector(0,-self.thickness,0)
     
     blind_top3 = Part.makePolygon([V1,V2,V3,V4,V1])
     blind_top3 = Part.Face(blind_top3)
     self.parts_left['blind_top3'] = blind_top3.extrude(Base.Vector(0,0,blinds_height))
     
     # Top 4 (right work surface)
     V1 = self.parts_right['top'].Vertex3.Point
     V2 = self.parts_right['top'].Vertex7.Point
     V3 = V2 + Base.Vector(-self.thickness, -self.thickness, 0)
     V4 = V1 + Base.Vector(0,-self.thickness,0)
     
     blind_top4 = Part.makePolygon([V1,V2,V3,V4,V1])
     blind_top4 = Part.Face(blind_top4)
     self.parts_right['blind_top4'] = blind_top4.extrude(Base.Vector(0,0,blinds_height))
     
     
     # Top 5 (right works surface)
     V1 = V2
     V2 = self.parts_right['top'].Vertex5.Point
     V4 = V3
     V3 = V2 + Base.Vector(-self.thickness, 0, 0)
     
     blind_top5 = Part.makePolygon([V1,V2,V3,V4,V1])
     blind_top5 = Part.Face(blind_top5)
     self.parts_right['blind_top5'] = blind_top5.extrude(Base.Vector(0,0,blinds_height))
Example #5
0
def makePrism(l):
	print l
	hp=l[-1]
	p1=l[0]
	bl=l[:-1]
	bl.append(p1)
	print bl
	
	s=Part.makePolygon(bl)
	f=Part.makeFilledFace(s.Edges)
	Part.show(f)
	cb=App.ActiveDocument.ActiveObject
	cb.Label="Prism Bottom Face"
	cb.ViewObject.hide()

	n=f.Faces[0].normalAt(0,0)
	n2=FreeCAD.Vector(0,0,1)
	r=FreeCAD.Rotation(n,n2)


	k1=r.multVec(p1)
	sp1=sympy.point.Point2D(k1.x,k1.y)
	z=k1.z
	sp1


	k4=r.multVec(hp)
	sp4=sympy.point.Point2D(k4.x,k4.y)
	sp4

	bl2=[]
	for p in bl:
		k=r.multVec(p)
		bl2.append(k)

	s=Part.makePolygon(bl2)
	f=Part.makeFilledFace(s.Edges)
	Part.show(f)
	cb=App.ActiveDocument.ActiveObject
	cb.Label="Prism Bottom Face Helper"
	cb.ViewObject.hide()

	h=k4.z-k1.z

	# und wieder zurueck
	r2=FreeCAD.Rotation(n2,n)

	ex=App.ActiveDocument.addObject("Part::Extrusion","Extrude")
	ex.Base = cb
	ex.Dir = (0,0,h)
	ex.Solid = (True)
	ex.Placement.Rotation=r2
	ex.ViewObject.Transparency=80
	ex.Label="Prism"
	App.activeDocument().recompute()
Example #6
0
	def execute(self, fp):
		scale = fp.Radius/1.7320508075689
		phy = 1.61803398875
		f = list()
		k = scale
		for i in (-scale,scale):
			for j in (-scale,scale):
				f.append(Part.Face(Part.makePolygon([(i,j,-k), (i/phy,j*phy,0), (i,j,k), (i*phy,0,k/phy), (i*phy,0,-k/phy), (i,j,-k)])))
				f.append(Part.Face(Part.makePolygon([(j,-k,i), (j*phy,0,i/phy), (j,k,i), (0,k/phy,i*phy), (0,-k/phy,i*phy), (j,-k,i)])))
				f.append(Part.Face(Part.makePolygon([(-k,i,j), (0,i/phy,j*phy), (k,i,j), (k/phy,i*phy,0), (-k/phy,i*phy,0), (-k,i,j)])))
		fp.Shape = Part.Solid(Part.Shell(f))
Example #7
0
    def createGeometry(self,fp):
        import FreeCAD,Part,math,sys
        #tangle = -twist #openscad uses degrees clockwise
        if fp.Base and fp.Angle and fp.Height and \
            fp.Base.Shape.isValid():
        #wire=fp.Base.Shape.Wires[0].transformGeometry(fp.Base.Placement.toMatrix()) 
            solids=[]
            for faceb in fp.Base.Shape.Faces:
            #fp.Base.Shape.Faces[0].check()

            #faceb=fp.Base.Shape.Faces[0]
            #faceb=fp.Base.Shape.removeSplitter().Faces[0]
                faceu=faceb.copy()
                facetransform=FreeCAD.Matrix()
                facetransform.rotateZ(math.radians(fp.Angle.Value))
                facetransform.move(FreeCAD.Vector(0,0,fp.Height.Value))
                faceu.transformShape(facetransform)
                step = 2 + abs(int(fp.Angle.Value // 90)) #resolution in z direction
                # print abs(int(fp.Angle.Value // 90)) #resolution in z direction
                # print step
                zinc = fp.Height.Value/(step-1.0)
                angleinc = math.radians(fp.Angle.Value)/(step-1.0)
                spine = Part.makePolygon([(0,0,i*zinc) \
                        for i in range(step)])
                auxspine = Part.makePolygon([(math.cos(i*angleinc),\
                        math.sin(i*angleinc),i*fp.Height.Value/(step-1)) \
                        for i in range(step)])
                faces=[faceb,faceu]
                for wire in faceb.Wires:
                    pipeshell=Part.BRepOffsetAPI.MakePipeShell(spine)
                    pipeshell.setSpineSupport(spine)
                    pipeshell.add(wire)
                    # Was before function change
                    # pipeshell.setAuxiliarySpine(auxspine,True,False)
                    if sys.version_info.major < 3:
                        pipeshell.setAuxiliarySpine(auxspine,True,long(0))
                    else:
                        pipeshell.setAuxiliarySpine(auxspine,True,0)
                    print(pipeshell.getStatus())
                    assert(pipeshell.isReady())
                    #fp.Shape=pipeshell.makeSolid()
                    pipeshell.build()
                    faces.extend(pipeshell.shape().Faces)
                try:
                    fullshell=Part.Shell(faces)
                    solid=Part.Solid(fullshell)
                    if solid.Volume < 0:
                        solid.reverse()
                    assert(solid.Volume >= 0)
                    solids.append(solid)
                except Part.OCCError:
                    solids.append(Part.Compound(faces))
                fp.Shape=Part.Compound(solids)
Example #8
0
 def shapeGrid(self):
     poly = []
     #polyV = []
     for row in self.result:
         poly.append(Part.makePolygon(row))
     for i in range(len(self.result[0])):
         row = []
         for j in range(len(self.result)):
             row.append(self.result[j][i])
         poly.append(Part.makePolygon(row))
     c = Part.Compound(poly)
     return(c)
Example #9
0
    def execute(self,obj):

        pl = obj.Placement
        length = obj.Length.Value
        width = obj.Width.Value
        height = obj.Height.Value
        chamfer = obj.Chamfer.Value
        dentlength = obj.DentLength.Value
        dentheight = obj.DentHeight.Value
    
        if (length == 0) or (width == 0) or (height == 0):
            return
        if (chamfer >= width/2) or (chamfer >= height/2):
            return
    
        import Part
        p = []
        if chamfer > 0:
            p.append(Vector(0,chamfer,0))
            p.append(Vector(0,width-chamfer,0))
            p.append(Vector(0,width,chamfer))
            p.append(Vector(0,width,height-chamfer))
            p.append(Vector(0,width-chamfer,height))
            p.append(Vector(0,chamfer,height))
            p.append(Vector(0,0,height-chamfer))
            p.append(Vector(0,0,chamfer))
        else:
            p.append(Vector(0,0,0))
            p.append(Vector(0,width,0))
            p.append(Vector(0,width,height))
            p.append(Vector(0,0,height))
        p.append(p[0])
        p = Part.makePolygon(p)
        f = Part.Face(p)
        shape = f.extrude(Vector(length,0,0))
        if (dentlength > 0) and (dentheight > 0):
            p = []
            p.append(Vector(0,0,0))
            p.append(Vector(dentlength,0,0))
            p.append(Vector(dentlength,width,0))
            p.append(Vector(0,width,0))
            p.append(p[0])
            p = Part.makePolygon(p)
            f = Part.Face(p)
            d1 = f.extrude(Vector(0,0,dentheight))
            d2 = d1.copy()
            d2.translate(Vector(length-dentlength,0,0))
            shape = shape.cut(d1)
            shape = shape.cut(d2)
            
        shape = self.processSubShapes(obj,shape,pl)
        self.applyShape(obj,shape,pl)
Example #10
0
	def execute(self, fp):
		scale = fp.Radius/1.90211303259
		phy = 1.61803398875
		f = list()
		for i in (-scale,scale):
			for j in (-scale,scale):
				k = scale
				f.append(Part.Face(Part.makePolygon([(-k,0,i*phy), (k,0,i*phy), (0,j*phy,i*1), (-k,0,i*phy)])))
				f.append(Part.Face(Part.makePolygon([(0,i*phy,-k), (0,i*phy,k), (j*phy,i*1,0), (0,i*phy,-k)])))
				f.append(Part.Face(Part.makePolygon([(i*phy,-k,0), (i*phy,k,0), (i*1,0,j*phy), (i*phy,-k,0)])))
				for k in (-scale,scale):
					f.append(Part.Face(Part.makePolygon([(i*1,0,k*phy), (0,j*phy,k*1), (i*phy,j*1,0), (i*1,0,k*phy)])))
		fp.Shape = Part.Solid(Part.Shell(f))
Example #11
0
def bague_propu():
    """most complicated bague"""
    # TODO
    # retreive configuration
    side = bague_data["side"]
    thick = bague_data["thick"]
    length = bague_data["len"]

    # make bague shape
    shape = []

    # first branch
    shape.append(Vector(side, -side / 2, 0))
    shape.append(Vector(length, -side / 2, 0))
    shape.append(Vector(length, side / 2, 0))
    shape.append(Vector(side, side / 2, 0))

    wire0 = Part.makePolygon(shape)

    # 2nd and 3rd branches
    wire1 = wire0.copy()
    wire1.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 120)
    wire2 = wire0.copy()
    wire2.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 240)

    # union of all branches
    wire = wire0.fuse(wire1)
    wire = wire.fuse(wire2)
    vertexes = []
    for edg in wire.Edges:
        vertexes += edg.Vertexes
    points = []
    for vrt in vertexes:
        points.append(vrt.Point)
    points.append(points[0])  # close the wire

    wire = Part.makePolygon(points)
    face = Part.Face(wire)

    # make the volume
    bagu = face.extrude(Vector(0, 0, thick))

    # ring part
    ring = Part.makeCylinder(bague_propu_data["ring radius"], thick)
    bagu = bagu.fuse(ring)

    # dig the hole
    hole = Part.makeCylinder(bague_propu_data["hole radius"], thick)
    bagu = bagu.cut(hole)

    return bagu
Example #12
0
    def __init__(self, doc, profil, name='bague'):
        self.data = {
            'thick': 10., # mm
            'hole radius': 4., # mm
            'side': profil['side'] - 2 * profil['thick'], # mm
            'len': 60.5, # mm
        }

        side = self.data['side']
        thick = self.data['thick']
        length = self.data['len']

        # make bague shape
        shape = []

        # first branch
        shape.append(Vector(side, -side / 2, 0))
        shape.append(Vector(length, -side / 2, 0))
        shape.append(Vector(length, side / 2, 0))
        shape.append(Vector(side, side / 2, 0))

        wire0 = Part.makePolygon(shape)

        # 2nd and 3rd branches
        wire1 = wire0.copy()
        wire1.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 120)
        wire2 = wire0.copy()
        wire2.rotate(Vector(0, 0, 0), Vector(0, 0, 1), 240)

        # union of all branches
        wire = wire0.fuse(wire1)
        wire = wire.fuse(wire2)
        vertexes = []
        for edg in wire.Edges:
            vertexes += edg.Vertexes
        points = []
        for vrt in vertexes:
            points.append(vrt.Point)
        points.append(points[0])    # close the wire

        wire = Part.makePolygon(points)
        face = Part.Face(wire)

        # make the volume
        bague = face.extrude(Vector(0, 0, thick))

        # dig the hole
        hole = Part.makeCylinder(self.data['hole radius'], thick)
        bague = bague.cut(hole)

        MecaComponent.__init__(self, doc, bague, name, (0.95, 1., 1.))
Example #13
0
def gen_haus0(le,wi,hiall,hi,midx,wx,midy,wy):

#	le=30
#	wi=20
	he=hiall
	he3=hi
	
	inle=8
	inwi=2
	if wx==0: wx=0.0001
	if wy==0: wy=0.0001
	
	if midx<0.5:
		bix=le*midx
	else:
		bix=le*(1-midx)

	if midy<0.5:
		biy=wi*midy
	else:
		biy=wi*(1-midy)

	list1=viereck(le,wi,0)
	list2=viereck(le,wi,he)
	# list3=viereck(le,wi,he3,inle,inwi)
	list3=viereck(le,wi,he3,
		le*midx-bix*wx,le-(le*midx+bix*wx),
		wi*midy-biy*wy,wi-(wi*midy+biy*wy),
	)
	
	poly1 = Part.makePolygon( list1)
	poly3 = Part.makePolygon( list3)
	face1 = Part.Face(poly1)
	face3 = Part.Face(poly3)
	faceListe=[face1,face3]

	for i in range(len(list1)-1):
		liste3=[list1[i],list1[i+1],list2[i+1],list2[i],list1[i]]
		poly=Part.makePolygon(liste3)
		face = Part.Face(poly)
		faceListe.append(face)

	for i in range(len(list2)-1):
		liste3=[list2[i],list2[i+1],list3[i+1],list3[i],list2[i]]
		poly=Part.makePolygon(liste3)
		face = Part.Face(poly)
		faceListe.append(face)

	myShell = Part.makeShell(faceListe)   
	mySolid = Part.makeSolid(myShell)
	return mySolid
Example #14
0
 def genDeckAndWalls(self):
   '''Returns a compound with the deck and walls of the structure'''
   #Deck
   ptDeckBL=self.kpITL.add(Base.Vector(-self.wallTh,0,-self.deckSlope*self.wallTh*self.wallTh))
   ptDeckBR=self.kpITR.add(Base.Vector(self.wallTh,0,self.deckSlope*self.wallTh*self.wallTh))
   linDeck=Part.makePolygon([self.kpITL,ptDeckBL,self.kpETL,self.kpETR,ptDeckBR,self.kpITR,self.kpITL])
   deck=Part.Face(linDeck)
   #Walls
   linLeftWall=Part.makePolygon([self.kpIBL,self.kpEBL,ptDeckBL,self.kpITL,self.kpIBL])
   leftWall=Part.Face(linLeftWall)
   linRightWall=Part.makePolygon([self.kpEBR,self.kpIBR,self.kpITR,ptDeckBR,self.kpEBR])
   rightWall=Part.Face(linRightWall)
   retComp=Part.makeCompound([deck,leftWall,rightWall])
   return self.placeAndExtrudeShape(retComp)
Example #15
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
Example #16
0
 def execute(self, obj):
     debug("* Interpolate : execute *")
     pts = self.getPoints( obj)
     if obj.Polygonal:
         if obj.Periodic:
             pts.append(pts[0])
         poly = Part.makePolygon(pts)
         if obj.WireOutput:
             obj.Shape = poly
             return()
         else:
             bs = poly.approximate(1e-8,obj.Tolerance,999,1)
     else:
         bs = Part.BSplineCurve()
         bs.interpolate(Points=pts, PeriodicFlag=obj.Periodic, Tolerance=obj.Tolerance, Parameters=obj.Parameters)
         if not (len(obj.Tangents) == len(pts) and len(obj.TangentFlags) == len(pts)) or obj.DetectAligned:
             if obj.Periodic:
                 obj.Tangents = [bs.tangent(p)[0] for p in obj.Parameters[0:-1]]
             else:
                 obj.Tangents = [bs.tangent(p)[0] for p in obj.Parameters]
             obj.TangentFlags = [True]*len(pts)
         if obj.CustomTangents or obj.DetectAligned:
             if obj.DetectAligned:
                 self.detect_aligned_pts(obj, pts)
             bs.interpolate(Points=pts, PeriodicFlag=obj.Periodic, Tolerance=obj.Tolerance, Parameters=obj.Parameters, Tangents=obj.Tangents, TangentFlags=obj.TangentFlags) #, Scale=False)
     obj.Shape = bs.toShape()
Example #17
0
 def execute(self, obj):
     pl = obj.Placement
     p1 = Vector(-obj.Width.Value / 2, -obj.Height.Value / 2, 0)
     p2 = Vector(obj.Width.Value / 2, -obj.Height.Value / 2, 0)
     p3 = Vector(obj.Width.Value / 2,
                 (-obj.Height.Value / 2) + obj.FlangeThickness.Value, 0)
     p4 = Vector(obj.WebThickness.Value / 2,
                 (-obj.Height.Value / 2) + obj.FlangeThickness.Value, 0)
     p5 = Vector(obj.WebThickness.Value / 2,
                 obj.Height.Value / 2 - obj.FlangeThickness.Value, 0)
     p6 = Vector(obj.Width.Value / 2,
                 obj.Height.Value / 2 - obj.FlangeThickness.Value, 0)
     p7 = Vector(obj.Width.Value / 2, obj.Height.Value / 2, 0)
     p8 = Vector(-obj.Width.Value / 2, obj.Height.Value / 2, 0)
     p9 = Vector(-obj.Width.Value / 2,
                 obj.Height.Value / 2 - obj.FlangeThickness.Value, 0)
     p10 = Vector(-obj.WebThickness.Value / 2,
                  obj.Height.Value / 2 - obj.FlangeThickness.Value, 0)
     p11 = Vector(-obj.WebThickness.Value / 2,
                  (-obj.Height.Value / 2) + obj.FlangeThickness.Value, 0)
     p12 = Vector(-obj.Width.Value / 2,
                  (-obj.Height.Value / 2) + obj.FlangeThickness.Value, 0)
     p = Part.makePolygon(
         [p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p1])
     p = Part.Face(p)
     p.reverse()
     obj.Shape = p
     obj.Placement = pl
Example #18
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 = DraftGeomUtils.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:]
Example #19
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]
Example #20
0
    def Activated(self):
        proceed = False
        obj = Gui.Selection.getSelection()
        if len(obj) > 0:
            obj = obj[0]
            if check_glider(obj):
                proceed = True
        if proceed:
            import openglider.plots
            import Part
            unwrapper = openglider.plots.PlotMaker(obj.GliderInstance)
            unwrapper.unwrap()

            areas = unwrapper.get_all_parts().group_materials()

            for material_name, draw_area in areas.items():
                pattern_doc = FreeCAD.newDocument("plots_{}".format(material_name))
                draw_area.rasterize()
                draw_area.scale(1000)
                for i, part in enumerate(draw_area.parts):
                    grp = pattern_doc.addObject("App::DocumentObjectGroup", part.name)
                    layer_dict = part.layers
                    for layer in layer_dict:
                        for j, line in enumerate(layer_dict[layer]):
                            obj = FreeCAD.ActiveDocument.addObject("Part::Feature", layer + str(j))
                            obj.Shape = Part.makePolygon(map(App.Vector, line))
                            grp.addObject(obj)

                    pattern_doc.recompute()
Example #21
0
def makeMesh(doc,activeobject,verts,facets,material,colortable):
    mfacets = []
    if facets:
        for facet in facets:
            if len(facet) > 3:
                vecs = [FreeCAD.Vector(*verts[i-1]) for i in facet]
                vecs.append(vecs[0])
                pol = Part.makePolygon(vecs)
                try:
                    face = Part.Face(pol)
                except Part.OCCError:
                    print("Skipping non-planar polygon:",vecs)
                else:
                    tris = face.tessellate(1)
                    for tri in tris[1]:
                        mfacets.append([tris[0][i] for i in tri])
            else:
                mfacets.append([verts[i-1] for i in facet])
    if mfacets:
        mobj = doc.addObject("Mesh::Feature",activeobject)
        mobj.Mesh = Mesh.Mesh(mfacets)
        if material and FreeCAD.GuiUp:
            if material in colortable:
                mobj.ViewObject.ShapeColor = colortable[material][0]
                if colortable[material][1] != None:
                    mobj.ViewObject.Transparency = colortable[material][1]
Example #22
0
 def execute(self,obj):
     pl = obj.Placement
     p1 = Vector(-obj.Width.Value/2,-obj.Height.Value/2,0)
     p2 = Vector(obj.Width.Value/2,-obj.Height.Value/2,0)
     p3 = Vector(obj.Width.Value/2,obj.Height.Value/2,0)
     p4 = Vector(-obj.Width.Value/2,obj.Height.Value/2,0)
     q1 = Vector(-obj.Width.Value/2+obj.Thickness.Value,-obj.Height.Value/2+obj.Thickness.Value,0)
     q2 = Vector(obj.Width.Value/2-obj.Thickness.Value,-obj.Height.Value/2+obj.Thickness.Value,0)
     q3 = Vector(obj.Width.Value/2-obj.Thickness.Value,obj.Height.Value/2-obj.Thickness.Value,0)
     q4 = Vector(-obj.Width.Value/2+obj.Thickness.Value,obj.Height.Value/2-obj.Thickness.Value,0)
     p = Part.makePolygon([p1,p2,p3,p4,p1])
     q = Part.makePolygon([q1,q2,q3,q4,q1])
     r = Part.Face([p,q])
     r.reverse()
     obj.Shape = r
     obj.Placement = pl
Example #23
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
 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)
Example #25
0
 def make_object(self, poly, thickness, pos, nudge):
     #print pos
     halfw = thickness * 0.5
     norm = Base.Vector(0,thickness,0)
     object = None
     for i in range(len(poly)):
         pts = []
         for p in poly.contour(i):
             pts.append( Base.Vector(p[0]+pos[1], -halfw-nudge+pos[0], p[1]+pos[2]) )
         # close the loop
         pts.append( pts[0] )
         #print 'pts:', pts
         seg = Part.makePolygon( pts )
         face = Part.Face(seg)
         shape = face.extrude(norm)
         if poly.isHole(i):
             #print 'hole:', poly.contour(i)
             if object:
                 object = object.cut(shape)
         else:
             #print 'outline:', poly.contour(i)
             if object:
                 object = object.fuse(shape)
             else:
                 object = shape
     return object
 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
Example #27
0
    def __init__(self, doc, name='fin'):
        # ailerons
        self.data = {
            'len': 365., # mm
            'e': 222., # mm
            'p': 55., # mm
            'm': 255., # mm
            'thick': 3., # mm
        }

        # use profile shape to make suppressed parts of the skin
        shape = []

        # 1st part
        shape.append(Vector(0, 0, 0))
        shape.append(Vector(0, 0, self.data['len']))
        shape.append(Vector(self.data['e'], 0, self.data['len'] - self.data['p']))
        shape.append(Vector(self.data['e'], 0, self.data['len'] - self.data['p'] - self.data['m']))
        shape.append(Vector(0, 0, 0))

        wire = Part.makePolygon(shape)
        # center it
        wire.translate(Vector(0, - self.data['thick'] / 2, 0))
        face = Part.Face(wire)

        # make the volume
        comp = face.extrude(Vector(0, self.data['thick'], 0))

        # center it
        #comp.translate(Vector(0, - self.data['thick'] / 2, 0))

        MecaComponent.__init__(self, doc, comp, name, (0.95, 1., 1.))
Example #28
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
Example #29
0
    def execute(self,obj):

        pl = obj.Placement
        length = obj.Length.Value
        width = obj.Width.Value
        height = obj.Height.Value
        base = obj.BeamBase.Value
        slant = obj.Chamfer.Value
    
        if (length == 0) or (width == 0) or (height == 0):
            return
        if (slant*2 >= width) or (base*2+slant*2 >= height):
            return
    
        import Part
        p = []
        p.append(Vector(0,0,0))
        p.append(Vector(0,0,base))
        p.append(Vector(0,slant,base+slant))
        p.append(Vector(0,slant,height-(base+slant)))
        p.append(Vector(0,0,height-base))
        p.append(Vector(0,0,height))
        p.append(Vector(0,width,height))
        p.append(Vector(0,width,height-base))
        p.append(Vector(0,width-slant,height-(base+slant)))
        p.append(Vector(0,width-slant,base+slant))
        p.append(Vector(0,width,base))
        p.append(Vector(0,width,0))
        p.append(p[0])
        p = Part.makePolygon(p)
        f = Part.Face(p)
        shape = f.extrude(Vector(length,0,0))

        shape = self.processSubShapes(obj,shape,pl)
        self.applyShape(obj,shape,pl)
Example #30
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
Example #31
0
    }


def getnameofpolygon(points):
    avgpt = sum(points, Vector()) * (1.0 / len(points))
    closestname = min(((avgpt - Vector(p[0] * 1000, p[1] * 1000)).Length, name)
                      for name, p in patchnamelookups.items())[1]
    return closestname


clw = getemptyobject(doc, "App::DocumentObjectGroup", "UVPolygons")

# find the sets of nodes from the coincident constraints
gcptsets, gcptnmap = extractcoincidentnodes(cutlinesketch)
gcptorders = [
    coincidentnodetanges(cutlinesketch, gcptset) for gcptset in gcptsets
]

# derive the sequences of (edge, startend) for each contour
seqs = extractsequences(gcptorders, gcptnmap)

for n, seq in enumerate(seqs):
    points = sequencetopoints(cutlinesketch, seq, legsampleleng=3.0)
    if not orientationclockwise(points):
        closestname = getnameofpolygon(points)
        ws = createobjectingroup(doc, clw, "Part::Feature",
                                 "w%s" % (closestname))
        ws.Shape = Part.makePolygon(points + [points[0]])
        lam = n / len(seqs)
        ws.ViewObject.PointColor = (0.5 + lam * 0.5, 1.0 - lam * 0.5, 0.8)
Example #32
0
def createStructuralMember(ifcfile, ifcbin, obj):

    """Creates a structural member if possible. Returns the member"""

    global structural_nodes, structural_curves
    structuralMember = None
    import Draft
    import Part
    import ifcopenshell
    import FreeCAD
    uid = ifcopenshell.guid.new
    ownerHistory = ifcfile.by_type("IfcOwnerHistory")[0]
    structContext = getStructuralContext(ifcfile)
    
    # find edges to convert into structural members
    edges = None
    if Draft.getType(obj) not in ["Structure"]:
        # for non structural elements 
        if ALLOW_LINEAR_OBJECTS and obj.isDerivedFrom("Part::Feature"):
            # for objects created with Part workbench
            if obj.Shape.Faces:
                # for objects with faces
                return None
            elif not obj.Shape.Edges:
                # for objects without edges
                return None
            else:
                edges = obj.Shape.Edges
    else:
        # for structural elements with nodes
        nodes = [obj.Placement.multVec(n) for n in obj.Nodes]
        if len(nodes) > 2:
            # when there are more then 2 nodes (i.e. for slabs) append closing node to produce closing edge
            nodes.append(nodes[0])
        wire = Part.makePolygon(nodes)
        edges = wire.Edges
    if not edges:
        return None
        
    # OBJECT CLASSIFICATION by edge number
    # Linear elements for edge_number = 1, Surface elements for edge_number > 1
    # we don't care about curved edges just now...
    
    if len(edges) == 1:
        # LINEAR OBJECTS: beams, columns
        # ATM limitations:
        # - no profile properties are taken into account
        # - no materials properties are takein into account
        # -
    	# create geometry
        verts = [None for _ in range(len(edges)+1)]
        verts[0] = tuple(edges[0].Vertexes[ 0].Point.multiply(scaling))
        verts[1] = tuple(edges[0].Vertexes[-1].Point.multiply(scaling))
        cartPnt1 = ifcfile.createIfcCartesianPoint(verts[0])
        cartPnt2 = ifcfile.createIfcCartesianPoint(verts[1])
        vertPnt1 = ifcfile.createIfcVertexPoint(cartPnt1)
        vertPnt2 = ifcfile.createIfcVertexPoint(cartPnt2)
        newEdge = ifcfile.createIfcEdge(vertPnt1, vertPnt2)
        topologyRep = ifcfile.createIfcTopologyRepresentation(structContext, "Analysis", "Edge", (newEdge,))
        prodDefShape = ifcfile.createIfcProductDefinitionShape(None, None, (topologyRep,))  
        # set local coordinate system
        localPlacement = ifcbin.createIfcLocalPlacement()
        localZAxis = ifcbin.createIfcDirection((0, 0, 1))    
        # create structural member    
        if ifcfile.wrapped_data.schema_name() == "IFC2X3":
            structuralMember = ifcfile.createIfcStructuralCurveMember(
                uid(), ownerHistory, obj.Label, None, None, localPlacement, prodDefShape, "RIGID_JOINED_MEMBER")
        else:
            localZAxis = ifcbin.createIfcDirection((0, 0, 1))
            structuralMember = ifcfile.createIfcStructuralCurveMember(
                uid(), ownerHistory, obj.Label, None, None, localPlacement, prodDefShape, "RIGID_JOINED_MEMBER", localZAxis)

    elif len(edges) > 1:
        # SURFACE OBJECTS: slabs (horizontal, vertical, inclined)
        # ATM limitations:
        # - mo material properties are taken into account
        # - walls don't work because they miss a node system   
        # -     
        # creates geometry
        verts = [None for _ in range(len(edges))]
        for i, edge in enumerate(edges):
           verts[i] = tuple(edge.Vertexes[0].Point.multiply(scaling))
           cartPnt = ifcfile.createIfcCartesianPoint(verts[i])
           vertPnt = ifcfile.createIfcVertexPoint(cartPnt)
        orientedEdges = [None for _ in range(len(edges))]
        for i, vert in enumerate(verts):
            v2Index = (i + 1) if i < len(verts) - 1 else 0
            cartPnt1 = ifcfile.createIfcCartesianPoint(vert)
            cartPnt2 = ifcfile.createIfcCartesianPoint(verts[v2Index])
            vertPnt1 = ifcfile.createIfcVertexPoint(cartPnt1)
            vertPnt2 = ifcfile.createIfcVertexPoint(cartPnt2)
            edge = ifcfile.createIfcEdge(vertPnt1, vertPnt2)
            orientedEdges[i] = ifcfile.createIfcOrientedEdge(None, None, edge, True) 
        edgeLoop = ifcfile.createIfcEdgeLoop(tuple(orientedEdges))
        # sets local coordinate system
        localPlacement = ifcbin.createIfcLocalPlacement()
        # sets face origin to the first vertex point of the planar surface
        origin = cartPnt2
        # find crossVect that is perpendicular to the planar surface
        vect0 = FreeCAD.Vector(verts[0])
        vect1 = FreeCAD.Vector(verts[1])
        vectn = FreeCAD.Vector(verts[-1])
        vect01 = vect1.sub(vect0)
        vect0n = vectn.sub(vect0)
        crossVect = vect01.cross(vect0n)
        # normalize crossVect
        normVect = crossVect.normalize()
        xAxis = ifcfile.createIfcDirection(tuple([vect01.x, vect01.y, vect01.z]))
        zAxis = ifcfile.createIfcDirection(tuple([normVect.x, normVect.y, normVect.z]))
        localAxes = ifcfile.createIfcAxis2Placement3D(origin, zAxis, xAxis)
        plane = ifcfile.createIfcPlane(localAxes)
        faceBound = ifcfile.createIfcFaceBound(edgeLoop, True)
        face = ifcfile.createIfcFaceSurface((faceBound,), plane, True)
        topologyRep = ifcfile.createIfcTopologyRepresentation(structContext, "Analysis", "Face", (face,))
        prodDefShape = ifcfile.createIfcProductDefinitionShape(None, None, (topologyRep,))
        # sets surface thickness
        # ATM limitations
        # - for verical slabs (walls) or inclined slabs (ramps) the thickness is taken from the Height property
        thickness = float(obj.Height)*scaling
        # creates structural member
        structuralMember = ifcfile.createIfcStructuralSurfaceMember(
            uid(), ownerHistory, obj.Label, None, None, localPlacement, prodDefShape, "SHELL", thickness)

    # check for existing connection nodes
    for vert in verts:
        vertCoord = tuple(vert)
        if vertCoord in structural_nodes:
            if structural_nodes[vertCoord]:
                # there is already another member using this point
                structPntConn = structural_nodes[vertCoord]
            else:
                # there is another member with same point, create a new node connection
                structPntConn = createStructuralNode(ifcfile, ifcbin, vert)
                structural_nodes[vertCoord] = structPntConn
            ifcfile.createIfcRelConnectsStructuralMember(
                uid(), ownerHistory, None, None, structuralMember, structPntConn, None, None, None, None)
        else:
            # just add the point, no other member using it yet
            structural_nodes[vertCoord] = None
                
    # check for existing connection curves
    for edge in edges:
        verts12 = tuple([edge.Vertexes[ 0].Point.x, edge.Vertexes[ 0].Point.y, edge.Vertexes[ 0].Point.z,
                         edge.Vertexes[-1].Point.x, edge.Vertexes[-1].Point.y, edge.Vertexes[-1].Point.z])
        verts21 = tuple([edge.Vertexes[-1].Point.x, edge.Vertexes[-1].Point.y, edge.Vertexes[-1].Point.z,
                         edge.Vertexes[ 0].Point.x, edge.Vertexes[ 0].Point.y, edge.Vertexes[ 0].Point.z])                
        verts12_in_curves = verts12 in structural_curves
        verts21_in_curves = verts21 in structural_curves
        if verts21_in_curves:
            verts = verts21
        else:
            verts = verts12
        if (verts12_in_curves or verts21_in_curves):
            if structural_curves[verts]:
                # there is already another member using this curve
                strucCrvConn = structural_curves[verts]
            else:
                # there is another member with same edge, create a new curve connection
                strucCrvConn = createStructuralCurve(ifcfile, ifcbin, edge)
                structural_curves[verts] = strucCrvConn
            ifcfile.createIfcRelConnectsStructuralMember(
                uid(), None, None, None, structuralMember, strucCrvConn, None, None, None, None)
        else:
            # just add the curve, no other member using it yet
            structural_curves[verts] = None
    return structuralMember
Example #33
0
 def alignTo3Points(self, p1, p2, p3, offset=0):
     import Part
     w = Part.makePolygon([p1, p2, p3, p1])
     f = Part.Face(w)
     return self.alignToFace(f, offset)
Example #34
0
def make_face(v1, v2, v3):
    wire = Part.makePolygon([v1, v2, v3, v1])
    face = Part.Face(wire)
    return face
def combineCurves():

    #get selected horizontal and vertical geometry
    (h, v) = Gui.Selection.getSelection()

    #get list of geometry edges
    horiz_edge = h.Shape.Edges[0]
    vert_edge = v.Shape.Edges[0]

    #get the horizontal curve's first and last parameters
    fip = horiz_edge.FirstParameter
    lap = horiz_edge.LastParameter

    #get the length of the curve and set the step interval
    horiz_len = horiz_edge.Length
    step = 3000

    #initialize point lists
    #ptsh is ... ?
    pts = []
    ptsh = [
        FreeCAD.Vector(),
        FreeCAD.Vector(horiz_len, 0, 0),
        FreeCAD.Vector()
    ]
    ptsn = []
    ptsc = []

    #divide the length by the number of steps, truncating the integer
    #then add one for the concluding point for the steps,
    #plus a point for the end of the edge, if the step point falls short
    point_count = int(horiz_len / float(step)) + 1

    if ((point_count - 1) * step) < horiz_len:
        point_count += 1

    #vertial curve as equidistant points at the step interval...
    vt_seg_pts = vert_edge.discretize(Number=point_count,
                                      First=0.00,
                                      Last=horiz_len)

    end_point = vt_seg_pts[point_count - 1]

    print('Start point: ', vt_seg_pts[0])
    print('End point: ', vt_seg_pts[point_count - 1])

    #c=FreeCAD.getDocument("stationing").getObject("MyBezierSketch")
    #pts=c.Shape.Edge1.discretize(20)

    import numpy as np

    #this pairs coordinates of like axes in three tuples (x_coords,y_coords,z)
    vt_pt_seg_axes = np.array(vt_seg_pts).swapaxes(0, 1)

    #save the x_coords/y_coords coordinate pairs in separate variables
    x_coords = list(range(0, int(horiz_len) + 1, step))

    #if we added two to the point count, then the step interval
    #won't quite make it to the end... add the length as the last point
    if len(x_coords) < point_count:
        x_coords.append(horiz_len)

    last_pt = len(x_coords)
    print(x_coords[last_pt - 10:])

    y_coords = vt_pt_seg_axes[1]

    #append the final elevation - see above
    if (len(y_coords) < point_count):
        y_coords = np.append(y_coords, end_point.y)

    print(len(x_coords))
    print(len(y_coords))

    #interpolation...
    from scipy import interpolate
    ff = interpolate.interp1d(x_coords,
                              y_coords,
                              kind='cubic',
                              bounds_error=False,
                              fill_value=0)

    ll = int(h.Shape.Length) + 1

    #create a set of x_coords-values evenly spaced between 0 and ll at the specified step interval
    xnew = np.arange(0, ll, step)

    last_element = xnew[len(xnew) - 1]

    if last_element != h.Shape.Length:
        xnew = np.append(xnew, h.Shape.Length)

    #interpolates y_coords values for the specified x_coords values
    ynew = ff(xnew)  # use interpolation function returned by `interp1d`

    #ynew = np.append(ynew, vert_edge.Curve.parameterAtDistance(horiz_len))
    #	plt.plot(x_coords, y_coords, 'o', xnew, ynew, '+')
    #	plt.show()

    #minimum of point_count, and the number of intervals in xnew
    #anz2=min(point_count,xnew.shape[0])

    print('point_count: ', point_count)
    print('xnew.shape[0]', xnew.shape[0])
    #print ("anz2: ", anz2)

    for i in range(xnew.shape[0]):

        print(xnew[i], ynew[i])
        #x,y coordinate on horizontal
        #p=horiz_edge.valueAt(fip+step*(lap-fip)/horiz_len*i)

        #tangent at point
        t = horiz_edge.tangentAt(fip + step * (lap - fip) / horiz_len * i)

        #x,y coordinate on horizontal
        p = horiz_edge.Curve.value(fip + step * (lap - fip) / horiz_len * i)

        #stationing line interval
        f = 2
        if i % 5 == 0:
            f = 4
        if i % 10 == 0:
            f = 10
        if i % 50 == 0:
            f = 30

        #calculate normal vector at point
        n = f * t.cross(FreeCAD.Vector(0, 0, 1))

        #hp=FreeCAD.Vector(p.x_coords,p.y_coords,hz_seg_pts[i].y_coords)
        # print i

        #generate z-coordinate for 3D spline
        hp = FreeCAD.Vector(p.x, p.y, ynew[i])

        pts += [p, p + n, p, p - n, p]
        ptsn += [p, hp, p]

        hh = FreeCAD.Vector(xnew[i], ynew[i], 0)
        vpp = vert_edge.Curve.parameterAtDistance(xnew[i])
        #vpp=vert_edge.Curve.parameter(hh)
        vtt = vert_edge.tangentAt(vpp)
        vn = f * vtt.cross(FreeCAD.Vector(0, 0, 1))

        #ptsh += [hz_seg_pts[i],hz_seg_pts[i]+vn,hz_seg_pts[i]-vn,hz_seg_pts[i]]
        ptsh += [hh, hh + vn, hh - vn, hh]

        ptsc += [hp]

    import Part

    #stationing along horizontal curve
    res = App.ActiveDocument.getObject("Wxy")
    if res == None:
        res = App.activeDocument().addObject('Part::Feature', 'Wxy')

    res.Shape = Part.makePolygon(pts)

    #
    res = App.ActiveDocument.getObject("Whmap")
    if res == None:
        res = App.activeDocument().addObject('Part::Feature', 'Whmap')

    res.Shape = Part.makePolygon(ptsn)

    #station along vertical curve
    res = App.ActiveDocument.getObject("Wh")
    if res == None:
        res = App.activeDocument().addObject('Part::Feature', 'Wh')

    res.Shape = Part.makePolygon(ptsh)

    res = App.ActiveDocument.getObject("W3D")
    if res == None:
        res = App.activeDocument().addObject('Part::Feature', 'W3D')

    s = Part.BSplineCurve()
    s.interpolate(ptsc)

    res.Shape = s.toShape()
    def createGeometry(self, obj):
        import Part, DraftGeomUtils

        # getting default values
        height = width = length = 1
        if hasattr(obj, "Length"):
            if obj.Length:
                length = obj.Length
        if hasattr(obj, "Width"):
            if obj.Width:
                width = obj.Width
        if hasattr(obj, "Height"):
            if obj.Height:
                height = obj.Height

        # creating base shape
        pl = obj.Placement
        base = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if hasattr(obj, "Tool"):
                    if obj.Tool:
                        try:
                            base = obj.Tool.Shape.copy().makePipe(
                                obj.Base.Shape.copy())
                        except:
                            FreeCAD.Console.PrintError(
                                str(
                                    translate(
                                        "Arch",
                                        "Error: The base shape couldn't be extruded along this tool object"
                                    )))
                            return
                if not base:
                    if obj.Normal == Vector(0, 0, 0):
                        p = FreeCAD.Placement(obj.Base.Placement)
                        normal = p.Rotation.multVec(Vector(0, 0, 1))
                    else:
                        normal = Vector(obj.Normal)
                    normal = normal.multiply(height)
                    base = obj.Base.Shape.copy()
                    if base.Solids:
                        pass
                    elif base.Faces:
                        base = base.extrude(normal)
                    elif (len(base.Wires) == 1):
                        if base.Wires[0].isClosed():
                            base = Part.Face(base.Wires[0])
                            base = base.extrude(normal)

            elif obj.Base.isDerivedFrom("Mesh::Feature"):
                if obj.Base.Mesh.isSolid():
                    if obj.Base.Mesh.countComponents() == 1:
                        sh = ArchCommands.getShapeFromMesh(obj.Base.Mesh)
                        if sh.isClosed() and sh.isValid() and sh.Solids:
                            base = sh
        else:
            if obj.Normal == Vector(0, 0, 0):
                normal = Vector(0, 0, 1)
            else:
                normal = Vector(obj.Normal)
            normal = normal.multiply(height)
            l2 = length / 2 or 0.5
            w2 = width / 2 or 0.5
            v1 = Vector(-l2, -w2, 0)
            v2 = Vector(l2, -w2, 0)
            v3 = Vector(l2, w2, 0)
            v4 = Vector(-l2, w2, 0)
            base = Part.makePolygon([v1, v2, v3, v4, v1])
            base = Part.Face(base)
            base = base.extrude(normal)

        base = self.processSubShapes(obj, base)

        if base:
            # applying axes
            pts = self.getAxisPoints(obj)
            apl = self.getAxisPlacement(obj)
            if pts:
                fsh = []
                for i in range(len(pts)):
                    if hasattr(obj, "Exclude"):
                        if i in obj.Exclude:
                            continue
                    sh = base.copy()
                    if apl:
                        sh.Placement.Rotation = apl.Rotation
                    sh.translate(pts[i])
                    fsh.append(sh)
                    obj.Shape = Part.makeCompound(fsh)

            # finalizing

            else:
                if base:
                    if not base.isNull():
                        if base.isValid() and base.Solids:
                            if base.Volume < 0:
                                base.reverse()
                            if base.Volume < 0:
                                FreeCAD.Console.PrintError(
                                    str(
                                        translate("Arch",
                                                  "Couldn't compute a shape")))
                                return
                            base = base.removeSplitter()
                            obj.Shape = base
                if not DraftGeomUtils.isNull(pl):
                    obj.Placement = pl
Example #37
0
def planarize(
        layerNum
):  #Creates a single Z valued layer covering all previous features
    '''
    planarize function takes the passed FreeCAD function name and finds the distance from that shape to the substrate. It then finds the highest
    point (top of a feature) and takes that point minus the base of the passed layer which gives the total height of the top object. From here an additional
    "buffer" is added to those values (so that all features are properly covered - and required for FreeCAD to evaluate properly) to create a total extrusion
    distance. A layer is then created using the outermost bounds of the FreeCAD document (substrate/outline layer) and the total extrusion distance.
    The new layer is then trimmed of all objects (not substrate) in the FreeCAD document (anything already deposited). The final object will rest on top of
    all the other layers as long as there are no gaps within the other layers (these will get filled in with this object).

    Function is passed the name of the top layer

    Returns the planarized layer

    **Currently only designed to create one planarization; however, FreeCAD will automatically append numbers to the name if additional planar layers are called.
    This can also be updated to use the two global arrays (currently commented out).
    '''
    print("Start planarize")
    layerObj = FreeCAD.ActiveDocument.getObject(layerNum).Shape
    belowLayer = layerObj.Edges[0].distToShape(
        FreeCAD.ActiveDocument.getObject("Substrate").Shape)[0]
    additionalPlanarizeLevel = 1  #Can change this to add extra thickness to the planarization
    maxHeight = round(sp.get_highest_point(), 4)
    objHeight = maxHeight - round(
        layerObj.Vertexes[0].Point[2],
        4)  #Returns the max height of just the object being planarizized
    totalExtrusion = belowLayer + objHeight + additionalPlanarizeLevel  #Total value needed to extrude the planar layer
    outerBounds = list(sp.get_2D_outer_bounds())
    outerBounds.append(
        outerBounds[0]
    )  #Closes the shape by reconnecting the last vertex to the first vertex
    for idx, point in enumerate(outerBounds):
        outerBounds[idx] = list(
            outerBounds[idx]
        )  #Changes the tuple values into a list so they can be edited
        outerBounds[idx].append(0)  #Starting Z value of 0
    #print(outerBounds)
    pts = []
    for pt in outerBounds:
        pts.append(FreeCAD.Vector(pt[0], pt[1], pt[2]))
    planarWire = Part.makePolygon(
        pts)  #Makes a wire out of the outermost bounds
    planarFace = Part.Face(planarWire)
    planarExtrusion = planarFace.extrude(
        Base.Vector(0, 0, totalExtrusion)
    )  #+.0005)) #Might need to add a small amount, like .0005, here to account for the subtraction done later on
    cutObj = planarExtrusion.copy()  #Used to trim the planar layer
    for obj in FreeCAD.ActiveDocument.Objects:  #Loops all objects
        if obj.Label != "Substrate":  #If FreeCAD label is not substrate
            #print(obj.Label)                                                   #For debugging
            planarExtrusion = planarExtrusion.cut(
                obj.Shape
            )  #Takes the original "block" planar layer and cuts out all features/layers
    #Part.show(planarExtrusion)                                                 #For debugging
    cutObj.Placement.move(
        FreeCAD.Vector(0, 0, totalExtrusion)
    )  #+.0006)) #The .0006 accounts for the -.0005 movement later on and allows for all extra edges to be deleted
    trimmedPlanar = planarExtrusion.cut(
        cutObj
    )  #Trims the top of the planar layer to ensure proper height and being flat
    planarLayer = FreeCAD.ActiveDocument.addObject("Part::Feature", "myPlanar")
    planarLayer.Shape = trimmedPlanar
    print("End planarize")
    return planarLayer
Example #38
0
    def run(self):

        """run(): Runs a nesting operation. Returns a list of lists of
           shapes, each primary list being one filled container, or None
           if the operation failed."""

        # reset abort mechanism and variables

        self.running = True
        self.progress = 0
        starttime = datetime.now()

        # general conformity tests

        print("Executing conformity tests ... ",end="")
        if not self.container:
            print("Empty container. Aborting")
            return
        if not self.shapes:
            print("Empty shapes. Aborting")
            return
        if not isinstance(self.container,Part.Face):
            print("Container is not a face. Aborting")
            return
        normal = self.container.normalAt(0,0)
        for s in self.shapes:
            if not self.update():
                return
            if len(s.Faces) != 1:
                print("One of the shapes does not contain exactly one face. Aborting")
                return
            # check if all faces correctly oriented (same normal)
            if s.Faces[0].normalAt(0,0).getAngle(normal) > TOLERANCE:
                # let pass faces with inverted normal
                if s.Faces[0].normalAt(0,0).getAngle(normal)-math.pi > TOLERANCE:
                    print("One of the face doesn't have the same orientation as the container. Aborting")
                    return

        # TODO
        # allow to use a non-rectangular container
        # manage margins/paddings
        # allow to prevent or force specific rotations for a piece

        # LONG-TERM TODO
        # add genetic algo to swap pieces, and check if the result is better

        # track progresses
        step = 100.0/(len(self.shapes)*len(ROTATIONS))

        # store hashCode together with the face so we can change the order
        # and still identify the original face, so we can calculate a transform afterwards
        self.indexedfaces = [[shape.hashCode(),shape] for shape in self.shapes]

        # build a clean copy so we don't touch the original
        faces = list(self.indexedfaces)

        # replace shapes by their face
        faces = [[f[0],f[1].Faces[0]] for f in faces]

        # order by area
        faces = sorted(faces,key=lambda face: face[1].Area)

        # discretize non-linear edges and remove holes
        nfaces = []
        for face in faces:
            if not self.update():
                return
            nedges = []
            allLines = True
            for edge in face[1].OuterWire.OrderedEdges:
                if isinstance(edge.Curve,(Part.LineSegment,Part.Line)):
                    nedges.append(edge)
                else:
                    allLines = False
                    last = edge.Vertexes[0].Point
                    for i in range(DISCRETIZE):
                        s = float(i+1)/DISCRETIZE
                        par = edge.FirstParameter + (edge.LastParameter-edge.FirstParameter)*s
                        new = edge.valueAt(par)
                        nedges.append(Part.LineSegment(last,new).toShape())
                        last = new
            f = Part.Face(Part.Wire(nedges))
            if not f.isValid():
                if allLines:
                    print("Invalid face found in set. Aborting")
                else:
                    print("Face distretizing failed. Aborting")
                return
            nfaces.append([face[0],f])
        faces = nfaces

        # container for sheets with a first, empty sheet
        sheets = [[]]

        print("Everything OK (",datetime.now()-starttime,")")

        # main loop

        facenumber = 1
        facesnumber = len(faces)

        #print("Vertices per face:",[len(face[1].Vertexes) for face in faces])

        while faces:

            print("Placing piece",facenumber,"/",facesnumber,"Area:",FreeCAD.Units.Quantity(faces[-1][1].Area,FreeCAD.Units.Area).getUserPreferred()[0],": ",end="")

            face = faces.pop()
            boc = self.container.BoundBox

            # this stores the available solutions for each rotation of a piece
            # contains [sheetnumber,face,xlength] lists,
            # face being [hascode,transformed face] and xlength
            # the X size of all boundboxes of placed pieces
            available = []

            # this stores the possible positions on a blank
            # sheet, in case we need to create a new one
            initials = []

            # this checks if the piece don't fit in the container
            unfit = True

            for rotation in ROTATIONS:

                if not self.update():
                    return

                self.progress += step

                print(rotation,", ",end="")
                hashcode = face[0]
                rotface = face[1].copy()
                if rotation:
                    rotface.rotate(rotface.CenterOfMass,normal,rotation)
                bof = rotface.BoundBox
                rotverts = self.order(rotface)
                #for i,v in enumerate(rotverts):
                #    Draft.makeText([str(i)],point=v)
                basepoint = rotverts[0] # leftmost point of the rotated face
                basecorner = boc.getPoint(0) # lower left corner of the container

                # See if the piece fits in the container dimensions
                if (bof.XLength < boc.XLength) and (bof.YLength < boc.YLength):
                    unfit = False

                # Get the fit polygon of the container
                # that is, the polygon inside which basepoint can
                # circulate, and the face still be fully inside the container

                v1 = basecorner.add(basepoint.sub(bof.getPoint(0)))
                v2 = v1.add(FreeCAD.Vector(0,boc.YLength-bof.YLength,0))
                v3 = v2.add(FreeCAD.Vector(boc.XLength-bof.XLength,0,0))
                v4 = v3.add(FreeCAD.Vector(0,-(boc.YLength-bof.YLength),0))
                binpol = Part.Face(Part.makePolygon([v1,v2,v3,v4,v1]))
                initials.append([binpol,[hashcode,rotface],basepoint])

                # check for available space on each existing sheet

                for sheetnumber,sheet in enumerate(sheets):
                    # Get the no-fit polygon for each already placed face in
                    # current sheet. That is, a polygon in which basepoint
                    # cannot be, if we want our face to not overlap with the
                    # placed face.
                    # To do this, we "circulate" the face around the placed face

                    if not self.update():
                        return

                    nofitpol = []
                    for placed in sheet:
                        pts = []
                        for placedvert in self.order(placed[1],right=True):
                            fpts = []
                            for i,rotvert in enumerate(rotverts):
                                if not self.update():
                                    return

                                facecopy = rotface.copy()
                                facecopy.translate(placedvert.sub(rotvert))

                                # test if all the points of the face are outside the
                                # placed face (except the base point, which is coincident)

                                outside = True
                                faceverts = self.order(facecopy)
                                for vert in faceverts:
                                    if (vert.sub(placedvert)).Length > TOLERANCE:
                                        if placed[1].isInside(vert,TOLERANCE,True):
                                            outside = False
                                            break

                                # also need to test for edge intersection, because even
                                # if all vertices are outside, the pieces could still
                                # overlap

                                if outside:
                                    for e1 in facecopy.OuterWire.Edges:
                                        for e2 in placed[1].OuterWire.Edges:
                                            if not self.update():
                                                return

                                            if True:
                                                # Draft code (SLOW)
                                                p = DraftGeomUtils.findIntersection(e1,e2)
                                                if p:
                                                    p = p[0]
                                                    p1 = e1.Vertexes[0].Point
                                                    p2 = e1.Vertexes[1].Point
                                                    p3 = e2.Vertexes[0].Point
                                                    p4 = e2.Vertexes[1].Point
                                                    if (p.sub(p1).Length > TOLERANCE) and (p.sub(p2).Length > TOLERANCE) \
                                                    and (p.sub(p3).Length > TOLERANCE) and (p.sub(p4).Length > TOLERANCE):
                                                        outside = False
                                                        break
                                            else:
                                                # alt code: using distToShape (EVEN SLOWER!)
                                                p = e1.distToShape(e2)
                                                if p:
                                                    if p[0] < TOLERANCE:
                                                        # allow vertex-to-vertex intersection
                                                        if (p[2][0][0] != "Vertex") or (p[2][0][3] != "Vertex"):
                                                            outside = False
                                                            break


                                if outside:
                                    fpts.append([faceverts[0],i])
                                    #Draft.makeText([str(i)],point=faceverts[0])

                            # reorder available solutions around a same point if needed
                            # ensure they are in the correct order

                            idxs = [p[1] for p in fpts]
                            if (0 in idxs) and (len(faceverts)-1 in idxs):
                                slicepoint = len(fpts)
                                last = len(faceverts)
                                for p in reversed(fpts):
                                    if p[1] == last-1:
                                        slicepoint -= 1
                                        last -= 1
                                    else:
                                        break
                                fpts = fpts[slicepoint:]+fpts[:slicepoint]
                                #print(fpts)
                            pts.extend(fpts)

                        # create the polygon

                        if len(pts) < 3:
                            print("Error calculating a no-fit polygon. Aborting")
                            return
                        pts = [p[0] for p in pts]
                        pol = Part.Face(Part.makePolygon(pts+[pts[0]]))

                        if not pol.isValid():

                            # fix overlapping edges

                            overlap = True
                            while overlap:
                                overlap = False
                                for i in range(len(pol.OuterWire.Edges)-1):
                                    if not self.update():
                                        return

                                    v1 = DraftGeomUtils.vec(pol.OuterWire.OrderedEdges[i])
                                    v2 = DraftGeomUtils.vec(pol.OuterWire.OrderedEdges[i+1])
                                    if abs(v1.getAngle(v2)-math.pi) <= TOLERANCE:
                                        overlap = True
                                        ne = Part.LineSegment(pol.OuterWire.OrderedEdges[i].Vertexes[0].Point,
                                                              pol.OuterWire.OrderedEdges[i+1].Vertexes[-1].Point).toShape()
                                        pol = Part.Face(Part.Wire(pol.OuterWire.OrderedEdges[:i]+[ne]+pol.OuterWire.OrderedEdges[i+2:]))
                                        break

                        if not pol.isValid():

                            # trying basic OCC fix

                            pol.fix(0,0,0)
                            if pol.isValid():
                                if pol.ShapeType == "Face":
                                    pol = Part.Face(pol.OuterWire) # discard possible inner holes
                                elif pol.Faces:
                                    # several faces after the fix, keep the biggest one
                                    a = 0
                                    ff = None
                                    for f in pol.Faces:
                                        if f.Area > a:
                                            a = f.Area
                                            ff = f
                                    if ff:
                                        pol = ff
                                else:
                                    print("Unable to fix invalid no-fit polygon. Aborting")
                                    Part.show(pol)
                                    return

                        if not pol.isValid():

                            # none of the fixes worked. Epic fail.

                            print("Invalid no-fit polygon. Aborting")
                            Part.show(pol.OuterWire)
                            for p in sheet:
                                Part.show(p[1])
                            Part.show(facecopy)
                            #for i,p in enumerate(faceverts):
                            #    Draft.makeText([str(i)],point=p)
                            return

                        if pol.isValid():
                            nofitpol.append(pol)
                            #Part.show(pol)

                    # Union all the no-fit pols into one

                    if len(nofitpol) == 1:
                        nofitpol = nofitpol[0]
                    elif len(nofitpol) > 1:
                        b = nofitpol.pop()
                        for n in nofitpol:
                            if not self.update():
                                return
                            b = b.fuse(n)
                        nofitpol = b

                        # remove internal edges (discard edges shared by 2 faces)

                        lut = {}
                        for f in fitpol.Faces:
                            for e in f.Edges:
                                h = e.hashCode()
                                if h in lut:
                                    lut[h].append(e)
                                else:
                                    lut[h] = [e]
                        edges = [e[0] for e in lut.values() if len(e) == 1]
                        try:
                            pol = Part.Face(Part.Wire(edges))
                        except Exception:
                            # above method can fail sometimes. Try a slower method
                            w = DraftGeomUtils.findWires(edges)
                            if len(w) == 1:
                                if w[0].isClosed():
                                    try:
                                        pol = Part.Face(w[0])
                                    except Exception:
                                        print("Error merging polygons. Aborting")
                                        try:
                                            Part.show(Part.Wire(edges))
                                        except Exception:
                                            for e in edges:
                                                Part.show(e)
                                        return

                    # subtract the no-fit polygon from the container's fit polygon
                    # we then have the zone where the face can be placed

                    if nofitpol:
                        fitpol = binpol.cut(nofitpol)
                    else:
                        fitpol = binpol.copy()

                    # check that we have some space on this sheet

                    if (fitpol.Area > 0) and fitpol.Vertexes:

                        # order the fitpol vertexes by smallest X
                        # and try to place the piece, making sure it doesn't
                        # intersect with already placed pieces
                        fitverts = sorted([v.Point for v in fitpol.Vertexes],key=lambda v: v.x)
                        for p in fitverts:
                            if not self.update():
                                return

                            trface = rotface.copy()
                            trface.translate(p.sub(basepoint))
                            ok = True
                            for placed in sheet:
                                if ok:
                                    for vert in trface.Vertexes:
                                        if placed[1].isInside(vert.Point,TOLERANCE,False):
                                            ok = False
                                            break
                                if ok:
                                    for e1 in trface.OuterWire.Edges:
                                        for e2 in placed[1].OuterWire.Edges:
                                            p = DraftGeomUtils.findIntersection(e1,e2)
                                            if p:
                                                p = p[0]
                                                p1 = e1.Vertexes[0].Point
                                                p2 = e1.Vertexes[1].Point
                                                p3 = e2.Vertexes[0].Point
                                                p4 = e2.Vertexes[1].Point
                                                if (p.sub(p1).Length > TOLERANCE) and (p.sub(p2).Length > TOLERANCE) \
                                                and (p.sub(p3).Length > TOLERANCE) and (p.sub(p4).Length > TOLERANCE):
                                                    ok = False
                                                    break
                                if not ok:
                                    break
                            if ok:
                                rotface = trface
                                break
                        else:
                            print("Couldn't determine location on sheet. Aborting")
                            return

                        # check the X space occupied by this solution

                        bb = rotface.BoundBox
                        for placed in sheet:
                            bb.add(placed[1].BoundBox)
                        available.append([sheetnumber,[hashcode,rotface],bb.XMax,fitpol])

            if unfit:
                print("One face doesn't fit in the container. Aborting")
                return

            if available:

                # order by smallest X size and take the first one
                available = sorted(available,key=lambda sol: sol[2])
                print("Adding piece to sheet",available[0][0]+1)
                sheets[available[0][0]].append(available[0][1])
                #Part.show(available[0][3])

            else:

                # adding to the leftmost vertex of the binpol

                sheet = []
                print("Creating new sheet, adding piece to sheet",len(sheets))
                # order initial positions by smallest X size
                initials = sorted(initials,key=lambda sol: sol[1][1].BoundBox.XLength)
                hashcode = initials[0][1][0]
                face = initials[0][1][1]
                # order binpol vertexes by X coord
                verts = sorted([v.Point for v in initials[0][0].Vertexes],key=lambda v: v.x)
                face.translate(verts[0].sub(initials[0][2]))
                sheet.append([hashcode,face])
                sheets.append(sheet)

            facenumber += 1

        print("Run time:",datetime.now()-starttime)
        self.results.append(sheets)
        return sheets
Example #39
0
    def makeStraightStairs(self, obj, edge, numberofsteps=None):

        "builds a simple, straight staircase from a straight edge"

        # general data
        import Part, DraftGeomUtils
        if not numberofsteps:
            numberofsteps = obj.NumberOfSteps
        v = DraftGeomUtils.vec(edge)
        vLength = DraftVecUtils.scaleTo(
            v,
            float(edge.Length) / (numberofsteps - 1))
        vLength = Vector(vLength.x, vLength.y, 0)
        if round(v.z, Draft.precision()) != 0:
            h = v.z
        else:
            h = obj.Height.Value
        vHeight = Vector(0, 0, float(h) / numberofsteps)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)),
                                       obj.Width.Value)
        vBase = edge.Vertexes[0].Point
        vNose = DraftVecUtils.scaleTo(vLength, -abs(obj.Nosing.Value))
        a = math.atan(vHeight.Length / vLength.Length)
        #print("stair data:",vLength.Length,":",vHeight.Length)

        # steps
        for i in range(numberofsteps - 1):
            p1 = vBase.add((Vector(vLength).multiply(i)).add(
                Vector(vHeight).multiply(i + 1)))
            p1 = self.align(p1, obj.Align, vWidth)
            p1 = p1.add(vNose).add(Vector(0, 0,
                                          -abs(obj.TreadThickness.Value)))
            p2 = p1.add(DraftVecUtils.neg(vNose)).add(vLength)
            p3 = p2.add(vWidth)
            p4 = p3.add(DraftVecUtils.neg(vLength)).add(vNose)
            step = Part.Face(Part.makePolygon([p1, p2, p3, p4, p1]))
            if obj.TreadThickness.Value:
                step = step.extrude(Vector(0, 0,
                                           abs(obj.TreadThickness.Value)))
                self.steps.append(step)
            else:
                self.pseudosteps.append(step)

        # structure
        lProfile = []
        struct = None
        if obj.Structure == "Massive":
            if obj.StructureThickness.Value:
                for i in range(numberofsteps - 1):
                    if not lProfile:
                        lProfile.append(vBase)
                    last = lProfile[-1]
                    if len(lProfile) == 1:
                        last = last.add(
                            Vector(0, 0, -abs(obj.TreadThickness.Value)))
                    lProfile.append(last.add(vHeight))
                    lProfile.append(lProfile[-1].add(vLength))
                resHeight1 = obj.StructureThickness.Value / math.cos(a)
                lProfile.append(lProfile[-1].add(Vector(0, 0, -resHeight1)))
                resHeight2 = ((numberofsteps - 1) * vHeight.Length) - (
                    resHeight1 + obj.TreadThickness.Value)
                resLength = (vLength.Length / vHeight.Length) * resHeight2
                h = DraftVecUtils.scaleTo(vLength, -resLength)
                lProfile.append(lProfile[-1].add(Vector(h.x, h.y,
                                                        -resHeight2)))
                lProfile.append(vBase)
                #print(lProfile)
                pol = Part.makePolygon(lProfile)
                struct = Part.Face(pol)
                evec = vWidth
                if obj.StructureOffset.Value:
                    mvec = DraftVecUtils.scaleTo(vWidth,
                                                 obj.StructureOffset.Value)
                    struct.translate(mvec)
                    evec = DraftVecUtils.scaleTo(
                        evec, evec.Length - (2 * mvec.Length))
                struct = struct.extrude(evec)
        elif obj.Structure in ["One stringer", "Two stringers"]:
            if obj.StringerWidth.Value and obj.StructureThickness.Value:
                hyp = math.sqrt(vHeight.Length**2 + vLength.Length**2)
                l1 = Vector(vLength).multiply(numberofsteps - 1)
                h1 = Vector(vHeight).multiply(numberofsteps - 1).add(
                    Vector(0, 0, -abs(obj.TreadThickness.Value)))
                p1 = vBase.add(l1).add(h1)
                p1 = self.align(p1, obj.Align, vWidth)
                lProfile.append(p1)
                h2 = (obj.StructureThickness.Value / vLength.Length) * hyp
                lProfile.append(lProfile[-1].add(Vector(0, 0, -abs(h2))))
                h3 = lProfile[-1].z - vBase.z
                l3 = (h3 / vHeight.Length) * vLength.Length
                v3 = DraftVecUtils.scaleTo(vLength, -l3)
                lProfile.append(lProfile[-1].add(Vector(0, 0,
                                                        -abs(h3))).add(v3))
                l4 = (obj.StructureThickness.Value / vHeight.Length) * hyp
                v4 = DraftVecUtils.scaleTo(vLength, -l4)
                lProfile.append(lProfile[-1].add(v4))
                lProfile.append(lProfile[0])
                #print(lProfile)
                pol = Part.makePolygon(lProfile)
                pol = Part.Face(pol)
                evec = DraftVecUtils.scaleTo(vWidth, obj.StringerWidth.Value)
                if obj.Structure == "One stringer":
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                    else:
                        mvec = DraftVecUtils.scaleTo(
                            vWidth,
                            (vWidth.Length / 2) - obj.StringerWidth.Value / 2)
                    pol.translate(mvec)
                    struct = pol.extrude(evec)
                elif obj.Structure == "Two stringers":
                    pol2 = pol.copy()
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                        pol.translate(mvec)
                        mvec = vWidth.add(mvec.negative())
                        pol2.translate(mvec)
                    else:
                        pol2.translate(vWidth)
                    s1 = pol.extrude(evec)
                    s2 = pol2.extrude(evec.negative())
                    struct = Part.makeCompound([s1, s2])
        if struct:
            self.structures.append(struct)
Example #40
0
def getCutVolume(cutplane,shapes):
    """getCutVolume(cutplane,shapes): returns a cut face and a cut volume
    from the given shapes and the given cutting plane"""
    if not shapes:
        return None,None,None
    import Part
    if not isinstance(shapes,list):
        shapes = [shapes]
    # building boundbox
    bb = shapes[0].BoundBox
    for sh in shapes[1:]:
        bb.add(sh.BoundBox)
    bb.enlarge(1)
    # building cutplane space
    placement = None
    um = vm = wm = 0
    try:
        if hasattr(cutplane,"Shape"):
            p = cutplane.Shape.copy().Faces[0]
        else:
            p = cutplane.copy().Faces[0]
    except:
        FreeCAD.Console.PrintMessage(translate("Arch","Invalid cutplane"))
        return None,None,None 
    ce = p.CenterOfMass
    ax = p.normalAt(0,0)
    u = p.Vertexes[1].Point.sub(p.Vertexes[0].Point).normalize()
    v = u.cross(ax)
    if not bb.isCutPlane(ce,ax):
        FreeCAD.Console.PrintMessage(translate("Arch","No objects are cut by the plane"))
        return None,None,None
    else:
        corners = [FreeCAD.Vector(bb.XMin,bb.YMin,bb.ZMin),
                   FreeCAD.Vector(bb.XMin,bb.YMax,bb.ZMin),
                   FreeCAD.Vector(bb.XMax,bb.YMin,bb.ZMin),
                   FreeCAD.Vector(bb.XMax,bb.YMax,bb.ZMin),
                   FreeCAD.Vector(bb.XMin,bb.YMin,bb.ZMax),
                   FreeCAD.Vector(bb.XMin,bb.YMax,bb.ZMax),
                   FreeCAD.Vector(bb.XMax,bb.YMin,bb.ZMax),
                   FreeCAD.Vector(bb.XMax,bb.YMax,bb.ZMax)]
        for c in corners:
            dv = c.sub(ce)
            um1 = DraftVecUtils.project(dv,u).Length
            um = max(um,um1)
            vm1 = DraftVecUtils.project(dv,v).Length
            vm = max(vm,vm1)
            wm1 = DraftVecUtils.project(dv,ax).Length
            wm = max(wm,wm1)
        vu = DraftVecUtils.scaleTo(u,um)
        vui = vu.negative()
        vv = DraftVecUtils.scaleTo(v,vm)
        vvi = vv.negative()
        p1 = ce.add(vu.add(vvi))
        p2 = ce.add(vu.add(vv))
        p3 = ce.add(vui.add(vv))
        p4 = ce.add(vui.add(vvi))
        cutface = Part.makePolygon([p1,p2,p3,p4,p1])
        cutface = Part.Face(cutface)
        cutnormal = DraftVecUtils.scaleTo(ax,wm)
        cutvolume = cutface.extrude(cutnormal)
        cutnormal = cutnormal.negative()
        invcutvolume = cutface.extrude(cutnormal)
        return cutface,cutvolume,invcutvolume
Example #41
0
def makeSolarDiagram(longitude, latitude, scale=1, complete=False):
    """makeSolarDiagram(longitude,latitude,[scale,complete]):
    returns a solar diagram as a pivy node. If complete is
    True, the 12 months are drawn"""

    from subprocess import call
    py3_failed = call(["python3", "-c", "import Pysolar"])

    if py3_failed:
        try:
            import Pysolar
        except:
            print(
                "Pysolar is not installed. Unable to generate solar diagrams")
            return None
    else:
        from subprocess import check_output

    from pivy import coin

    if not scale:
        return None

    def toNode(shape):
        "builds a pivy node from a simple linear shape"
        from pivy import coin
        buf = shape.writeInventor(2, 0.01)
        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)
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(line)
        return item

    circles = []
    sunpaths = []
    hourpaths = []
    circlepos = []
    hourpos = []

    # build the base circle + number positions
    import Part
    for i in range(1, 9):
        circles.append(Part.makeCircle(scale * (i / 8.0)))
    for ad in range(0, 360, 15):
        a = math.radians(ad)
        p1 = FreeCAD.Vector(math.cos(a) * scale, math.sin(a) * scale, 0)
        p2 = FreeCAD.Vector(
            math.cos(a) * scale * 0.125,
            math.sin(a) * scale * 0.125, 0)
        p3 = FreeCAD.Vector(
            math.cos(a) * scale * 1.08,
            math.sin(a) * scale * 1.08, 0)
        circles.append(Part.LineSegment(p1, p2).toShape())
        circlepos.append((ad, p3))

    # build the sun curves at solstices and equinoxe
    year = datetime.datetime.now().year
    hpts = [[] for i in range(24)]
    m = [(6, 21), (7, 21), (8, 21), (9, 21), (10, 21), (11, 21), (12, 21)]
    if complete:
        m.extend([(1, 21), (2, 21), (3, 21), (4, 21), (5, 21)])
    for i, d in enumerate(m):
        pts = []
        for h in range(24):
            if not py3_failed:
                dt = "datetime.datetime(%s, %s, %s, %s)" % (year, d[0], d[1],
                                                            h)
                alt_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_altitude_fast(%s, %s, %s))'" % (
                    latitude, longitude, dt)
                alt = math.radians(
                    float(check_output(alt_call, shell=True).strip()))
                az_call = "python3 -c 'import datetime,Pysolar; print (Pysolar.solar.get_azimuth(%s, %s, %s))'" % (
                    latitude, longitude, dt)
                az = float(
                    re.search('.+$', check_output(az_call,
                                                  shell=True)).group(0))
            else:
                dt = datetime.datetime(year, d[0], d[1], h)
                alt = math.radians(
                    Pysolar.solar.GetAltitudeFast(latitude, longitude, dt))
                az = Pysolar.solar.GetAzimuth(latitude, longitude, dt)
            az = -90 + az  # pysolar's zero is south
            if az < 0:
                az = 360 + az
            az = math.radians(az)
            zc = math.sin(alt) * scale
            ic = math.cos(alt) * scale
            xc = math.cos(az) * ic
            yc = math.sin(az) * ic
            p = FreeCAD.Vector(xc, yc, zc)
            pts.append(p)
            hpts[h].append(p)
            if i in [0, 6]:
                ep = FreeCAD.Vector(p)
                ep.multiply(1.08)
                if ep.z >= 0:
                    if h == 12:
                        if i == 0:
                            h = "SUMMER"
                        else:
                            h = "WINTER"
                        if latitude < 0:
                            if h == "SUMMER":
                                h = "WINTER"
                            else:
                                h = "SUMMER"
                    hourpos.append((h, ep))
        if i < 7:
            sunpaths.append(Part.makePolygon(pts))
    for h in hpts:
        if complete:
            h.append(h[0])
        hourpaths.append(Part.makePolygon(h))

    # cut underground lines
    sz = 2.1 * scale
    cube = Part.makeBox(sz, sz, sz)
    cube.translate(FreeCAD.Vector(-sz / 2, -sz / 2, -sz))
    sunpaths = [sp.cut(cube) for sp in sunpaths]
    hourpaths = [hp.cut(cube) for hp in hourpaths]

    # build nodes
    ts = 0.005 * scale  # text scale
    mastersep = coin.SoSeparator()
    circlesep = coin.SoSeparator()
    numsep = coin.SoSeparator()
    pathsep = coin.SoSeparator()
    hoursep = coin.SoSeparator()
    hournumsep = coin.SoSeparator()
    mastersep.addChild(circlesep)
    mastersep.addChild(numsep)
    mastersep.addChild(pathsep)
    mastersep.addChild(hoursep)
    for item in circles:
        circlesep.addChild(toNode(item))
    for item in sunpaths:
        for w in item.Edges:
            pathsep.addChild(toNode(w))
    for item in hourpaths:
        for w in item.Edges:
            hoursep.addChild(toNode(w))
    for p in circlepos:
        text = coin.SoText2()
        s = p[0] - 90
        s = -s
        if s > 360:
            s = s - 360
        if s < 0:
            s = 360 + s
        if s == 0:
            s = "N"
        elif s == 90:
            s = "E"
        elif s == 180:
            s = "S"
        elif s == 270:
            s = "W"
        else:
            s = str(s)
        text.string = s
        text.justification = coin.SoText2.CENTER
        coords = coin.SoTransform()
        coords.translation.setValue([p[1].x, p[1].y, p[1].z])
        coords.scaleFactor.setValue([ts, ts, ts])
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(text)
        numsep.addChild(item)
    for p in hourpos:
        text = coin.SoText2()
        s = str(p[0])
        text.string = s
        text.justification = coin.SoText2.CENTER
        coords = coin.SoTransform()
        coords.translation.setValue([p[1].x, p[1].y, p[1].z])
        coords.scaleFactor.setValue([ts, ts, ts])
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(text)
        numsep.addChild(item)
    return mastersep
Example #42
0
def createShape(obj):
	'''create the 2D or 3D mapping Shape for a wire and a base face
	the data are parameters of the obj
	 '''

#	print "CreateShape for obj:",obj.Label

	#pointCount=obj.pointcount
	#pointCount=50

	[uv2x,uv2y,xy2u,xy2v]=[obj.mapobject.Proxy.uv2x,obj.mapobject.Proxy.uv2y,obj.mapobject.Proxy.xy2u,obj.mapobject.Proxy.xy2v]

	if xy2v==None:
		print "Kann umkehrung nicht berechnen xy2v nicht vorhanden"
		return

	# diese daten vom mapobjekt lesen #+#

	mpv=0.5
	mpu=0.5

	u0=0
	v0=0

	fy=1.
	fx=1.

	#+# facenumer aus obj param holen
	face=obj.face.Shape.Face1
	bs=face.Surface
#	w=obj.wire.Shape.Wires[0]
	wires=obj.wire.Shape.Wires
	if len(wires)==0:
		wires=obj.wire.Shape.Edges

	ppall=[]

	pos=FreeCAD.Vector(obj.mapobject.Placement.Base.x,obj.mapobject.Placement.Base.y,0)

	for i,w in enumerate(wires):
		# print ("Wire ...",i,pointCount)
		FreeCAD.w=w
		for i,ee in enumerate(w.Edges):
			ct=max(int(round(ee.Length/obj.pointdist)),2)
			if i == 0:
				ptsaa= ee.discretize(ct)
			else:
				pts=ee.discretize(ct)
				if pts[-1]==ptsaa[-1]:
					pts=pts[::-1]
				ptsaa += pts[1:]

		pts=[p-pos for p in ptsaa]
		
		pts2=[]

		#refpos geht noch nicht
		mpv=0.
		mpu=0.

#		refpos=bs.value(mpu,mpv)
#		print ("refpos",mpu,mpv)
#		print refpos

		refpos=FreeCAD.Vector(0,0,0)

		for p in pts:

			y=fx*(p.x-refpos.x)
			x=fy*(p.y-refpos.y)

			#fuer ruled surface !!
			x=fx*p.y
			y=fy*p.x

			u=xy2u(x,y)
			v=xy2v(x,y)

##			su=face.ParameterRange[1]
##			sv=face.ParameterRange[3]



			sua=face.ParameterRange[0]
			sva=face.ParameterRange[2]
			sue=face.ParameterRange[1]
			sve=face.ParameterRange[3]
			sul=sue-sua
			svl=sve-sva

			#sua + svl*
			#sva + svl*


			#try: sweep=obj.face.TypeId=='Part::Sweep'
			#except: sweep=True


			if obj.mapobject.flipuv23: p2=bs.value(u,v)
			else: p2=bs.value(sva+u*svl,aua+v*sul)

			pts2.append(p2)

		FreeCAD.pts2a=pts2
		obj.Shape=Part.makePolygon(pts2)
Example #43
0
    def execute(self, obj):
        import Part
        plm = obj.Placement
        if obj.Base and (not obj.Tool):
            if obj.Base.isDerivedFrom("Sketcher::SketchObject"):
                shape = obj.Base.Shape.copy()
                if obj.Base.Shape.isClosed():
                    if hasattr(obj, "MakeFace"):
                        if obj.MakeFace:
                            shape = Part.Face(shape)
                    else:
                        shape = Part.Face(shape)
                obj.Shape = shape
        elif obj.Base and obj.Tool:
            if hasattr(obj.Base, 'Shape') and hasattr(obj.Tool, 'Shape'):
                if (not obj.Base.Shape.isNull()) and (
                        not obj.Tool.Shape.isNull()):
                    sh1 = obj.Base.Shape.copy()
                    sh2 = obj.Tool.Shape.copy()
                    shape = sh1.fuse(sh2)
                    if DraftGeomUtils.isCoplanar(shape.Faces):
                        shape = DraftGeomUtils.concatenate(shape)
                        obj.Shape = shape
                        p = []
                        for v in shape.Vertexes:
                            p.append(v.Point)
                        if obj.Points != p: obj.Points = p
        elif obj.Points:
            if obj.Points[0] == obj.Points[-1]:
                if not obj.Closed: obj.Closed = True
                obj.Points.pop()
            if obj.Closed and (len(obj.Points) > 2):
                pts = obj.Points
                if hasattr(obj, "Subdivisions"):
                    if obj.Subdivisions > 0:
                        npts = []
                        for i in range(len(pts)):
                            p1 = pts[i]
                            npts.append(pts[i])
                            if i == len(pts) - 1:
                                p2 = pts[0]
                            else:
                                p2 = pts[i + 1]
                            v = p2.sub(p1)
                            v = DraftVecUtils.scaleTo(
                                v, v.Length / (obj.Subdivisions + 1))
                            for j in range(obj.Subdivisions):
                                npts.append(
                                    p1.add(App.Vector(v).multiply(j + 1)))
                        pts = npts
                shape = Part.makePolygon(pts + [pts[0]])
                if "ChamferSize" in obj.PropertiesList:
                    if obj.ChamferSize.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.ChamferSize.Value,
                                                      chamfer=True)
                        if w:
                            shape = w
                if "FilletRadius" in obj.PropertiesList:
                    if obj.FilletRadius.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.FilletRadius.Value)
                        if w:
                            shape = w
                try:
                    if hasattr(obj, "MakeFace"):
                        if obj.MakeFace:
                            shape = Part.Face(shape)
                    else:
                        shape = Part.Face(shape)
                except Part.OCCError:
                    pass
            else:
                edges = []
                pts = obj.Points[1:]
                lp = obj.Points[0]
                for p in pts:
                    if not DraftVecUtils.equals(lp, p):
                        if hasattr(obj, "Subdivisions"):
                            if obj.Subdivisions > 0:
                                npts = []
                                v = p.sub(lp)
                                v = DraftVecUtils.scaleTo(
                                    v, v.Length / (obj.Subdivisions + 1))
                                edges.append(
                                    Part.LineSegment(lp, lp.add(v)).toShape())
                                lv = lp.add(v)
                                for j in range(obj.Subdivisions):
                                    edges.append(
                                        Part.LineSegment(lv,
                                                         lv.add(v)).toShape())
                                    lv = lv.add(v)
                            else:
                                edges.append(Part.LineSegment(lp, p).toShape())
                        else:
                            edges.append(Part.LineSegment(lp, p).toShape())
                        lp = p
                try:
                    shape = Part.Wire(edges)
                except Part.OCCError:
                    print("Error wiring edges")
                    shape = None
                if "ChamferSize" in obj.PropertiesList:
                    if obj.ChamferSize.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.ChamferSize.Value,
                                                      chamfer=True)
                        if w:
                            shape = w
                if "FilletRadius" in obj.PropertiesList:
                    if obj.FilletRadius.Value != 0:
                        w = DraftGeomUtils.filletWire(shape,
                                                      obj.FilletRadius.Value)
                        if w:
                            shape = w
            if shape:
                obj.Shape = shape
                if hasattr(obj, "Area") and hasattr(shape, "Area"):
                    obj.Area = shape.Area
                if hasattr(obj, "Length"):
                    obj.Length = shape.Length

        obj.Placement = plm
        obj.positionBySupport()
        self.onChanged(obj, "Placement")
Example #44
0
def run_FreeCAD_CurveOffset(self):
    import Part

    edge = self.getPinObject("Shape_in")

    if edge is None:
        sayW("no shape edge")
        return

    Z = FreeCAD.Vector(0, 0, 1)
    col = []

    lastdd = 100

    edstart = edge
    ed = edstart

    loops = self.getData("loops")
    for i in range(loops):

        cs = ed.Curve

        size = 300

        norms = []

        if i > 1:
            #step=self.getData("step")/10
            #size=int(round(edstart.Length/step))
            #tas=[]
            say("get distant points size ", size)
            points = cs.discretize(size + 1)

        else:
            deflection = self.getData("deflection")
            points = cs.discretize(QuasiDeflection=deflection * 0.001)

        for p in points:
            v = cs.parameter(p)
            t = cs.tangent(v)[0]
            norms += [t.cross(Z)]

        dd = self.getData("mindd") / 100

        if self.getData('flip'):
            dd = -dd

        distA = self.getData("distA")

        pts = []
        ptserr = []

        if 1:
            for n, p in zip(norms, points):
                neup = p + n * dd
                zp = edstart.distToShape(Part.Vertex(*neup))[1][0][0]

                if (p - zp).Length > distA * 0.01:
                    #say("ABweichung",(p-zp).Length)
                    #say("p",p)
                    #say("neup",neup)
                    #say("zp",zp)
                    #say(edstart.distToShape(Part.Vertex(*neup)))
                    if i == 0:
                        ptserr += [neup]
                    else:
                        pts += [neup]
                else:
                    pts += [neup]

        lp = len(pts)

        def checkcross(A, B, C, D):
            ''' schneiden sich die strecken AC und BD innen?'''

            a = C - A
            b = B - D
            c = B - A

            aa = np.array([[a.x, a.y], [b.x, b.y]])
            aa = np.array([[a.x, b.x], [a.y, b.y]])
            bb = np.array([c.x, c.y])
            x = np.linalg.solve(aa, bb)

            fa = 0 < x[0] and x[0] < 1
            fb = 0 < x[1] and x[1] < 1

            return fa and fb

        def cut(i, j):

            A = pts[i]
            B = pts[i + 1]
            C = pts[j]
            D = pts[j + 1]

            return checkcross(A, C, B, D)

        fehler = [0]
        for i in range(lp - 2):
            for j in range(lp - 2):
                if i >= j:
                    continue
                if cut(i, j):
                    fehler += [i, j]

        fehler += [-1]

        neupol = []

        for l in range(int(len(fehler) / 2)):
            neupol += pts[fehler[2 * l]:fehler[2 * l + 1]]

        neupol += pts[fehler[-1]:]
        pts = neupol

        col = [Part.makePolygon(pts)]
        FreeCADGui.updateGui()

        bc = Part.BSplineCurve()

        bc.buildFromPoles(pts)
        ed = bc.toShape()

        if not self.getData('asPolygon'):
            col = [ed]

        self.setPinObject("Shape_out", Part.Compound(col))
        self.outExec.call()

    ptsn = bc.discretize(size + 1)

    dists = [edstart.distToShape(Part.Vertex(*p))[0] for p in ptsn]
    say("distance expected min max", abs(dd), round(min(dists), 2),
        round(max(dists), 2))
Example #45
0
def smgetSubface(face, obj, edge, thk):
    # Project thickness side edge to get one side rectangle
    normal = face.normalAt(0, 0)
    faceVert = face.Vertexes[0].Point
    pt1 = edge.Vertexes[0].Point.projectToPlane(faceVert, normal)
    pt2 = edge.Vertexes[1].Point.projectToPlane(faceVert, normal)
    vec1 = (pt2 - pt1)

    # find min & max point of cut shape
    wallsolidlist = []
    for solid in obj.Solids:
        pt_list = []
        for vertex in solid.Vertexes:
            poi = vertex.Point
            pt = poi.projectToPlane(faceVert, normal)
            pt_list.append(pt)
        p1 = Base.Vector(min([pts.x for pts in pt_list]),
                         min([pts.y for pts in pt_list]),
                         min([pts.z for pts in pt_list]))
        p2 = Base.Vector(max([pts.x for pts in pt_list]),
                         max([pts.y for pts in pt_list]),
                         max([pts.z for pts in pt_list]))
        #print([p1, p2])

        # Find angle between diagonal & thickness side edge
        vec2 = (p2 - p1)
        angle1 = vec2.getAngle(vec1)
        angle = math.degrees(angle1)
        #print(angle)

        # Check & correct orientation of diagonal edge rotation
        e = Part.makeLine(p1, p2)
        e.rotate(p1, normal, -angle)
        vec2 = (e.valueAt(e.LastParameter) -
                e.valueAt(e.FirstParameter)).normalize()
        coeff = vec2.dot(vec1.normalize())
        #print(coeff)
        if coeff != 1.0:
            angle = 90 - angle

        # Create Cut Rectangle Face from min/max points & angle
        e = Part.Line(p1, p2).toShape()
        e1 = e.copy()
        e1.rotate(p1, normal, -angle)
        e2 = e.copy()
        e2.rotate(p2, normal, 90 - angle)
        section1 = e1.section(e2)
        #Part.show(section1,'section1')
        p3 = section1.Vertexes[0].Point
        e3 = e.copy()
        e3.rotate(p1, normal, 90 - angle)
        e4 = e.copy()
        e4.rotate(p2, normal, -angle)
        section2 = e3.section(e4)
        #Part.show(section2,'section2')
        p4 = section2.Vertexes[0].Point
        w = Part.makePolygon([p1, p3, p2, p4, p1])
        #Part.show(w, "wire")
        face = Part.Face(w)
        wallSolid = face.extrude(normal * -thk)
        wallsolidlist.append(wallSolid)
    return wallsolidlist
Example #46
0
    def execute(self,obj):
        
        tol = 1 # tolerance for alignment. This is only visual, we can keep it low...

        import math,Part,DraftGeomUtils,ArchCommands
        if len(obj.Pipes) < 2:
            return
        if len(obj.Pipes) > 3:
            FreeCAD.Console.PrintWarning(translate("Arch","Only the 3 first wires will be connected\n"))
        if obj.Radius.Value == 0:
            return
        wires = []
        order = []
        for o in obj.Pipes:
            wires.append(o.Proxy.getWire(o))
        if wires[0].Vertexes[0].Point == wires[1].Vertexes[0].Point:
            order = ["start","start"]
            point = wires[0].Vertexes[0].Point
        elif wires[0].Vertexes[0].Point == wires[1].Vertexes[-1].Point:
            order = ["start","end"]
            point = wires[0].Vertexes[0].Point
        elif wires[0].Vertexes[-1].Point == wires[1].Vertexes[-1].Point:
            order = ["end","end"]
            point = wires[0].Vertexes[-1].Point
        elif wires[0].Vertexes[-1].Point == wires[1].Vertexes[0].Point:
            order = ["end","start"]
            point = wires[0].Vertexes[-1].Point
        else:
            FreeCAD.Console.PrintError(translate("Arch","Common vertex not found\n"))
            return
        if order[0] == "start":
            v1 = wires[0].Vertexes[1].Point.sub(wires[0].Vertexes[0].Point).normalize()
        else:
            v1 = wires[0].Vertexes[-2].Point.sub(wires[0].Vertexes[-1].Point).normalize()
        if order[1] == "start":
            v2 = wires[1].Vertexes[1].Point.sub(wires[1].Vertexes[0].Point).normalize()
        else:
            v2 = wires[1].Vertexes[-2].Point.sub(wires[1].Vertexes[-1].Point).normalize()
        p = obj.Pipes[0].Proxy.getProfile(obj.Pipes[0])
        p = Part.Face(p)
        if len(obj.Pipes) == 2:
            if obj.ConnectorType != "Corner":
                obj.ConnectorType = "Corner"
            if round(v1.getAngle(v2),tol) in [0,round(math.pi,tol)]:
                FreeCAD.Console.PrintError(translate("Arch","Pipes are already aligned\n"))
                return
            normal = v2.cross(v1)
            offset = math.tan(math.pi/2-v1.getAngle(v2)/2)*obj.Radius.Value
            v1.multiply(offset)
            v2.multiply(offset)
            self.setOffset(obj.Pipes[0],order[0],offset)
            self.setOffset(obj.Pipes[1],order[1],offset)
            # find center
            perp = v1.cross(normal).normalize()
            perp.multiply(obj.Radius.Value)
            center = point.add(v1).add(perp)
            # move and rotate the profile to the first point
            delta = point.add(v1)-p.CenterOfMass
            p.translate(delta)
            vp = DraftGeomUtils.getNormal(p)
            rot = FreeCAD.Rotation(vp,v1)
            p.rotate(p.CenterOfMass,rot.Axis,math.degrees(rot.Angle))
            sh = p.revolve(center,normal,math.degrees(math.pi-v1.getAngle(v2)))
            #sh = Part.makeCompound([sh]+[Part.Vertex(point),Part.Vertex(point.add(v1)),Part.Vertex(center),Part.Vertex(point.add(v2))])
        else:
            if obj.ConnectorType != "Tee":
                obj.ConnectorType = "Tee"
            if wires[2].Vertexes[0].Point == point:
                order.append("start")
            elif wires[0].Vertexes[-1].Point == point:
                order.append("end")
            else:
                FreeCAD.Console.PrintError(translate("Arch","Common vertex not found\n"))
            if order[2] == "start":
                v3 = wires[2].Vertexes[1].Point.sub(wires[2].Vertexes[0].Point).normalize()
            else:
                v3 = wires[2].Vertexes[-2].Point.sub(wires[2].Vertexes[-1].Point).normalize()
            if round(v1.getAngle(v2),tol) in [0,round(math.pi,tol)]:
                pair = [v1,v2,v3]
            elif round(v1.getAngle(v3),tol) in [0,round(math.pi,tol)]:
                pair = [v1,v3,v2]
            elif round(v2.getAngle(v3),tol) in [0,round(math.pi,tol)]:
                pair = [v2,v3,v1]
            else:
                FreeCAD.Console.PrintError(translate("Arch","At least 2 pipes must aligned\n"))
                return
            offset = obj.Radius.Value
            v1.multiply(offset)
            v2.multiply(offset)
            v3.multiply(offset)
            self.setOffset(obj.Pipes[0],order[0],offset)
            self.setOffset(obj.Pipes[1],order[1],offset)
            self.setOffset(obj.Pipes[2],order[2],offset)
            normal = pair[0].cross(pair[2])
            # move and rotate the profile to the first point
            delta = point.add(pair[0])-p.CenterOfMass
            p.translate(delta)
            vp = DraftGeomUtils.getNormal(p)
            rot = FreeCAD.Rotation(vp,pair[0])
            p.rotate(p.CenterOfMass,rot.Axis,math.degrees(rot.Angle))
            t1 = p.extrude(pair[1].multiply(2))
            # move and rotate the profile to the second point
            delta = point.add(pair[2])-p.CenterOfMass
            p.translate(delta)
            vp = DraftGeomUtils.getNormal(p)
            rot = FreeCAD.Rotation(vp,pair[2])
            p.rotate(p.CenterOfMass,rot.Axis,math.degrees(rot.Angle))
            t2 = p.extrude(pair[2].negative().multiply(2))
            # create a cut plane
            cp = Part.makePolygon([point,point.add(pair[0]),point.add(normal),point])
            cp = Part.Face(cp)
            if cp.normalAt(0,0).getAngle(pair[2]) < math.pi/2:
                cp.reverse()
            cf, cv, invcv = ArchCommands.getCutVolume(cp,t2)
            t2 = t2.cut(cv)
            sh = t1.fuse(t2)
        obj.Shape = sh
Example #47
0
def createGrid(mapobj,upmode=False):
	'''create a 2D grid  or 3D grid (if upmode) for the map obj'''
 
	obj=mapobj
	
	try: 
		face=obj.faceObject.Shape.Faces[obj.faceNumber]
		bs=face.Surface
	except: return Part.Shape()
	
	print "createGrid for special faces"
	print face
	import numpy as np

	sf=face.Surface
	
	if sf.__class__.__name__ == 'Cone':

		alpha,beta,hmin,hmax = face.ParameterRange

		r2=sf.Radius
		r1=(sf.Apex-sf.Center).Length

		alpha=r2*np.pi/r1

		su=21
		sv=21

		pts=np.zeros(su*sv*3).reshape(su,sv,3)

		comp=[]
		for u in range(su):
			for v in range(sv):
				#print (beta-alpha)*u/2
				p=FreeCAD.Vector((r1+hmax*v/sv)*np.cos((alpha)*u/su),(r1+hmax*v/sv)*np.sin((alpha)*u/su))
				pts[u,v]=p


		for z in pts:
			comp += [Part.makePolygon([FreeCAD.Vector(p) for p in z])]

		pts=pts.swapaxes(0,1)
		for z in pts:
			comp += [Part.makePolygon([FreeCAD.Vector(p) for p in z])]

		#Part.show(Part.Compound(comp))

		return Part.Compound(comp)


#	face=obj.faceObject.Shape.Face1

#	mpu=obj.uMapCenter/100
#	mpv=obj.vMapCenter/100

	mpv=obj.uMapCenter/100
	mpu=obj.vMapCenter/100


	# skalierung/lage
	fx=obj.fx
	fy=obj.fy

	fz=1.0

	comps=[]

	refpos=bs.value(mpv,mpu)

	#su=bs.UPeriod()
	#sv=bs.VPeriod()
	
	print "hack DD suu asv"
	su=face.ParameterRange[1]
	sv=face.ParameterRange[3]


	if su>1000: su=face.ParameterRange[1]
	if sv>1000: sv=face.ParameterRange[3]

	# mittelpunkt
	
#	try: sweep=obj.Faceobject.TypeId=='Part::Sweep'
#	except: sweep=True


	sua=face.ParameterRange[0]
	sva=face.ParameterRange[2]
	sue=face.ParameterRange[1]
	sve=face.ParameterRange[3]
	sul=sue-sua
	svl=sve-sva

	#sua + svl*
	#sva + svl*


	if not obj.flipuv23:

		mpu2=sva+mpu*svl
		mpv2=aza+mpv*sul

	else:
		if upmode:
			mpu2=sua+mpu*sul
			mpv2=sva+mpv*svl
		else:
			mpu2=sva+mpu*svl
			mpv2=sua+mpv*sul



	mpu=mpv2
	mpv=mpu2



	vc=obj.uCount
	uc=obj.vCount

	print "isodraw #ll"
	print (su,sv)
	print (uc,vc)
	print face.ParameterRange


	ptsa=[]
	ptska=[]

	ba=bs.uIso(mpu)
	comps += [ba.toShape()]


	for v in range(vc+1):
		pts=[]
		vm=sva+1.0/vc*v*svl

		ky=ba.length(vm,mpv)

		if vm<mpv: ky =-ky
		bbc=bs.vIso(vm)

		comps += [bbc.toShape()]

		ptsk=[]
		for u in range(uc+1):
			uv=sua+1.0/uc*u*sul

			ba=bs.uIso(uv)

			ky=ba.length(vm,mpv)
			if vm<mpv: ky =-ky


			kx=bbc.length(mpu,uv)
			if uv<mpu: kx =-kx

			# ptsk.append(bs.value(vm,uv))
			ptsk.append(bs.value(uv,vm))

			pts.append([kx,ky,0])
			#print ("isodraw nknk",uv,vm,bs.value(uv,vm))

		ptsa.append(pts)
		ptska.append(ptsk)

#-----------------------------------------------

	[uv2x,uv2y,xy2u,xy2v]=getmap(mapobj,obj.faceObject)

	print "hier 3D Methode  ccc..oo.............."
	if obj.mode=='curvature':
		[uv2x,uv2y,uv2z,xy2u,xy2v]=getmap3(mapobj,obj.faceObject)
	ptsa=[]


	for v in range(vc+1):
		pts=[]
		z2=0
		z=0
		for u in range(uc+1):

				if mapobj.flipuv:
					uv=sua+1.0/uc*u*sul
					vv=sva+1.0/vc*v*svl
					vv2=sva+1.0/uc*u*svl
					uv2=sua+1.0/vc*v*sul
				else:
					vv=sua+1.0/uc*u*sul
					uv=sva+1.0/vc*v*svl
					uv2=sva+1.0/uc*u*svl
					vv2=sua+1.0/vc*v*sul


#				try: sweep=face.TypeId=='Part::Sweep'
#				except: sweep=True
#
#				sweep=True

				if 1 or ( mapobj.flipuv23 and upmode):
#					print "---------------------------RRRRRRRRRRRRRRRRRRR"
#					x=uv2x(vv,uv)
#					y=uv2y(vv,uv)
##					uv=sua+1.0/uc*(uc-u)*sul
					uv=sua+1.0/uc*(u)*sul
##					vv=sva+1.0/vc*(vc-v)*svl
					vv=sva+1.0/vc*(v)*svl

					x=uv2x(uv,vv)
					y=uv2y(uv,vv)
#					x=uv2x(vv,uv)
#					y=uv2y(vv,uv)



				else:
					x=uv2x(uv,vv)
					y=uv2y(uv,vv)

				if obj.mode=='curvature':
					#z=uv2z(uv,vv)
					# drekt nutzen statt interpolator
					#z=bs.curvature(vv,uv,"Mean")
					try:
						z2=bs.curvature(uv2,vv2,obj.modeCurvature)
					except:
						z2=0
					
					if z2<>0:r=round(1.0/z2)
					else: r='planar'
					if u>=mapobj.vMin-1 and u<=mapobj.vMax+1 and v>=mapobj.uMin-1 and v<=mapobj.uMax+1:
						print ("u,v, curvature,radius ",u,v,round(z2,6),r)

						if abs(z2)>0.001:
							print ("********** HIGH",u,v,z2,r)

					z=obj.factorCurvature*z2

				else: z=0
				#print z
#				print (x,y,z)
				pts.append(FreeCAD.Vector(x,y,z))

#				if u==5: 
#					print ("aadfdbbw--",uv,vv,z)
#					print (x,y)


		ptsa.append(pts)


	if upmode:


		print ("Rahmen 3D",obj.uMin,obj.uMax,obj.vMin,obj.vMax)
		print obj.faceObject.TypeId

#		try: sweep=obj.faceObject.TypeId=='Part::Sweep'
#		except: sweep=True

#		sweep=True
		if not obj.flipuv23:
			uMin,uMax,vMin,vMax=obj.uMin,obj.uMax,obj.vMin,obj.vMax
		else:
			vMin,vMax,uMin,uMax=obj.uMin,obj.uMax,obj.vMin,obj.vMax

		relpos=obj.Placement.Base*(-1)
		
		comps=[]

		for pts in ptska[uMin:uMax]:

			ll=[]
			for p in pts[vMin:vMax]:
				pmh=obj.Placement.inverse()
				vh=FreeCAD.Vector(tuple(p))
				th=FreeCAD.Placement()
				th.Base=vh
				t2=pmh.multiply(th)
				vh2=t2.Base
				ll += [vh2]
			try:
				comps += [ Part.makePolygon(ll) ]
			except: pass

		'''
		comps=[]

		for pts in ptska[obj.vMin:obj.vMax]:

			ll=[]
			for p in pts[obj.uMin:obj.uMax]:
				pmh=obj.Placement.inverse()
				vh=FreeCAD.Vector(tuple(p))
				th=FreeCAD.Placement()
				th.Base=vh
				t2=pmh.multiply(th)
				vh2=t2.Base
				ll += [vh2]

			comps += [ Part.makePolygon(ll) ]

		'''




		ptska=np.array(ptska).swapaxes(0,1)

		for pts in ptska[vMin:vMax]:

			ll=[]
			for p in pts[uMin:uMax]:
				pmh=obj.Placement.inverse()
				vh=FreeCAD.Vector(tuple(p))
				th=FreeCAD.Placement()
				th.Base=vh
				t2=pmh.multiply(th)
				vh2=t2.Base
				ll += [vh2]

			comps += [ Part.makePolygon(ll) ]
		

		# markiere zentrum der karte
		z=bs.value(sua+0.5*sul,sva+0.5*svl)
		circ=Part.Circle()
		circ.Radius=10

		th=FreeCAD.Placement()
		th.Base=z
		t2=pmh.multiply(th)
		circ.Location=t2.Base
		
		th=FreeCAD.Placement()
		th.Base=bs.normal(sua+0.5*sul,sva+0.5*svl)
		t2=pmh.multiply(th)

		circ.Axis=t2.Base
		if obj.displayCircles:
			comps += [circ.toShape()]

		# mapcenter

		z=bs.value(mpu,mpv)
		z=bs.value(mpv,mpu)

		circ=Part.Circle()
		circ.Radius=20


		th=FreeCAD.Placement()
		th.Base=z
		t2=pmh.multiply(th)
		circ.Location=t2.Base

		th=FreeCAD.Placement()
		th.Base=bs.normal(mpv,mpu)
		t2=th.multiply(pmh)
#		t2=pmh.multiply(th)

		# diese richtung stimmt noch nicht, deaktivert
##		circ.Axis=t2.Base

		if obj.displayCircles:
			comps += [circ.toShape()]

		return Part.Compound(comps)

	else: # 2d mode
		comps=[]

		# markiere zentrum der karte
		uv=sua+0.5*sul
		vm=sva+0.5*svl
		
		ky=ba.length(vm,mpv)
		if vm<mpv: ky =-ky

		kx=bbc.length(mpu,uv)
		if uv<mpu: kx =-kx

		if not obj.flipxy:
			z=FreeCAD.Vector(fy*ky,fx*kx,0)
		else:
			z=FreeCAD.Vector(fx*kx,fy*ky,0)

		circ=Part.Circle()
		circ.Radius=10
		circ.Location=z
		if obj.displayCircles:
			comps += [circ.toShape()]

		z=FreeCAD.Vector(0,0,0)
		circ=Part.Circle()
		circ.Radius=20
		circ.Location=z
		if obj.displayCircles:
			comps += [circ.toShape()]

		print ("Rahmen 2D",obj.uMin,obj.uMax,obj.vMin,obj.vMax)

		if obj.flipxy:
			if 1:
				for pts in ptsa[obj.uMin:obj.uMax]:
					try:
						comps += [ Part.makePolygon([FreeCAD.Vector(fx*p[1],fy*p[0],fz*p[2]) for p in pts[obj.vMin:obj.vMax]]) ]
					except: pass

				ptsa=np.array(ptsa).swapaxes(0,1)
				for pts in ptsa[obj.vMin:obj.vMax]:
					try:
						comps += [ Part.makePolygon([FreeCAD.Vector(fx*p[1],fy*p[0],fz*p[2]) for p in pts[obj.uMin:obj.uMax]]) ]
					except: pass

		else :
			if 1:
				for pts in ptsa[obj.uMin:obj.uMax]:
					comps += [ Part.makePolygon([FreeCAD.Vector(fx*p[0],fy*p[1],fz*p[2]) for p in pts[obj.vMin:obj.vMax]]) ]

				ptsa=np.array(ptsa).swapaxes(0,1)
				for pts in ptsa[obj.vMin:obj.vMax]:
					comps += [ Part.makePolygon([FreeCAD.Vector(fx*p[0],fy*p[1],fz*p[2]) for p in pts[obj.uMin:obj.uMax]]) ]

			else:
				for pts in ptsa[obj.vMin:obj.vMax]:
					comps += [ Part.makePolygon([FreeCAD.Vector(fx*p[0],fy*p[1],fz*p[2]) for p in pts[obj.vMin:obj.vMax]]) ]

				ptsa=np.array(ptsa).swapaxes(0,1)

				for pts in ptsa[obj.uMin:obj.uMax]:
					comps += [ Part.makePolygon([FreeCAD.Vector(fx*p[0],fy*p[1],fz*p[2]) for p in pts[obj.uMin:obj.uMax]]) ]




		return Part.Compound(comps)
Example #48
0
def createAll(mode="all",obj=None,dimU=500,dimV=500,
				ua=10,sizeU=100,va=10,sizeV=100,
				socketheight=10,saxonyflag=True,rowselector='',center=False,scale=1,
				createpart=False,createsurface=True 
			):




#	obj=App.ActiveDocument.Points
	print obj.Points.BoundBox.Center
	# center=False

	if center:
		zmin=obj.Points.BoundBox.ZMin -obj.Points.BoundBox.Center.z
		zmax=obj.Points.BoundBox.ZMax -obj.Points.BoundBox.Center.z
	else:
		zmin=obj.Points.BoundBox.ZMin
		zmax=obj.Points.BoundBox.ZMax

	p=obj.Points.Points


	if center:
		p=np.array(obj.Points.Points)- obj.Points.BoundBox.Center

	assert dimU*dimV==len(p)

#	if mode<>"all":
#		return


	zmin *=scale
	zmax *=scale
	socketheight *= scale
	p=[pp*scale for pp in p]


	pa2=np.array(p).reshape(dimU,dimV,3)

#	pa3=[]
#	a=0
#	for i in range(dimU):
#		if pa2[i][0][0]<>a:
#			pa3 += [pa2[i]] 
#			print pa2[i][0][0]-a
#		
#		print pa2[i][0]
#		a= pa2[i][0][0]

	# andere variante
	
	if saxonyflag:
		pa3=[]
		pmin=[]
		pmax=[]
		for i in range(dimU):
			if i%4==1:
				pmin += [pa2[i]]
			if i%4==3:
				pmax += [pa2[i]]
			if i%2==0:
				pa3 += [pa2[i]] 
			

	else:
		p3=p2
	pa4=np.array(pa3)
	pa4.shape
	
	if 0: # auswertung der anderen baender
		pmin=np.array(pmin)
		print pmin.shape
		pmax=np.array(pmax)
		print pmax.shape
		comp=[]
		for i in range(124):
			for j in range(500):
				if i<4 and j<4:
					print [pmin[i+1],j,pmax[i,j]]
				a=FreeCAD.Vector(pmin[i+1,j])
				b=FreeCAD.Vector(pmax[i,j])
				if a<>b:
					if b.z<a.z: a,b=b,a
					comp += [ Part.makePolygon([a,a+(b-a)*10])]
					

		print len(comp)
		Part.show(Part.Compound(comp))


#	return


	if 0:
		ta=time.time()
		ss=PointarrayToMesh(pa4[60:70,60:70])

		siz=10
		tb=time.time()
		bc=Part.BSplineSurface()
		bc.interpolate(pa4[100:100+siz,100:100+2*siz])
		tc=time.time()
		Part.show(bc.toShape())
		td=time.time()
		tc-tb
		td-tc


	#ss=PointarrayToMesh(pa4)

	if mode=='mesh':
		ta=time.time()
		if 0:
			ss=PointarrayToMesh(pa4,h=zmax)
			ss=PointarrayToMesh(pa4,h=zmin)

		tb=time.time()
		print "create meshes all", tb-ta

		ta=time.time()
		#ss=PointarrayToMesh(pa4)
		if 1:
			print ("!",zmax,zmin,socketheight)
			# ss=PointarrayToMesh(pa4[ua:ua+sizeU,va:va+2*sizeV],h=zmax+socketheight)
			ss=PointarrayToMesh(pa4[ua:ua+sizeU,va:va+2*sizeV],h=zmin-socketheight)

		tb=time.time()
		print "create meshes sub ", tb-ta
		#return


#	if not createsurface: return


	if mode=='part' or mode=='nurbs':
		#create nurbs face
		tb=time.time()
		bs=machFlaeche(pa4[ua:ua+sizeU,va:va+2*sizeV])
		tc=time.time()
		print "create surf 200 x 200 ", tc-tb

		if 0:
			tb=time.time()
			bs=machFlaeche(pa4,degree=3)
			tc=time.time()
			print "create surf all ", tc-tb


#	if not createpart: return
	if not mode=='part': return


	#create side faces
	ff=App.ActiveDocument.ActiveObject
	be=[]
	faces=[ff.Shape.Face1]
	for i,e in enumerate(ff.Shape.Face1.Edges):
		print e
		pa=e.Vertexes[0].Point
		pe=e.Vertexes[-1].Point

		h=zmin-socketheight
		pau=FreeCAD.Vector(pa.x,pa.y,h)
		peu=FreeCAD.Vector(pe.x,pe.y,h)

		e2=Part.makePolygon([pa,pau])
		e3=Part.makePolygon([peu,pe])
		e4=Part.makePolygon([pau,peu])

	#	Part.show(e2)
	#	Part.show(e3)
		Part.show(e4)
		App.activeDocument().recompute()
		eA=App.ActiveDocument.ActiveObject
		if i%2==0:
			be += [eA]

		Part.show(e)
		App.activeDocument().recompute()
		eB=App.ActiveDocument.ActiveObject
		
		rf=FreeCAD.ActiveDocument.addObject('Part::RuledSurface', 'Ruled Surface')
		rf.Curve1=(eA,['Edge1'])
		rf.Curve2=(eB,['Edge1'])
		App.activeDocument().recompute()
		faces += [rf.Shape.Face1]

	# create bottom face
	rf=FreeCAD.ActiveDocument.addObject('Part::RuledSurface', 'Ruled Surface')
	rf.Curve1=(be[0],['Edge1'])
	rf.Curve2=(be[1],['Edge1'])
	App.activeDocument().recompute()
	faces += [rf.Shape.Face1]


	#create shell and solid
	_=Part.Shell(faces)
	sh=App.ActiveDocument.addObject('Part::Feature','Shell2')
	sh.Shape=_.removeSplitter()
	del _
	App.activeDocument().recompute()

	shell=sh.Shape
	_=Part.Solid(shell)
	App.ActiveDocument.addObject('Part::Feature','Solid').Shape=_.removeSplitter()
	del _

	App.activeDocument().recompute()

	tc=time.time()

	# toUVMesh(bs)

	tc-tb
Example #49
0
    def _build_spline_sections(spline, sketch, interval):
        """
        Generate / regenerate the loft along a spline path
        """

        #reference spline curve object
        curve = spline.Shape.Curve

        #return first / last parameters
        [_a, _b] = spline.Shape.ParameterRange

        #round the length up and add one
        length = int(round(_b)) + 1

        comps = []
        z_up = App.Vector(0, 0, 1)

        #iterate the range of the length as integers
        i = 0.0
        step = 304.8 * interval

        sketch_points = []

        for vtx in sketch.Shape.Vertexes:
            sketch_points.append(vtx.Point)

        is_last_section = False

        while i <= length:

            #get the coordinate of the sweep path at the first millimeter
            origin = curve.value(i)

            #get the tangent of the sweep path at that coordinate
            tangent = curve.tangent(i)[0]

            #calculate the normal against z-up and normalize
            x_normal = tangent.cross(z_up).normalize()
            z_normal = tangent.cross(x_normal).normalize()

            #z-coordinate should always be positive
            if z_normal.z < 0.0:
                z_normal = z_normal.negative()

            poly_points = []

            for point in sketch_points:
                poly_points.append(origin + (point.x * x_normal) +
                                   (point.y * z_normal))

            poly_points.append(origin)

            #generate a polygon of the points and save it
            comps += [Part.makePolygon(poly_points)]

            i += step

            if i > length:
                if not is_last_section:
                    i = length
                    is_last_section = True

        return comps
Example #50
0
def createMeshView(obj,
                   direction=FreeCAD.Vector(0, 0, -1),
                   outeronly=False,
                   largestonly=False):
    """createMeshView(obj,[direction,outeronly,largestonly]): creates a flat shape that is the
    projection of the given mesh object in the given direction (default = on the XY plane). If
    outeronly is True, only the outer contour is taken into consideration, discarding the inner
    holes. If largestonly is True, only the largest segment of the given mesh will be used."""

    import Mesh, math, Part, DraftGeomUtils
    if not obj.isDerivedFrom("Mesh::Feature"):
        return
    mesh = obj.Mesh

    # 1. Flattening the mesh
    proj = []
    for f in mesh.Facets:
        nf = []
        for v in f.Points:
            v = FreeCAD.Vector(v)
            a = v.negative().getAngle(direction)
            l = math.cos(a) * v.Length
            p = v.add(FreeCAD.Vector(direction).multiply(l))
            p = DraftVecUtils.rounded(p)
            nf.append(p)
        proj.append(nf)
    flatmesh = Mesh.Mesh(proj)

    # 2. Removing wrong faces
    facets = []
    for f in flatmesh.Facets:
        if f.Normal.getAngle(direction) < math.pi:
            facets.append(f)
    cleanmesh = Mesh.Mesh(facets)

    #Mesh.show(cleanmesh)

    # 3. Getting the bigger mesh from the planar segments
    if largestonly:
        c = cleanmesh.getSeparateComponents()
        #print(c)
        cleanmesh = c[0]
        segs = cleanmesh.getPlanarSegments(1)
        meshes = []
        for s in segs:
            f = [cleanmesh.Facets[i] for i in s]
            meshes.append(Mesh.Mesh(f))
        a = 0
        for m in meshes:
            if m.Area > a:
                boundarymesh = m
                a = m.Area
        #Mesh.show(boundarymesh)
        cleanmesh = boundarymesh

    # 4. Creating a Part and getting the contour

    shape = None
    for f in cleanmesh.Facets:
        p = Part.makePolygon(f.Points + [f.Points[0]])
        #print(p,len(p.Vertexes),p.isClosed())
        try:
            p = Part.Face(p)
            if shape:
                shape = shape.fuse(p)
            else:
                shape = p
        except Part.OCCError:
            pass
    shape = shape.removeSplitter()

    # 5. Extracting the largest wire

    if outeronly:
        count = 0
        largest = None
        for w in shape.Wires:
            if len(w.Vertexes) > count:
                count = len(w.Vertexes)
                largest = w
        if largest:
            try:
                f = Part.Face(w)
            except Part.OCCError:
                print("Unable to produce a face from the outer wire.")
            else:
                shape = f

    return shape
Example #51
0
def map3Dgridto2Dgrid():
	# 3D Edges auf 2D Edges

	s0=Gui.Selection.getSelection()
	base=s0[-1]

	if hasattr(base,"faceObject"):
		face=base.faceObject
		mapobj=base
	else:
		face=base
		mapobj=None


	s=s0[:-1]
	if len(s0)==1:
		s=s0

	print s0

	polcol=[]
	for wire in s:
		print wire.Label
		[uv2x,uv2y,xy2u,xy2v]=getmap(mapobj,face)

		# bs=face.Shape.Face1.Surface
		bs=face.Shape.Faces[base.faceNumber].Surface
		pts2=[]
		firstEdge=True
		n=0
		for e in wire.Shape.Edges:
			#print e
			n +=1
			# if n>6: break
			# auf 5 millimeter genau
			if mapobj<>None:
				dd=mapobj.pointsPerEdge
			else:
				dd=int(round(e.Length/5))
				dd=30
			dd=3
			ptsa=e.discretize(dd)
			#if not firstEdge:
			#	pts=ptsa[1:]
			#else:
			pts=ptsa
			firstEdge=False

			FreeCAD.ptsaa=pts
			
			ptsb=[]
			for p in pts:
#				(u,v)=bs.parameter(p)
				(v,u)=bs.parameter(p)

#				print "hack A su sv aa bb"
#				su=face.Shape.Face1.ParameterRange[1]
#				sv=face.Shape.Face1.ParameterRange[3]
#
#				if su>1000: su=face.ParameterRange[1]
#				if sv>1000: sv=face.ParameterRange[3]

				sua=face.ParameterRange[0]
				sva=face.ParameterRange[2]
				sue=face.ParameterRange[1]
				sve=face.ParameterRange[3]
				sul=sue-sua
				svl=sve-sva



				v=(v-sva)/svl
				u=(u-sua)/sul
				
				x=uv2x(u,v)
				y=uv2y(u,v)
				if mapobj<>None and mapobj.flipxy:
					p2=FreeCAD.Vector(y,x,0)
				else:
					p2=FreeCAD.Vector(-y,-x,0)
				# hack richgtung beim Schuh
				p2=FreeCAD.Vector(y,x,0)

				ptsb.append(p2)

			if len(ptsb)>1:
				try:
					polcol += [Part.makePolygon(ptsb)]
				except:
					print "kann kein polygon bauen"
					print ptsb

		#Draft.makeWire(pts2)
	Part.show(Part.Compound(polcol))
Example #52
0
def makeSolarDiagram(longitude, latitude, scale=1, complete=False, tz=None):
    """makeSolarDiagram(longitude,latitude,[scale,complete,tz]):
    returns a solar diagram as a pivy node. If complete is
    True, the 12 months are drawn. Tz is the timezone related to
    UTC (ex: -3 = UTC-3)"""

    oldversion = False
    try:
        import pysolar
    except:
        try:
            import Pysolar as pysolar
        except:
            FreeCAD.Console.PrintError(
                "The pysolar module was not found. Unable to generate solar diagrams\n"
            )
            return None
        else:
            oldversion = True

    from pivy import coin

    if not scale:
        return None

    if tz:
        tz = datetime.timezone(datetime.timedelta(hours=-3))
    else:
        tz = datetime.timezone.utc

    def toNode(shape):
        "builds a pivy node from a simple linear shape"
        from pivy import coin
        buf = shape.writeInventor(2, 0.01)
        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)
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(line)
        return item

    circles = []
    sunpaths = []
    hourpaths = []
    circlepos = []
    hourpos = []

    # build the base circle + number positions
    import Part
    for i in range(1, 9):
        circles.append(Part.makeCircle(scale * (i / 8.0)))
    for ad in range(0, 360, 15):
        a = math.radians(ad)
        p1 = FreeCAD.Vector(math.cos(a) * scale, math.sin(a) * scale, 0)
        p2 = FreeCAD.Vector(
            math.cos(a) * scale * 0.125,
            math.sin(a) * scale * 0.125, 0)
        p3 = FreeCAD.Vector(
            math.cos(a) * scale * 1.08,
            math.sin(a) * scale * 1.08, 0)
        circles.append(Part.LineSegment(p1, p2).toShape())
        circlepos.append((ad, p3))

    # build the sun curves at solstices and equinoxe
    year = datetime.datetime.now().year
    hpts = [[] for i in range(24)]
    m = [(6, 21), (7, 21), (8, 21), (9, 21), (10, 21), (11, 21), (12, 21)]
    if complete:
        m.extend([(1, 21), (2, 21), (3, 21), (4, 21), (5, 21)])
    for i, d in enumerate(m):
        pts = []
        for h in range(24):
            if oldversion:
                dt = datetime.datetime(year, d[0], d[1], h)
                alt = math.radians(
                    pysolar.solar.GetAltitudeFast(latitude, longitude, dt))
                az = pysolar.solar.GetAzimuth(latitude, longitude, dt)
                az = -90 + az  # pysolar's zero is south, ours is X direction
            else:
                dt = datetime.datetime(year, d[0], d[1], h, tzinfo=tz)
                alt = math.radians(
                    pysolar.solar.get_altitude_fast(latitude, longitude, dt))
                az = pysolar.solar.get_azimuth(latitude, longitude, dt)
                az = 90 + az  # pysolar's zero is north, ours is X direction
            if az < 0:
                az = 360 + az
            az = math.radians(az)
            zc = math.sin(alt) * scale
            ic = math.cos(alt) * scale
            xc = math.cos(az) * ic
            yc = math.sin(az) * ic
            p = FreeCAD.Vector(xc, yc, zc)
            pts.append(p)
            hpts[h].append(p)
            if i in [0, 6]:
                ep = FreeCAD.Vector(p)
                ep.multiply(1.08)
                if ep.z >= 0:
                    if not oldversion:
                        h = 24 - h  # not sure why this is needed now... But it is.
                    if h == 12:
                        if i == 0:
                            h = "SUMMER"
                        else:
                            h = "WINTER"
                        if latitude < 0:
                            if h == "SUMMER":
                                h = "WINTER"
                            else:
                                h = "SUMMER"
                    hourpos.append((h, ep))
        if i < 7:
            sunpaths.append(Part.makePolygon(pts))
    for h in hpts:
        if complete:
            h.append(h[0])
        hourpaths.append(Part.makePolygon(h))

    # cut underground lines
    sz = 2.1 * scale
    cube = Part.makeBox(sz, sz, sz)
    cube.translate(FreeCAD.Vector(-sz / 2, -sz / 2, -sz))
    sunpaths = [sp.cut(cube) for sp in sunpaths]
    hourpaths = [hp.cut(cube) for hp in hourpaths]

    # build nodes
    ts = 0.005 * scale  # text scale
    mastersep = coin.SoSeparator()
    circlesep = coin.SoSeparator()
    numsep = coin.SoSeparator()
    pathsep = coin.SoSeparator()
    hoursep = coin.SoSeparator()
    hournumsep = coin.SoSeparator()
    mastersep.addChild(circlesep)
    mastersep.addChild(numsep)
    mastersep.addChild(pathsep)
    mastersep.addChild(hoursep)
    for item in circles:
        circlesep.addChild(toNode(item))
    for item in sunpaths:
        for w in item.Edges:
            pathsep.addChild(toNode(w))
    for item in hourpaths:
        for w in item.Edges:
            hoursep.addChild(toNode(w))
    for p in circlepos:
        text = coin.SoText2()
        s = p[0] - 90
        s = -s
        if s > 360:
            s = s - 360
        if s < 0:
            s = 360 + s
        if s == 0:
            s = "N"
        elif s == 90:
            s = "E"
        elif s == 180:
            s = "S"
        elif s == 270:
            s = "W"
        else:
            s = str(s)
        text.string = s
        text.justification = coin.SoText2.CENTER
        coords = coin.SoTransform()
        coords.translation.setValue([p[1].x, p[1].y, p[1].z])
        coords.scaleFactor.setValue([ts, ts, ts])
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(text)
        numsep.addChild(item)
    for p in hourpos:
        text = coin.SoText2()
        s = str(p[0])
        text.string = s
        text.justification = coin.SoText2.CENTER
        coords = coin.SoTransform()
        coords.translation.setValue([p[1].x, p[1].y, p[1].z])
        coords.scaleFactor.setValue([ts, ts, ts])
        item = coin.SoSeparator()
        item.addChild(coords)
        item.addChild(text)
        numsep.addChild(item)
    return mastersep
Example #53
0
    def createGeometry(self,obj):
        import Part, DraftGeomUtils
        
        # getting default values
        height = width = length = 1
        if hasattr(obj,"Length"):
            if obj.Length:
                length = obj.Length
        if hasattr(obj,"Width"):
            if obj.Width:
                width = obj.Width
        if hasattr(obj,"Height"):
            if obj.Height:
                height = obj.Height

        # creating base shape
        pl = obj.Placement
        base = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Normal == Vector(0,0,0):
                    p = FreeCAD.Placement(obj.Base.Placement)
                    normal = p.Rotation.multVec(Vector(0,0,1))
                else:
                    normal = Vector(obj.Normal)
                normal = normal.multiply(height)
                base = obj.Base.Shape.copy()
                if base.Solids:
                    pass
                elif base.Faces:
                    base = base.extrude(normal)
                elif (len(base.Wires) == 1):
                    if base.Wires[0].isClosed():
                        base = Part.Face(base.Wires[0])
                        base = base.extrude(normal)                
        else:
            if obj.Normal == Vector(0,0,0):
                normal = Vector(0,0,1)
            else:
                normal = Vector(obj.Normal)
            normal = normal.multiply(height)
            l2 = length/2 or 0.5
            w2 = width/2 or 0.5
            v1 = Vector(-l2,-w2,0)
            v2 = Vector(l2,-w2,0)
            v3 = Vector(l2,w2,0)
            v4 = Vector(-l2,w2,0)
            base = Part.makePolygon([v1,v2,v3,v4,v1])
            base = Part.Face(base)
            base = base.extrude(normal)
            
        if base:
            # applying adds and subs
            if not base.isNull():
                for app in obj.Additions:
                    if hasattr(app,"Shape"):
                        if not app.Shape.isNull():
                            base = base.fuse(app.Shape)
                            app.ViewObject.hide() # to be removed
                for hole in obj.Subtractions:
                    if hasattr(hole,"Shape"):
                        if not hole.Shape.isNull():
                            base = base.cut(hole.Shape)
                            hole.ViewObject.hide() # to be removed
            pts = self.getAxisPoints(obj)
            if pts:
                fsh = []
                for p in pts:
                    sh = base.copy()
                    sh.translate(p)
                    fsh.append(sh)
                    obj.Shape = Part.makeCompound(fsh)
            else:
                if base:
                    if not base.isNull():
                        base = base.removeSplitter()
                        obj.Shape = base
            if not DraftGeomUtils.isNull(pl):
                obj.Placement = pl
Example #54
0
LEidx = int(.1 * xDisc)  #chord point index included in LE refinement
extradosLine = []
intradosLine = []
LELines = []
TELines = []
print("Creating stations")
for i in geom:
    if i[4] == 'cylinder':
        extradosPts = profil(float(i[3]), i[4], float(i[5]), "extrados",
                             1 / 1000.)
        intradosPts = profil(float(i[3]), i[4], float(i[5]), "intrados",
                             1 / 1000.)
    else:
        extradosPts = profil(float(i[3]), i[4], float(i[5]), "extrados", TEGap)
        intradosPts = profil(float(i[3]), i[4], float(i[5]), "intrados", TEGap)
    extradosLineOrig = Part.makePolygon(
        [Base.Vector(x[0], x[1], float(i[1])) for x in extradosPts])
    intradosLineOrig = Part.makePolygon(
        [Base.Vector(x[0], x[1], float(i[1])) for x in intradosPts])
    extradosLineOrig.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1),
                            float(i[2]) + pitch - 90)
    intradosLineOrig.rotate(Base.Vector(0, 0, 0), Base.Vector(0, 0, 1),
                            float(i[2]) + pitch - 90)
    extradosPtsInterp = numpy.array(extradosLineOrig.discretize(xDisc))
    intradosPtsInterp = numpy.array(intradosLineOrig.discretize(xDisc))
    extradosInterp = Part.makePolygon(
        [Base.Vector(x[0], x[1], x[2]) for x in extradosPtsInterp])
    intradosInterp = Part.makePolygon(
        [Base.Vector(x[0], x[1], x[2]) for x in intradosPtsInterp])
    extradosLine.append(extradosInterp)
    intradosLine.append(intradosInterp)
    LELines.append(
Example #55
0
    def alignToSelection(self, offset=0):
        """Align the plane to a selection if it defines a plane.

        If the selection uniquely defines a plane it will be used.

        Parameter
        ---------
        offset : float
            Defaults to zero. A value which will be used to offset
            the plane in the direction of its `axis`.

        Returns
        -------
        bool
            `True` if the operation was successful, and `False` otherwise.
            It returns `False` if the selection has no elements,
            or if the object is not derived from `'Part::Feature'`
            or if the object doesn't have a `Shape`.

        See Also
        --------
        alignToFace, alignToCurve
        """
        sel_ex = FreeCADGui.Selection.getSelectionEx(
            FreeCAD.ActiveDocument.Name)
        if not sel_ex:
            return False

        shapes = list()
        names = list()
        for obj in sel_ex:
            # check that the geometric property is a Part.Shape object
            geom_is_shape = False
            if isinstance(obj.Object, FreeCAD.GeoFeature):
                geom = obj.Object.getPropertyOfGeometry()
                if isinstance(geom, Part.Shape):
                    geom_is_shape = True
            if not geom_is_shape:
                FreeCAD.Console.PrintError(
                    translate(
                        "draft",
                        "Object without Part.Shape geometry:'{}'\n".format(
                            obj.ObjectName)))
                return False
            if geom.isNull():
                FreeCAD.Console.PrintError(
                    translate(
                        "draft",
                        "Object with null Part.Shape geometry:'{}'\n".format(
                            obj.ObjectName)))
                return False
            if obj.HasSubObjects:
                shapes.extend(obj.SubObjects)
                names.extend(
                    [obj.ObjectName + "." + n for n in obj.SubElementNames])
            else:
                shapes.append(geom)
                names.append(obj.ObjectName)

        normal = None
        for n in range(len(shapes)):
            if not DraftGeomUtils.is_planar(shapes[n]):
                FreeCAD.Console.PrintError(
                    translate("draft",
                              "'{}' object is not planar\n".format(names[n])))
                return False
            if not normal:
                normal = DraftGeomUtils.get_normal(shapes[n])
                shape_ref = n

        # test if all shapes are coplanar
        if normal:
            for n in range(len(shapes)):
                if not DraftGeomUtils.are_coplanar(shapes[shape_ref],
                                                   shapes[n]):
                    FreeCAD.Console.PrintError(
                        translate(
                            "draft", "{} and {} aren't coplanar\n".format(
                                names[shape_ref], names[n])))
                    return False
        else:
            # suppose all geometries are straight lines or points
            points = [
                vertex.Point for shape in shapes for vertex in shape.Vertexes
            ]
            if len(points) >= 3:
                poly = Part.makePolygon(points)
                if not DraftGeomUtils.is_planar(poly):
                    FreeCAD.Console.PrintError(
                        translate("draft", "All Shapes must be coplanar\n"))
                    return False
                normal = DraftGeomUtils.get_normal(poly)
            else:
                normal = None

        if not normal:
            FreeCAD.Console.PrintError(
                translate("draft", "Selected Shapes must define a plane\n"))
            return False

        # set center of mass
        ctr_mass = FreeCAD.Vector(0, 0, 0)
        ctr_pts = FreeCAD.Vector(0, 0, 0)
        mass = 0
        for shape in shapes:
            if hasattr(shape, "CenterOfMass"):
                ctr_mass += shape.CenterOfMass * shape.Mass
                mass += shape.Mass
            else:
                ctr_pts += shape.Point
        if mass > 0:
            ctr_mass /= mass
        # all shapes are vertexes
        else:
            ctr_mass = ctr_pts / len(shapes)

        self.alignToPointAndAxis(ctr_mass, normal, offset)

        return True
Example #56
0
 def getProfiles(self, obj, noplacement=False):
     "Returns the base profile(s) of this component, if applicable"
     wires = []
     n, l, w, h = self.getDefaultValues(obj)
     if obj.Base:
         if obj.Base.isDerivedFrom("Part::Feature"):
             if obj.Base.Shape:
                 base = obj.Base.Shape.copy()
                 if noplacement:
                     base.Placement = FreeCAD.Placement()
                 if not base.Solids:
                     if base.Faces:
                         return [base]
                     basewires = []
                     if not base.Wires:
                         if len(base.Edges) == 1:
                             import Part
                             basewires = [Part.Wire(base.Edges)]
                     else:
                         basewires = base.Wires
                     if basewires:
                         import DraftGeomUtils, DraftVecUtils, Part
                         for wire in basewires:
                             e = wire.Edges[0]
                             if isinstance(e.Curve, Part.Circle):
                                 dvec = e.Vertexes[0].Point.sub(
                                     e.Curve.Center)
                             else:
                                 dvec = DraftGeomUtils.vec(
                                     wire.Edges[0]).cross(n)
                             if not DraftVecUtils.isNull(dvec):
                                 dvec.normalize()
                             sh = None
                             if hasattr(obj, "Align"):
                                 if obj.Align == "Left":
                                     dvec.multiply(w)
                                     if hasattr(obj, "Offset"):
                                         if obj.Offset.Value:
                                             dvec2 = DraftVecUtils.scaleTo(
                                                 dvec, obj.Offset.Value)
                                             wire = DraftGeomUtils.offsetWire(
                                                 wire, dvec2)
                                     w2 = DraftGeomUtils.offsetWire(
                                         wire, dvec)
                                     w1 = Part.Wire(
                                         DraftGeomUtils.sortEdges(
                                             wire.Edges))
                                     sh = DraftGeomUtils.bind(w1, w2)
                                 elif obj.Align == "Right":
                                     dvec.multiply(w)
                                     dvec = dvec.negative()
                                     if hasattr(obj, "Offset"):
                                         if obj.Offset.Value:
                                             dvec2 = DraftVecUtils.scaleTo(
                                                 dvec, obj.Offset.Value)
                                             wire = DraftGeomUtils.offsetWire(
                                                 wire, dvec2)
                                     w2 = DraftGeomUtils.offsetWire(
                                         wire, dvec)
                                     w1 = Part.Wire(
                                         DraftGeomUtils.sortEdges(
                                             wire.Edges))
                                     sh = DraftGeomUtils.bind(w1, w2)
                                 elif obj.Align == "Center":
                                     dvec.multiply(w / 2)
                                     w1 = DraftGeomUtils.offsetWire(
                                         wire, dvec)
                                     dvec = dvec.negative()
                                     w2 = DraftGeomUtils.offsetWire(
                                         wire, dvec)
                                     sh = DraftGeomUtils.bind(w1, w2)
                                 if sh:
                                     wires.append(sh)
                             else:
                                 wires.append(wire)
     else:
         if (Draft.getType(obj) == "Structure") and (l > h):
             if noplacement:
                 h2 = h / 2 or 0.5
                 w2 = w / 2 or 0.5
                 v1 = Vector(-h2, -w2, 0)
                 v2 = Vector(h2, -w2, 0)
                 v3 = Vector(h2, w2, 0)
                 v4 = Vector(-h2, w2, 0)
             else:
                 h2 = h / 2 or 0.5
                 w2 = w / 2 or 0.5
                 v1 = Vector(0, -w2, -h2)
                 v2 = Vector(0, -w2, h2)
                 v3 = Vector(0, w2, h2)
                 v4 = Vector(0, w2, -h2)
         else:
             l2 = l / 2 or 0.5
             w2 = w / 2 or 0.5
             v1 = Vector(-l2, -w2, 0)
             v2 = Vector(l2, -w2, 0)
             v3 = Vector(l2, w2, 0)
             v4 = Vector(-l2, w2, 0)
         import Part
         base = Part.makePolygon([v1, v2, v3, v4, v1])
         return [base]
     return wires
Example #57
0
 def makePolygon(cls, listOfVertices, forConstruction=False):
     # convert list of tuples into Vectors.
     w = Wire(FreeCADPart.makePolygon([i.wrapped for i in listOfVertices]))
     w.forConstruction = forConstruction
     return w
Example #58
0
def helix2(points):  # гвинтова лінія з відхиленнями
    pts = [(x, y, z) for t, x, y, z in points]
    h = Part.makePolygon(pts)
    return h
Example #59
0
def runB():
    ''' testcase for a expression baes mountain profile '''

    import numpy as np
    print "WARNING:this is a testcase only"
    # hard coded test data
    kl = App.ActiveDocument.subedge
    kr = App.ActiveDocument.subedge001

    kali = kl.Shape.Edge1.Curve.getPoles()
    kare = kr.Shape.Edge1.Curve.getPoles()

    lena = len(kali)

    l0 = (kali[0] - kare[0]).Length

    scales = [(kali[i] - kare[i]).Length / l0 for i in range(lena)]

    rots = [0.0] + [(kali[i] - kare[i]).normalize().cross(
        (kali[0] - kare[0]).normalize()).dot(FreeCAD.Vector(0, 0, 1))
                    for i in range(1, lena)]
    rots = np.arcsin(rots)

    apts = []
    for i in range(lena):
        yy = (kare[0] - kali[0]) * scales[i]

        polyp = [
            FreeCAD.Vector(),
            FreeCAD.Vector(0, 0, 115),
            FreeCAD.Vector(0, 0, 130),
            ((kare[0] - kali[0]) * 0.3 + FreeCAD.Vector(0, 0, 200)) *
            scales[i],
            ((kare[0] - kali[0]) * 0.3 + FreeCAD.Vector(0, 0, 200)) * scales[i]
            + FreeCAD.Vector(40, 0, 0),
            ((kare[0] - kali[0]) * 0.3 + FreeCAD.Vector(0, 0, 200)) * scales[i]
            + FreeCAD.Vector(80, 0, 0),
            yy + FreeCAD.Vector(0, 0, 50),
            yy + FreeCAD.Vector(0, 0, 25),
            yy + FreeCAD.Vector(),
        ]

        pol = Part.makePolygon(polyp)

        if 1:  # display the control points polygons
            res = App.ActiveDocument.addObject("Part::Spline",
                                               "aa" + str(i) + "__")
            res.Shape = pol
            res.Placement = FreeCAD.Placement(
                kali[i], FreeCAD.Rotation()).multiply(
                    FreeCAD.Placement(
                        FreeCAD.Vector(),
                        FreeCAD.Rotation(FreeCAD.Vector(0, 0, 1),
                                         -180.0 * rots[i] / np.pi)))

#		print kali[i]
#		print rots[i]
#		print scales[i]

        pts = [v.Point for v in res.Shape.Vertexes]
        apts += [pts]

    machFlaeche(np.array(apts))

    # display the controlpoint curves
    bpts = np.array(apts).swapaxes(0, 1)
    for l in bpts:
        machkurve(l)
Example #60
0
    def makeStraightLanding(self, obj, edge, numberofsteps=None):

        "builds a landing from a straight edge"

        # general data
        if not numberofsteps:
            numberofsteps = obj.NumberOfSteps
        import Part, DraftGeomUtils
        v = DraftGeomUtils.vec(edge)
        vLength = Vector(v.x, v.y, 0)
        vWidth = vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)),
                                                obj.Width.Value)
        vBase = edge.Vertexes[0].Point
        vNose = DraftVecUtils.scaleTo(vLength, -abs(obj.Nosing.Value))
        h = obj.Height.Value
        l = obj.Length.Value
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                l = obj.Base.Shape.Length
                if obj.Base.Shape.BoundBox.ZLength:
                    h = obj.Base.Shape.BoundBox.ZLength
        fLength = float(l - obj.Width.Value) / (numberofsteps - 2)
        fHeight = float(h) / numberofsteps
        a = math.atan(fHeight / fLength)
        print("landing data:", fLength, ":", fHeight)

        # step
        p1 = self.align(vBase, obj.Align, vWidth)
        p1 = p1.add(vNose).add(Vector(0, 0, -abs(obj.TreadThickness.Value)))
        p2 = p1.add(DraftVecUtils.neg(vNose)).add(vLength)
        p3 = p2.add(vWidth)
        p4 = p3.add(DraftVecUtils.neg(vLength)).add(vNose)
        step = Part.Face(Part.makePolygon([p1, p2, p3, p4, p1]))
        if obj.TreadThickness.Value:
            step = step.extrude(Vector(0, 0, abs(obj.TreadThickness.Value)))
            self.steps.append(step)
        else:
            self.pseudosteps.append(step)

        # structure
        lProfile = []
        struct = None
        p7 = None
        p1 = p1.add(DraftVecUtils.neg(vNose))
        p2 = p1.add(Vector(0, 0, -fHeight)).add(
            Vector(0, 0, -obj.StructureThickness.Value / math.cos(a)))
        resheight = p1.sub(p2).Length - obj.StructureThickness.Value
        reslength = resheight / math.tan(a)
        p3 = p2.add(DraftVecUtils.scaleTo(vLength, reslength)).add(
            Vector(0, 0, resheight))
        p6 = p1.add(vLength)
        if obj.TreadThickness.Value:
            p7 = p6.add(Vector(0, 0, obj.TreadThickness.Value))

        reslength = fLength + (
            obj.StructureThickness.Value / math.sin(a) -
            (fHeight - obj.TreadThickness.Value) / math.tan(a))
        if p7:
            p5 = p7.add(DraftVecUtils.scaleTo(vLength, reslength))
        else:
            p5 = p6.add(DraftVecUtils.scaleTo(vLength, reslength))
        resheight = obj.StructureThickness.Value + obj.TreadThickness.Value
        reslength = resheight / math.tan(a)
        p4 = p5.add(DraftVecUtils.scaleTo(vLength, -reslength)).add(
            Vector(0, 0, -resheight))
        if obj.Structure == "Massive":
            if obj.StructureThickness.Value:
                if p7:
                    struct = Part.Face(
                        Part.makePolygon([p1, p2, p3, p4, p5, p7, p6, p1]))
                else:
                    struct = Part.Face(
                        Part.makePolygon([p1, p2, p3, p4, p5, p6, p1]))
                evec = vWidth
                if obj.StructureOffset.Value:
                    mvec = DraftVecUtils.scaleTo(vWidth,
                                                 obj.StructureOffset.Value)
                    struct.translate(mvec)
                    evec = DraftVecUtils.scaleTo(
                        evec, evec.Length - (2 * mvec.Length))
                struct = struct.extrude(evec)
        elif obj.Structure in ["One stringer", "Two stringers"]:
            if obj.StringerWidth.Value and obj.StructureThickness.Value:
                p1b = p1.add(Vector(0, 0, -fHeight))
                reslength = fHeight / math.tan(a)
                p1c = p1.add(DraftVecUtils.scaleTo(vLength, reslength))
                p5b = None
                p5c = None
                if obj.TreadThickness.Value:
                    reslength = obj.StructureThickness.Value / math.sin(a)
                    p5b = p5.add(DraftVecUtils.scaleTo(vLength, -reslength))
                    reslength = obj.TreadThickness.Value / math.tan(a)
                    p5c = p5b.add(DraftVecUtils.scaleTo(
                        vLength, -reslength)).add(
                            Vector(0, 0, -obj.TreadThickness.Value))
                    pol = Part.Face(
                        Part.makePolygon(
                            [p1c, p1b, p2, p3, p4, p5, p5b, p5c, p1c]))
                else:
                    pol = Part.Face(
                        Part.makePolygon([p1c, p1b, p2, p3, p4, p5, p1c]))
                evec = DraftVecUtils.scaleTo(vWidth, obj.StringerWidth.Value)
                if obj.Structure == "One stringer":
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                    else:
                        mvec = DraftVecUtils.scaleTo(
                            vWidth,
                            (vWidth.Length / 2) - obj.StringerWidth.Value / 2)
                    pol.translate(mvec)
                    struct = pol.extrude(evec)
                elif obj.Structure == "Two stringers":
                    pol2 = pol.copy()
                    if obj.StructureOffset.Value:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset.Value)
                        pol.translate(mvec)
                        mvec = vWidth.add(mvec.negative())
                        pol2.translate(mvec)
                    else:
                        pol2.translate(vWidth)
                    s1 = pol.extrude(evec)
                    s2 = pol2.extrude(evec.negative())
                    struct = Part.makeCompound([s1, s2])
        if struct:
            self.structures.append(struct)