def getGlobalRot(self,point):
     "Same as getGlobalCoords, but discards the WP position"
     vx = Vector(self.u).multiply(point.x)
     vy = Vector(self.v).multiply(point.y)
     vz = Vector(self.axis).multiply(point.z)
     pt = (vx.add(vy)).add(vz)
     return pt
 def getGlobalCoords(self,point):
     "returns the global coordinates of the given point, taken relatively to this working plane"
     vx = Vector(self.u).multiply(point.x)
     vy = Vector(self.v).multiply(point.y)
     vz = Vector(self.axis).multiply(point.z)
     pt = (vx.add(vy)).add(vz)
     return pt.add(self.position)
Beispiel #3
0
    def makeStraightStairsWithLanding(self,obj,edge):
        
        "builds a straight staircase with a landing in the middle"

        if obj.NumberOfSteps < 3:
            return
        import Part,DraftGeomUtils
        v = DraftGeomUtils.vec(edge)
        reslength = edge.Length - obj.Width.Value
        vLength = DraftVecUtils.scaleTo(v,float(reslength)/(obj.NumberOfSteps-2))
        vLength = Vector(vLength.x,vLength.y,0)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0,0,1)),obj.Width.Value)
        p1 = edge.Vertexes[0].Point
        if round(v.z,Draft.precision()) != 0:
            h = v.z
        else:
            h = obj.Height.Value
        hstep = h/obj.NumberOfSteps
        landing = obj.NumberOfSteps/2
        p2 = p1.add(DraftVecUtils.scale(vLength,landing-1).add(Vector(0,0,landing*hstep)))
        p3 = p2.add(DraftVecUtils.scaleTo(vLength,obj.Width.Value))
        p4 = p3.add(DraftVecUtils.scale(vLength,obj.NumberOfSteps-(landing+1)).add(Vector(0,0,(obj.NumberOfSteps-landing)*hstep)))
        self.makeStraightStairs(obj,Part.Line(p1,p2).toShape(),landing)
        self.makeStraightLanding(obj,Part.Line(p2,p3).toShape())
        self.makeStraightStairs(obj,Part.Line(p3,p4).toShape(),obj.NumberOfSteps-landing)
Beispiel #4
0
def removeShape(objs, mark=True):
    """takes an arch object (wall or structure) built on a cubic shape, and removes
    the inner shape, keeping its length, width and height as parameters."""
    import DraftGeomUtils

    if not isinstance(objs, list):
        objs = [objs]
    for obj in objs:
        if DraftGeomUtils.isCubic(obj.Shape):
            dims = DraftGeomUtils.getCubicDimensions(obj.Shape)
            if dims:
                name = obj.Name
                tp = Draft.getType(obj)
                print tp
                if tp == "Structure":
                    FreeCAD.ActiveDocument.removeObject(name)
                    import ArchStructure

                    str = ArchStructure.makeStructure(length=dims[1], width=dims[2], height=dims[3], name=name)
                    str.Placement = dims[0]
                elif tp == "Wall":
                    FreeCAD.ActiveDocument.removeObject(name)
                    import ArchWall

                    length = dims[1]
                    width = dims[2]
                    v1 = Vector(length / 2, 0, 0)
                    v2 = v1.negative()
                    v1 = dims[0].multVec(v1)
                    v2 = dims[0].multVec(v2)
                    line = Draft.makeLine(v1, v2)
                    wal = ArchWall.makeWall(line, width=width, height=dims[3], name=name)
        else:
            if mark:
                obj.ViewObject.ShapeColor = (1.0, 0.0, 0.0, 1.0)
Beispiel #5
0
    def constrain(self,point,basepoint=None,axis=None):
        '''constrain(point,basepoint=None,axis=None: Returns a
        constrained point. Axis can be "x","y" or "z" or a custom vector. If None,
        the closest working plane axis will be picked.
        Basepoint is the base point used to figure out from where the point
        must be constrained. If no basepoint is given, the current point is
        used as basepoint.'''

        # without the Draft module fully loaded, no axes system!"
        if not hasattr(FreeCAD,"DraftWorkingPlane"):
            return point

        point = Vector(point)

        # setup trackers if needed
        if not self.constrainLine:
            self.constrainLine = DraftTrackers.lineTracker(dotted=True)

        # setting basepoint
        if not basepoint:
            if not self.basepoint:
                self.basepoint = point
        else:
            self.basepoint = basepoint
        delta = point.sub(self.basepoint)

        # setting constraint axis
        if not self.affinity:
            self.affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(delta)
        if isinstance(axis,FreeCAD.Vector):
            self.constraintAxis = axis
        elif axis == "x":
            self.constraintAxis = FreeCAD.DraftWorkingPlane.u
        elif axis == "y":
            self.constraintAxis = FreeCAD.DraftWorkingPlane.v
        elif axis == "z":
            self.constraintAxis = FreeCAD.DraftWorkingPlane.axis
        else:
            if self.affinity == "x":
                self.constraintAxis = FreeCAD.DraftWorkingPlane.u
            elif self.affinity == "y":
                self.constraintAxis = FreeCAD.DraftWorkingPlane.v
            else:
                self.constraintAxis = FreeCAD.DraftWorkingPlane.axis
                
        # calculating constrained point
        cdelta = fcvec.project(delta,self.constraintAxis)
        npoint = self.basepoint.add(cdelta)

        # setting constrain line
        if self.constrainLine:
            if point != npoint:
                self.constrainLine.p1(point)
                self.constrainLine.p2(npoint)
                self.constrainLine.on()
            else:
                self.constrainLine.off()
		
        return npoint       
 def getDeviation(self):
     "returns the deviation angle between the u axis and the horizontal plane"
     proj = Vector(self.u.x,self.u.y,0)
     if self.u.getAngle(proj) == 0:
         return 0
     else:
         norm = proj.cross(self.u)
         return DraftVecUtils.angle(self.u,proj,norm)
def equals(p1, p2):
    '''returns True if vertexes have same coordinates within precision amount of digits '''
    precision = 12
    p = precision
    u = Vector(p1.X, p1.Y, p1.Z)
    v = Vector(p2.X, p2.Y, p2.Z)
    vector = (u.sub(v))
    isNull = (round(vector.x, p) == 0 and round(vector.y, p) == 0 and round(vector.z, p) == 0)
    return isNull
    def alignToPointAndAxis_SVG(self, point, axis, offset):
        # based on cases table
        self.doc = FreeCAD.ActiveDocument
        self.axis = axis;
        self.axis.normalize()
        ref_vec = Vector(0.0, 1.0, 0.0)

        if ((abs(axis.x) > abs(axis.y)) and (abs(axis.y) > abs(axis.z))):
            ref_vec = Vector(0.0, 0., 1.0)
            self.u = axis.negative().cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi/2, self.axis)
            #projcase = "Case new"
        
        elif ((abs(axis.y) > abs(axis.z)) and (abs(axis.z) >= abs(axis.x))):
            ref_vec = Vector(1.0, 0.0, 0.0)
            self.u = axis.negative().cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi/2, self.axis)
            #projcase = "Y>Z, View Y"

        elif ((abs(axis.y) >= abs(axis.x)) and (abs(axis.x) > abs(axis.z))):
            ref_vec = Vector(0.0, 0., 1.0)
            self.u = axis.cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi/2, self.axis)
            #projcase = "ehem. XY, Case XY"

        elif ((abs(axis.x) > abs(axis.z)) and (abs(axis.z) >= abs(axis.y))):
            self.u = axis.cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi/2, self.axis)
            #projcase = "X>Z, View X"

        elif ((abs(axis.z) >= abs(axis.y)) and (abs(axis.y) > abs(axis.x))):
            ref_vec = Vector(1.0, 0., 0.0)
            self.u = axis.cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi/2, self.axis)
            #projcase = "Y>X, Case YZ"

        else:
            self.u = axis.negative().cross(ref_vec)
            self.u.normalize()
            self.v = DraftVecUtils.rotate(self.u, math.pi/2, self.axis)
            #projcase = "else"

        #spat_vec = self.u.cross(self.v)
        #spat_res = spat_vec.dot(axis)
        #FreeCAD.Console.PrintMessage(projcase + " spat Prod = " + str(spat_res) + "\n")
        
        offsetVector = Vector(axis); offsetVector.multiply(offset)
        self.position = point.add(offsetVector)
        self.weak = False
 def __init__(self):
     # keep track of active document.  Reset view when doc changes.
     self.doc = None
     # self.weak is true if the plane has been defined by self.setup or has been reset
     self.weak = True
     # u, v axes and position define plane, perpendicular axis is handy, though redundant.
     self.u = Vector(1,0,0)
     self.v = Vector(0,1,0)
     self.axis = Vector(0,0,1)
     self.position = Vector(0,0,0)
     # a placeholder for a stored state
     self.stored = None
 def projectPointOld(self, p, direction=None):
     '''project point onto plane, default direction is orthogonal. Obsolete'''
     if not direction:
         direction = self.axis
     t = Vector(direction)
     #t.normalize()
     a = round(t.getAngle(self.axis),DraftVecUtils.precision())
     pp = round((math.pi)/2,DraftVecUtils.precision())
     if a == pp:
         return p
     t.multiply(self.offsetToPoint(p, direction))
     return p.add(t)
 def setString(self,text=None):
     "sets the dim string to the given value or auto value"
     self.dimnode.param1.setValue(.5)
     p1 = Vector(self.dimnode.pnts.getValues()[0].getValue())
     p2 = Vector(self.dimnode.pnts.getValues()[-1].getValue())
     m = self.dimnode.datumtype.getValue()
     if m == 2:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(1,0,0))).Length
     elif m == 3:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(0,1,0))).Length
     else:
         self.Distance = (p2.sub(p1)).Length 
     if not text:
         text = Draft.getParam("dimPrecision",2)
         text = "%."+str(text)+"f"
         text = (text % self.Distance)
     self.dimnode.string.setValue(text)
Beispiel #12
0
 def __init__(self, dotted=False, scolor=None, swidth=None):
     self.origin = Vector(0, 0, 0)
     line = coin.SoLineSet()
     line.numVertices.setValue(5)
     self.coords = coin.SoCoordinate3()  # this is the coordinate
     self.coords.point.setValues(0, 5, [[0, 0, 0], [2, 0, 0], [2, 2, 0], [0, 2, 0], [0, 0, 0]])
     Tracker.__init__(self, dotted, scolor, swidth, [self.coords, line])
     self.u = plane.u
     self.v = plane.v
 def alignToPointAndAxis(self, point, axis, offset, upvec=None):
     self.doc = FreeCAD.ActiveDocument
     self.axis = axis;
     self.axis.normalize()
     if (DraftVecUtils.equals(axis, Vector(1,0,0))):
         self.u = Vector(0,1,0)
         self.v = Vector(0,0,1)
     elif (DraftVecUtils.equals(axis, Vector(-1,0,0))):
         self.u = Vector(0,-1,0)
         self.v = Vector(0,0,1)
     elif upvec:
         self.v = upvec
         self.v.normalize()
         self.u = self.v.cross(self.axis)
     else:
         self.v = axis.cross(Vector(1,0,0))
         self.v.normalize()
         self.u = DraftVecUtils.rotate(self.v, -math.pi/2, self.axis)
     offsetVector = Vector(axis); offsetVector.multiply(offset)
     self.position = point.add(offsetVector)
     self.weak = False
 def __init__(self,dotted=False,scolor=None,swidth=None,face=False):
     self.origin = Vector(0,0,0)
     line = coin.SoLineSet()
     line.numVertices.setValue(5)
     self.coords = coin.SoCoordinate3() # this is the coordinate
     self.coords.point.setValues(0,50,[[0,0,0],[2,0,0],[2,2,0],[0,2,0],[0,0,0]])
     if face:
         m1 = coin.SoMaterial()
         m1.transparency.setValue(0.5)
         m1.diffuseColor.setValue([0.5,0.5,1.0])
         f = coin.SoIndexedFaceSet()
         f.coordIndex.setValues([0,1,2,3])
         Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line,m1,f],name="rectangleTracker")
     else:
         Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line],name="rectangleTracker")
     self.u = FreeCAD.DraftWorkingPlane.u
     self.v = FreeCAD.DraftWorkingPlane.v
Beispiel #15
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

            # 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():
                        base = base.removeSplitter()
                        obj.Shape = base
                if not DraftGeomUtils.isNull(pl):
                    obj.Placement = pl
Beispiel #16
0
 def getExtrusionData(self,obj):
     """returns (shape,extrusion vector,placement) or None"""
     import Part,DraftGeomUtils
     data = ArchComponent.Component.getExtrusionData(self,obj)
     if data:
         if not isinstance(data[0],list):
             # multifuses not considered here
             return data
     length  = obj.Length.Value
     width = obj.Width.Value
     height = obj.Height.Value
     if not height:
         for p in obj.InList:
             if Draft.getType(p) == "Floor":
                 if p.Height.Value:
                     height = p.Height.Value
     if obj.Normal == Vector(0,0,0):
         normal = Vector(0,0,1)
     else:
         normal = Vector(obj.Normal)
     base = None
     placement = None
     basewires = None
     if obj.Base:
         if obj.Base.isDerivedFrom("Part::Feature"):
             if obj.Base.Shape:
                 if obj.Base.Shape.Solids:
                     return None
                 elif obj.Face > 0:
                     if len(obj.Base.Shape.Faces) >= obj.Face:
                         face = obj.Base.Shape.Faces[obj.Face-1]
                         # this wall is based on a specific face of its base object
                         normal = face.normalAt(0,0)
                         if normal.getAngle(Vector(0,0,1)) > math.pi/4:
                             normal.multiply(width)
                             base = face.extrude(normal)
                             if obj.Align == "Center":
                                 base.translate(normal.negative().multiply(0.5))
                             elif obj.Align == "Right":
                                 base.translate(normal.negative())
                         else:
                             normal.multiply(height)
                             base = face.extrude(normal)
                         base,placement = self.rebase(base)
                         return (base,normal,placement)
                 elif obj.Base.Shape.Faces:
                     if not DraftGeomUtils.isCoplanar(obj.Base.Shape.Faces):
                         return None
                     else:
                         base,placement = self.rebase(obj.Base.Shape)
                 elif obj.Base.Shape.Wires:
                     basewires = obj.Base.Shape.Wires
                 elif len(obj.Base.Shape.Edges) == 1:
                     basewires = [Part.Wire(obj.Base.Shape.Edges)]
                 if basewires and width:
                     baseface = None
                     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(normal)
                         if not DraftVecUtils.isNull(dvec):
                             dvec.normalize()
                         sh = None
                         if obj.Align == "Left":
                             dvec.multiply(width)
                             if obj.Offset.Value:
                                 dvec2 = DraftVecUtils.scaleTo(dvec,obj.Offset.Value)
                                 wire = DraftGeomUtils.offsetWire(wire,dvec2)
                             w2 = DraftGeomUtils.offsetWire(wire,dvec)
                             w1 = Part.Wire(Part.__sortEdges__(wire.Edges))
                             sh = DraftGeomUtils.bind(w1,w2)
                         elif obj.Align == "Right":
                             dvec.multiply(width)
                             dvec = dvec.negative()
                             if obj.Offset.Value:
                                 dvec2 = DraftVecUtils.scaleTo(dvec,obj.Offset.Value)
                                 wire = DraftGeomUtils.offsetWire(wire,dvec2)
                             w2 = DraftGeomUtils.offsetWire(wire,dvec)
                             w1 = Part.Wire(Part.__sortEdges__(wire.Edges))
                             sh = DraftGeomUtils.bind(w1,w2)
                         elif obj.Align == "Center":
                             dvec.multiply(width/2)
                             w1 = DraftGeomUtils.offsetWire(wire,dvec)
                             dvec = dvec.negative()
                             w2 = DraftGeomUtils.offsetWire(wire,dvec)
                             sh = DraftGeomUtils.bind(w1,w2)
                         if sh:
                             sh.fix(0.1,0,1) # fixes self-intersecting wires
                             f = Part.Face(sh)
                             if baseface:
                                 baseface = baseface.fuse(f)
                             else:
                                 baseface = f
                     if baseface:
                         base,placement = self.rebase(baseface)
     else:
         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.Face(Part.makePolygon([v1,v2,v3,v4,v1]))
         placement = FreeCAD.Placement()
     if base and placement:
         extrusion = normal.multiply(height)
         return (base,extrusion,placement)
     return None
Beispiel #17
0
    def execute(self,obj):
        "creates the panel shape"
        
        if self.clone(obj):
            return

        import Part, DraftGeomUtils

        # base tests
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.isNull():
                    return
            elif obj.Base.isDerivedFrom("Mesh::Feature"):
                if not obj.Base.Mesh.isSolid():
                    return
        else:
            if obj.Length.Value:
                length = obj.Length.Value
            else:
                return
            if obj.Width.Value:
                width = obj.Width.Value
            else:
                return
        if obj.Thickness.Value:
            thickness = obj.Thickness.Value
        else:
            if not obj.Base:
                return
            elif obj.Base.isDerivedFrom("Part::Feature"):
                if not obj.Base.Shape.Solids:
                    return

        # creating base shape
        pl = obj.Placement
        base = None
        normal = None
        baseprofile = None
        if obj.Base:
            base = obj.Base.Shape.copy()
            if not base.Solids:
                p = FreeCAD.Placement(obj.Base.Placement)
                if base.Faces:
                    baseprofile = base
                    normal = baseprofile.Faces[0].normalAt(0,0).multiply(thickness)
                    base = base.extrude(normal)
                elif base.Wires:
                    closed = True
                    for w in base.Wires:
                        if not w.isClosed():
                            closed = False
                    if closed:
                        baseprofile = ArchCommands.makeFace(base.Wires)
                        normal = baseprofile.normalAt(0,0).multiply(thickness)
                        base = baseprofile.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:
            normal = Vector(0,0,1).multiply(thickness)
            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])
            baseprofile = Part.Face(base)
            base = baseprofile.extrude(normal)
            
        if hasattr(obj,"Area"):
            if baseprofile:
                obj.Area = baseprofile.Area
            
        if hasattr(obj,"WaveLength"):
            if baseprofile and obj.WaveLength.Value and obj.WaveHeight.Value:
                # corrugated element
                bb = baseprofile.BoundBox
                bb.enlarge(bb.DiagonalLength)
                p1 = Vector(bb.getPoint(0).x,bb.getPoint(0).y,bb.Center.z)
                if obj.WaveType == "Curved":
                    p2 = p1.add(Vector(obj.WaveLength.Value/2,0,obj.WaveHeight.Value))
                    p3 = p2.add(Vector(obj.WaveLength.Value/2,0,-obj.WaveHeight.Value))
                    e1 = Part.Arc(p1,p2,p3).toShape()
                    p4 = p3.add(Vector(obj.WaveLength.Value/2,0,-obj.WaveHeight.Value))
                    p5 = p4.add(Vector(obj.WaveLength.Value/2,0,obj.WaveHeight.Value))
                    e2 = Part.Arc(p3,p4,p5).toShape()
                else:
                    if obj.WaveHeight.Value < obj.WaveLength.Value:
                        p2 = p1.add(Vector(obj.WaveHeight.Value,0,obj.WaveHeight.Value))
                        p3 = p2.add(Vector(obj.WaveLength.Value-2*obj.WaveHeight.Value,0,0))
                        p4 = p3.add(Vector(obj.WaveHeight.Value,0,-obj.WaveHeight.Value))
                        e1 = Part.makePolygon([p1,p2,p3,p4])
                        p5 = p4.add(Vector(obj.WaveHeight.Value,0,-obj.WaveHeight.Value))
                        p6 = p5.add(Vector(obj.WaveLength.Value-2*obj.WaveHeight.Value,0,0))
                        p7 = p6.add(Vector(obj.WaveHeight.Value,0,obj.WaveHeight.Value))
                        e2 = Part.makePolygon([p4,p5,p6,p7])
                    else:
                        p2 = p1.add(Vector(obj.WaveLength.Value/2,0,obj.WaveHeight.Value))
                        p3 = p2.add(Vector(obj.WaveLength.Value/2,0,-obj.WaveHeight.Value))
                        e1 = Part.makePolygon([p1,p2,p3])
                        p4 = p3.add(Vector(obj.WaveLength.Value/2,0,-obj.WaveHeight.Value))
                        p5 = p4.add(Vector(obj.WaveLength.Value/2,0,obj.WaveHeight.Value))
                        e2 = Part.makePolygon([p3,p4,p5])
                edges = [e1,e2]
                for i in range(int(bb.XLength/(obj.WaveLength.Value*2))):
                    e1 = e1.copy()
                    e1.translate(Vector(obj.WaveLength.Value*2,0,0))
                    e2 = e2.copy()
                    e2.translate(Vector(obj.WaveLength.Value*2,0,0))
                    edges.extend([e1,e2])
                basewire = Part.Wire(edges)
                baseface = basewire.extrude(Vector(0,bb.YLength,0))
                base = baseface.extrude(Vector(0,0,thickness))
                rot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1),normal)
                base.rotate(bb.Center,rot.Axis,math.degrees(rot.Angle))
                if obj.WaveDirection.Value:
                    base.rotate(bb.Center,normal,obj.WaveDirection.Value)
                n1 = normal.negative().normalize().multiply(obj.WaveHeight.Value*2)
                self.vol = baseprofile.copy()
                self.vol.translate(n1)
                self.vol = self.vol.extrude(n1.negative().multiply(2))
                base = self.vol.common(base)
                base = base.removeSplitter()
                if not base:
                    FreeCAD.Console.PrintError(transpate("Arch","Error computing shape of ")+obj.Label+"\n")
                    return False

        if base and (obj.Sheets > 1) and normal and thickness:
            bases = [base]
            for i in range(1,obj.Sheets):
                n = FreeCAD.Vector(normal).normalize().multiply(i*thickness)
                b = base.copy()
                b.translate(n)
                bases.append(b)
            base = Part.makeCompound(bases)

        if base and normal and hasattr(obj,"Offset"):
            if obj.Offset.Value:
                v = DraftVecUtils.scaleTo(normal,obj.Offset.Value)
                base.translate(v)

        # process subshapes
        base = self.processSubShapes(obj,base,pl)

        # applying
        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(translate("Arch","Couldn't compute a shape"))
                        return
                    base = base.removeSplitter()
                    obj.Shape = base
                    if not pl.isNull():
                        obj.Placement = pl
Beispiel #18
0
 def getDeviation(self):
     "returns a deviation vector that represents the base of the circle"
     import Part
     c = Part.makeCircle(1, Vector(0, 0, 0), self.normal)
     return c.Vertexes[0].Point
Beispiel #19
0
 def test00(self):
     """Check Tag origin."""
     tag = Tag(0, 77, 13, 4, 5, 90, True)
     self.assertCoincide(tag.originAt(3), Vector(77, 13, 3))
 def getLength(self):
     "returns the length of the line"
     p1 = Vector(self.coords.point.getValues()[0].getValue())
     p2 = Vector(self.coords.point.getValues()[-1].getValue())
     return (p2.sub(p1)).Length
Beispiel #21
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)
    def __init__(self,
                 obj,
                 _rootRib,
                 _path,
                 _enveloppe,
                 _leadingedge,
                 _traillingedge,
                 _rootChord=200,
                 _tipChord=100,
                 _panelLength=100,
                 _tipTwist=0,
                 _dihedral=0,
                 axis=Vector(0.0, 0.0, 0.0),
                 items=5,
                 OffsetStart=0,
                 OffsetEnd=0,
                 _distribution='linear',
                 _distributionReverse=False,
                 extract=False,
                 Twist=0,
                 _ribs=[]):

        #_rootRib,_tipRib,
        '''Add some custom properties to our box feature'''
        self.obj = obj

        obj.addProperty(
            "App::PropertyLink", "Base", "WingPanel",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property", "Tip Rib of the panel")).Base = _rootRib  #
        obj.addProperty(
            "App::PropertyLink", "Enveloppe", "WPRibs",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property", "Eveloppe of wing")).Enveloppe = _enveloppe
        obj.addProperty(
            "App::PropertyLink", "Path", "WPRibs",
            QtCore.QT_TRANSLATE_NOOP("App::Property",
                                     "Path of wing")).Path = _path

        # generated Ribs
        obj.addProperty(
            "App::PropertyLinkList", "Ribs", "WPRibs",
            QtCore.QT_TRANSLATE_NOOP("App::Property",
                                     "Ribs of the panel")).Ribs = _ribs

        # need to convert into function not attributes
        obj.addProperty("App::PropertyLength", "TipChord", "WPRibs",
                        QtCore.QT_TRANSLATE_NOOP(
                            "App::Property", "Tip Chord")).TipChord = _tipChord
        obj.addProperty(
            "App::PropertyLength", "RootChord", "WPRibs",
            QtCore.QT_TRANSLATE_NOOP("App::Property",
                                     "Root Chord")).RootChord = _rootChord
        obj.addProperty(
            "App::PropertyLength", "PanelLength", "Design",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property", "Panel Length")).PanelLength = _panelLength

        # need to convert into function not attributes
        obj.addProperty("App::PropertyVector", "Axis", "WingPanel",
                        "Direction axis").Axis = axis
        obj.addProperty(
            "App::PropertyLinkList", "Hullcurves", "WingEdge",
            "Bounding curves").Hullcurves = [_leadingedge, _traillingedge]

        # leadingEdge : bord d'attaque
        obj.addProperty(
            "App::PropertyLinkList", "Edges", "WingEdges",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property",
                "Select the leading edge of the panal, line or Spline")
        ).Edges = []
        obj.addProperty(
            "App::PropertyLink", "LeadingEdge", "WingEdges",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property",
                "Select the leading edge of the panal, line or Spline")
        ).LeadingEdge = _leadingedge
        # trailing edge : bord de fuite
        obj.addProperty(
            "App::PropertyLink", "TrailingEdge", "WingEdges",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property",
                "Select the trailing edge of the panel, line or Spline")
        ).TrailingEdge = _traillingedge

        obj.addProperty("App::PropertyAngle", "TipTwist", "Design",
                        QtCore.QT_TRANSLATE_NOOP(
                            "App::Property", "Tip Twist")).TipTwist = _tipTwist
        obj.addProperty("App::PropertyAngle", "Dihedral", "Design",
                        QtCore.QT_TRANSLATE_NOOP(
                            "App::Property", "Dihedral")).Dihedral = _dihedral
        #obj.addProperty("App::PropertyLinkList","Ribs","WingPanel",QtCore.QT_TRANSLATE_NOOP("App::Property","list of ribs")).Ribs=[]

        obj.addProperty("App::PropertyBool", "Solid", "Design",
                        QtCore.QT_TRANSLATE_NOOP("App::Property",
                                                 "Solid")).Solid = False
        obj.addProperty("App::PropertyBool", "Surface", "Design",
                        QtCore.QT_TRANSLATE_NOOP("App::Property",
                                                 "Surface")).Surface = False
        obj.addProperty("App::PropertyBool", "Structure", "Design",
                        QtCore.QT_TRANSLATE_NOOP("App::Property",
                                                 "Surface")).Structure = False

        obj.addProperty("App::PropertyQuantity", "Items", "Design",
                        "Nr. of array items").Items = items
        obj.addProperty("App::PropertyFloat", "OffsetStart", "Design",
                        "Offset of the first part in Axis direction"
                        ).OffsetStart = OffsetStart
        obj.addProperty(
            "App::PropertyFloat", "OffsetEnd", "Design",
            "Offset of the last part from the end in opposite Axis direction"
        ).OffsetEnd = OffsetEnd

        obj.addProperty("App::PropertyFloat", "Twist", "Design",
                        "Rotate around Axis in degrees").Twist = Twist

        obj.addProperty(
            "App::PropertyEnumeration", "Distribution", "Design",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property", "Algorithm for distance between elements"))
        obj.addProperty(
            "App::PropertyBool", "DistributionReverse", "Design",
            QtCore.QT_TRANSLATE_NOOP(
                "App::Property", "Reverses direction of Distribution algorithm"
            )).DistributionReverse = _distributionReverse
        obj.Distribution = [
            'linear', 'parabolic', 'x³', 'sinusoidal', 'elliptic'
        ]
        obj.Distribution = _distribution
        self.extract = extract
        self.doScaleXYZ = []
        self.doScaleXYZsum = [False, False, False]
        obj.Base.Visibility = False
        obj.Proxy = self
def scaleByBoundbox2(shape, boundbox, doScaleXYZ):
    basebbox = shape.BoundBox
    scalevec = Vector(1, 1, 1)
    x = shape.Placement.Base.x
    y = shape.Placement.Base.y
    z = shape.Placement.Base.z
    if doScaleXYZ[0] and basebbox.XLength > epsilon:
        scalevec.x = boundbox.XLength / basebbox.XLength
    if doScaleXYZ[1] and basebbox.YLength > epsilon:
        scalevec.y = boundbox.YLength / basebbox.YLength
    if doScaleXYZ[2] and basebbox.ZLength > epsilon:
        scalevec.z = boundbox.ZLength / basebbox.ZLength

    scalevec.x = boundbox.XLength
    scalevec.y = boundbox.YLength
    scalevec.z = boundbox.ZLength

    if scalevec.x < epsilon:
        if doScaleXYZ[0]:
            scalevec.x = epsilon
        else:
            scalevec.x = 1
    if scalevec.y < epsilon:
        if doScaleXYZ[1]:
            scalevec.y = epsilon
        else:
            scalevec.y = 1
    if scalevec.z < epsilon:
        if doScaleXYZ[2]:
            scalevec.z = epsilon
        else:
            scalevec.z = 1

    if doScaleXYZ[0]:
        x += boundbox.XMin - basebbox.XMin * scalevec.x
    if doScaleXYZ[1]:
        y += boundbox.YMin - basebbox.YMin * scalevec.y
    if doScaleXYZ[2]:
        z += boundbox.ZMin - basebbox.ZMin * scalevec.z

    return x, y, z, scalevec.x, scalevec.y, scalevec.z
Beispiel #24
0
    def test50(self):
        """Verify proper wire(s) aggregation from a Path."""
        commands = []
        commands.append(Path.Command('G1', {'X': 1}))
        commands.append(Path.Command('G1', {'Y': 1}))
        commands.append(Path.Command('G0', {'X': 0}))
        commands.append(Path.Command('G1', {'Y': 0}))

        wire = PathGeom.wireForPath(Path.Path(commands))
        self.assertEqual(len(wire.Edges), 4)
        self.assertLine(wire.Edges[0], Vector(0, 0, 0), Vector(1, 0, 0))
        self.assertLine(wire.Edges[1], Vector(1, 0, 0), Vector(1, 1, 0))
        self.assertLine(wire.Edges[2], Vector(1, 1, 0), Vector(0, 1, 0))
        self.assertLine(wire.Edges[3], Vector(0, 1, 0), Vector(0, 0, 0))

        wires = PathGeom.wiresForPath(Path.Path(commands))
        self.assertEqual(len(wires), 2)
        self.assertEqual(len(wires[0].Edges), 2)
        self.assertLine(wires[0].Edges[0], Vector(0, 0, 0), Vector(1, 0, 0))
        self.assertLine(wires[0].Edges[1], Vector(1, 0, 0), Vector(1, 1, 0))
        self.assertEqual(len(wires[1].Edges), 1)
        self.assertLine(wires[1].Edges[0], Vector(0, 1, 0), Vector(0, 0, 0))
Beispiel #25
0
    def test30(self):
        """Verify proper geometry for arcs with rising and fall ing Z-axis are created."""
        #print("------ rising helix -------")
        p1 = Vector(0, 1, 0)
        p2 = Vector(1, 0, 2)
        self.assertCurve(
            PathGeom.edgeForCmd(
                Path.Command('G2', {
                    'X': p2.x,
                    'Y': p2.y,
                    'Z': p2.z,
                    'I': 0,
                    'J': -1,
                    'K': 1
                }), p1), p1, Vector(1 / math.sqrt(2), 1 / math.sqrt(2), 1), p2)
        p1 = Vector(-1, 0, 0)
        p2 = Vector(0, -1, 2)
        self.assertCurve(
            PathGeom.edgeForCmd(
                Path.Command('G3', {
                    'X': p2.x,
                    'Y': p2.y,
                    'Z': p2.z,
                    'I': 1,
                    'J': 0,
                    'K': 1
                }), p1), p1, Vector(-1 / math.sqrt(2), -1 / math.sqrt(2), 1),
            p2)

        #print("------ falling helix -------")
        p1 = Vector(0, -1, 2)
        p2 = Vector(-1, 0, 0)
        self.assertCurve(
            PathGeom.edgeForCmd(
                Path.Command('G2', {
                    'X': p2.x,
                    'Y': p2.y,
                    'Z': p2.z,
                    'I': 0,
                    'J': 1,
                    'K': -1
                }), p1), p1, Vector(-1 / math.sqrt(2), -1 / math.sqrt(2), 1),
            p2)
        p1 = Vector(-1, 0, 2)
        p2 = Vector(0, -1, 0)
        self.assertCurve(
            PathGeom.edgeForCmd(
                Path.Command('G3', {
                    'X': p2.x,
                    'Y': p2.y,
                    'Z': p2.z,
                    'I': 1,
                    'J': 0,
                    'K': -1
                }), p1), p1, Vector(-1 / math.sqrt(2), -1 / math.sqrt(2), 1),
            p2)
Beispiel #26
0
 def assertCircle(self, edge, pt, r):
     """Verivy that edge is a circle at given location."""
     curve = edge.Curve
     self.assertIs(type(curve), Part.Circle)
     self.assertCoincide(curve.Center, Vector(pt.x, pt.y, pt.z))
     self.assertRoughly(curve.Radius, r)
Beispiel #27
0
 def get(self):
     p = self.coords.point.getValues()[0]
     return Vector(p[0], p[1], p[2])
    def getExtrusionData(self,obj):

        """returns (shape,extrusion vector,placement) or None"""
        import Part,DraftGeomUtils
        data = ArchComponent.Component.getExtrusionData(self,obj)
        if data:
            if not isinstance(data[0],list):
                # multifuses not considered here
                return data
        length  = obj.Length.Value
        width = obj.Width.Value
        height = obj.Height.Value
        if not height:
            for p in obj.InList:
                if Draft.getType(p) in ["Floor","BuildingPart"]:
                    if p.Height.Value:
                        height = p.Height.Value
        if not height:
            return None
        if obj.Normal == Vector(0,0,0):
            normal = Vector(0,0,1)
        else:
            normal = Vector(obj.Normal)
        base = None
        placement = None
        self.basewires = None
        # build wall layers
        layers = []
        if hasattr(obj,"Material"):
            if obj.Material:
                if hasattr(obj.Material,"Materials"):
                    varwidth = 0
                    restwidth = width - sum(obj.Material.Thicknesses)
                    if restwidth > 0:
                        varwidth = [t for t in obj.Material.Thicknesses if t == 0]
                        if varwidth:
                            varwidth = restwidth/len(varwidth)
                    for t in obj.Material.Thicknesses:
                        if t:
                            layers.append(t)
                        elif varwidth:
                            layers.append(varwidth)
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape:
                    if obj.Base.Shape.Solids:
                        return None
                    elif obj.Face > 0:
                        if len(obj.Base.Shape.Faces) >= obj.Face:
                            face = obj.Base.Shape.Faces[obj.Face-1]
                            # this wall is based on a specific face of its base object
                            if obj.Normal != Vector(0,0,0):
                                normal = face.normalAt(0,0)
                            if normal.getAngle(Vector(0,0,1)) > math.pi/4:
                                normal.multiply(width)
                                base = face.extrude(normal)
                                if obj.Align == "Center":
                                    base.translate(normal.negative().multiply(0.5))
                                elif obj.Align == "Right":
                                    base.translate(normal.negative())
                            else:
                                normal.multiply(height)
                                base = face.extrude(normal)
                            base,placement = self.rebase(base)
                            return (base,normal,placement)
                    elif obj.Base.Shape.Faces:
                        if not DraftGeomUtils.isCoplanar(obj.Base.Shape.Faces):
                            return None
                        else:
                            base,placement = self.rebase(obj.Base.Shape)
                    elif len(obj.Base.Shape.Edges) == 1:
                        self.basewires = [Part.Wire(obj.Base.Shape.Edges)]
                    else:
                        # self.basewires = obj.Base.Shape.Wires
                        self.basewires = []
                        for cluster in Part.getSortedClusters(obj.Base.Shape.Edges):
                            for c in Part.sortEdges(cluster):
                                self.basewires.append(Part.Wire(c))

                    if self.basewires and width:
                        if (len(self.basewires) == 1) and layers:
                            self.basewires = [self.basewires[0] for l in layers]
                        layeroffset = 0
                        baseface = None
                        for i,wire in enumerate(self.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(normal)
                            if not DraftVecUtils.isNull(dvec):
                                dvec.normalize()
                            sh = None
                            if obj.Align == "Left":
                                off = obj.Offset.Value
                                if layers:
                                    off = off+layeroffset
                                    dvec.multiply(layers[i])
                                    layeroffset += layers[i]
                                else:
                                    dvec.multiply(width)
                                if off:
                                    dvec2 = DraftVecUtils.scaleTo(dvec,off)
                                    wire = DraftGeomUtils.offsetWire(wire,dvec2)
                                w2 = DraftGeomUtils.offsetWire(wire,dvec)
                                w1 = Part.Wire(Part.__sortEdges__(wire.Edges))
                                sh = DraftGeomUtils.bind(w1,w2)
                            elif obj.Align == "Right":
                                dvec = dvec.negative()
                                off = obj.Offset.Value
                                if layers:
                                    off = off+layeroffset
                                    dvec.multiply(layers[i])
                                    layeroffset += layers[i]
                                else:
                                    dvec.multiply(width)
                                if off:
                                    dvec2 = DraftVecUtils.scaleTo(dvec,off)
                                    wire = DraftGeomUtils.offsetWire(wire,dvec2)
                                w2 = DraftGeomUtils.offsetWire(wire,dvec)
                                w1 = Part.Wire(Part.__sortEdges__(wire.Edges))
                                sh = DraftGeomUtils.bind(w1,w2)
                            elif obj.Align == "Center":
                                if layers:
                                    off = width/2-layeroffset
                                    d1 = Vector(dvec).multiply(off)
                                    w1 = DraftGeomUtils.offsetWire(wire,d1)
                                    layeroffset += layers[i]
                                    off = width/2-layeroffset
                                    d1 = Vector(dvec).multiply(off)
                                    w2 = DraftGeomUtils.offsetWire(wire,d1)
                                else:
                                    dvec.multiply(width/2)
                                    w1 = DraftGeomUtils.offsetWire(wire,dvec)
                                    dvec = dvec.negative()
                                    w2 = DraftGeomUtils.offsetWire(wire,dvec)
                                sh = DraftGeomUtils.bind(w1,w2)
                            if sh:
                                sh.fix(0.1,0,1) # fixes self-intersecting wires
                                f = Part.Face(sh)
                                if baseface:
                                    if layers:
                                        baseface.append(f)
                                    else:
                                        baseface = baseface.fuse(f)
                                        # baseface = baseface.removeSplitter()
                                        s = DraftGeomUtils.removeSplitter(baseface)
                                        if s:
                                            baseface = s
                                else:
                                    if layers:
                                        baseface = [f]
                                    else:
                                        baseface = f
                        if baseface:
                            base,placement = self.rebase(baseface)
        else:
            if layers:
                totalwidth = sum(layers)
                offset = 0
                base = []
                for l in layers:
                    l2 = length/2 or 0.5
                    w1 = -totalwidth/2 + offset
                    w2 = w1 + l
                    v1 = Vector(-l2,w1,0)
                    v2 = Vector(l2,w1,0)
                    v3 = Vector(l2,w2,0)
                    v4 = Vector(-l2,w2,0)
                    base.append(Part.Face(Part.makePolygon([v1,v2,v3,v4,v1])))
                    offset += l
            else:
                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.Face(Part.makePolygon([v1,v2,v3,v4,v1]))
            placement = FreeCAD.Placement()
        if base and placement:
            extrusion = normal.multiply(height)
            if placement.Rotation.Angle > 0:
                extrusion = placement.inverse().Rotation.multVec(extrusion)
            return (base,extrusion,placement)
        return None
    def execute(self,obj):
        "creates the structure shape"
        
        import Part, DraftGeomUtils
        
        # getting default values
        length = 1
        width = 1
        height = 1
        if hasattr(obj,"Length"):
            if obj.Length.Value:
                length = obj.Length.Value
        if hasattr(obj,"Width"):
            if obj.Width.Value:
                width = obj.Width.Value
        if hasattr(obj,"Height"):
            if obj.Height.Value:
                height = obj.Height.Value
            else:
                for p in obj.InList:
                    if Draft.getType(p) == "Floor":
                        if p.Height.Value:
                            height = p.Height.Value

        # creating base shape
        pl = obj.Placement
        base = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.isNull():
                    return
                if hasattr(obj,"Tool"):
                    if obj.Tool:
                        try:
                            base = obj.Tool.Shape.copy().makePipe(obj.Base.Shape.copy())
                        except:
                            FreeCAD.Console.PrintError(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:
                        self.BaseProfile = base
                        self.ExtrusionVector = normal
                        base = base.extrude(normal)
                    elif (len(base.Wires) == 1):
                        if base.Wires[0].isClosed():
                            base = Part.Face(base.Wires[0])
                            self.BaseProfile = base
                            self.ExtrusionVector = normal
                            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):
                if length > height:
                    normal = Vector(1,0,0).multiply(length)
                else:
                    normal = Vector(0,0,1).multiply(height)
            else:
                normal = Vector(obj.Normal).multiply(height)
            self.ExtrusionVector = normal
            if length > height:
                h2 = height/2 or 0.5
                w2 = width/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 = 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)
            self.BaseProfile = base
            base = base.extrude(self.ExtrusionVector)
            
        base = self.processSubShapes(obj,base,pl)
            
        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(translate("Arch","Couldn't compute a shape"))
                                return
                            base = base.removeSplitter()
                            obj.Shape = base
                if not pl.isNull():
                    obj.Placement = pl
def scaleByBoundbox(shape, boundbox, doScaleXYZ, copy=True):
    basebbox = shape.BoundBox
    #basebbox=[1.0,1.0,1.0]
    scalevec = Vector(1, 1, 1)
    if doScaleXYZ[0] and basebbox.XLength > epsilon:
        scalevec.x = boundbox.XLength / basebbox.XLength
    if doScaleXYZ[1] and basebbox.YLength > epsilon:
        scalevec.y = boundbox.YLength / basebbox.YLength
    if doScaleXYZ[2] and basebbox.ZLength > epsilon:
        scalevec.z = boundbox.ZLength / basebbox.ZLength

    scalevec.x = boundbox.XLength
    scalevec.y = boundbox.YLength
    scalevec.z = boundbox.ZLength

    if scalevec.x < epsilon:
        if doScaleXYZ[0]:
            scalevec.x = epsilon
        else:
            scalevec.x = 1
    if scalevec.y < epsilon:
        if doScaleXYZ[1]:
            scalevec.y = epsilon
        else:
            scalevec.y = 1
    if scalevec.z < epsilon:
        if doScaleXYZ[2]:
            scalevec.z = epsilon
        else:
            scalevec.z = 1

    _rib = FreeCAD.ActiveDocument.addObject("Part::FeaturePython", "Rib00")
    print("Scale in scaleByBoundbox")
    print(scalevec)
    WingRib(
        _rib,
        "/Users/fredericnivoix/Library/Preferences/FreeCAD/Mod/AirPlaneDesign/wingribprofil/naca/naca2412.dat",
        False, 0, scalevec.x, 0, 0, 0, 0, 0, 0)
    ViewProviderWingRib(_rib.ViewObject)
    _rib.Placement = shape.Placement
    #dolly = scale(shape, scalevec, basebbox.Center, copy)
    #dolly.Placement = shape.Placement

    if doScaleXYZ[0]:
        _rib.Placement.Base.x += boundbox.XMin - basebbox.XMin * scalevec.x
    if doScaleXYZ[1]:
        _rib.Placement.Base.y += boundbox.YMin - basebbox.YMin * scalevec.y
    if doScaleXYZ[2]:
        _rib.Placement.Base.z += boundbox.ZMin - basebbox.ZMin * scalevec.z

    return _rib  #dolly
def displacement(ship, draft, roll=0.0, trim=0.0, yaw=0.0):
    """ Compute the ship displacement.
    @param ship Ship instance.
    @param draft Ship draft.
    @param roll Ship roll angle.
    @param trim Ship trim angle.
    @param yaw Ship yaw angle. Ussually you don't want to use this
     value.
    @return [disp, B, Cb], \n
      - disp = Ship displacement [ton].
      - B = Bouyance center [m].
      - Cb = Block coefficient.
    @note Bouyance center will returned as a FreeCAD.Vector instance.
    @note Returned Bouyance center is in the non modified ship coordinates
    """
    # We will take a duplicate of ship shape in order to conviniently
    # manipulate it
    shape = ship.Shape.copy()

    shape.translate(Vector(0.0, 0.0, -draft * Units.Metre.Value))
    shape.rotate(Vector(0.0, 0.0, 0.0), Vector(1.0, 0.0, 0.0), roll)
    shape.rotate(Vector(0.0, 0.0, 0.0), Vector(0.0, -1.0, 0.0), trim)
    shape.rotate(Vector(0.0, 0.0, 0.0), Vector(0.0, 0.0, 1.0), yaw)

    bbox = shape.BoundBox
    xmin = bbox.XMin
    xmax = bbox.XMax
    # Create the "sea" box to intersect the ship
    L = xmax - xmin
    B = bbox.YMax - bbox.YMin
    p = Vector(-1.5*L, -1.5*B, bbox.ZMin - 1.0)
    try:
        box = Part.makeBox(3.0*L, 3.0*B, - bbox.ZMin + 1.0, p)
    except:
        return [0.0, Vector(), 0.0]

    vol = 0.0
    cog = Vector()
    for solid in shape.Solids:
        # Compute the common part of the "sea" with the ship
        try:
            common = box.common(solid)
        except:
            continue
        # Get the data
        vol = vol + common.Volume / Units.Metre.Value**3
        for s in common.Solids:
            sCoG = s.CenterOfMass
            cog.x = cog.x + sCoG.x * s.Volume / Units.Metre.Value**4
            cog.y = cog.y + sCoG.y * s.Volume / Units.Metre.Value**4
            cog.z = cog.z + sCoG.z * s.Volume / Units.Metre.Value**4
    cog.x = cog.x / vol
    cog.y = cog.y / vol
    cog.z = cog.z / vol
    Vol = L * B * abs(bbox.ZMin) / Units.Metre.Value**3
    # Undo the transformations
    B = Vector()
    B.x = cog.x * math.cos(math.radians(-yaw)) - \
        cog.y * math.sin(math.radians(-yaw))
    B.y = cog.x * math.sin(math.radians(-yaw)) + \
        cog.y * math.cos(math.radians(-yaw))
    B.z = cog.z
    cog.x = B.x * math.cos(math.radians(-trim)) - \
        B.z * math.sin(math.radians(-trim))
    cog.y = B.y
    cog.z = B.x * math.sin(math.radians(-trim)) + \
        B.z * math.cos(math.radians(-trim))
    B.x = cog.x
    B.y = cog.y * math.cos(math.radians(-roll)) - \
        cog.z * math.sin(math.radians(-roll))
    B.z = cog.y * math.sin(math.radians(-roll)) + \
        cog.z * math.cos(math.radians(-roll))
    B.z = B.z + draft
    # Return the computed data
    dens = 1.025  # [tons/m3], salt water
    return [dens*vol, B, vol/Vol]
Beispiel #32
0
    def make(initial_placement: Placement = Placement(),
             origin_translation_offset: Vector = Vector()):
        """Make an extruder.

        :param initial_placement: Initial placement for part.
        :param origin_translation_offset: Offset part from origin.
        :return: Extruder object.
        """
        main_part_width = 50
        main_part_length = 87
        main_part_bottom_base_overhang_width = 5

        main_part = MainExtruderPart.make(
            main_part_width, main_part_length,
            main_part_bottom_base_overhang_width)

        cooling_and_sensor_slanted_side_width = 4
        cooling_and_sensor_mount = CoolingAndSensorMount.make(
            cooling_and_sensor_slanted_side_width, main_part_length,
            main_part_bottom_base_overhang_width)
        cooling_and_sensor_mount.translate(
            Vector(0, main_part_bottom_base_overhang_width, 0))

        blower_radius = 45 / 2
        blower_width = 15.4
        blower = Part.makeCylinder(blower_radius, blower_width)
        blower.rotate(Vector(0, 0, 0), Vector(0, -1, 0), 90)
        blower_y = 15.25 + blower_radius
        blower.translate(
            Vector(-cooling_and_sensor_slanted_side_width, blower_y,
                   blower_radius))

        # TODO: Remove duplication of sensor_holder_width
        #       from extruder_model.py and cooling_and_sensor_mount.py
        #       Should blower box even use sensor_holder_width,
        #       or should the blower be independent from knowledge of
        #       cooling and sensor mount?
        sensor_holder_width = 25
        blower_box_y_offset = main_part_bottom_base_overhang_width + \
            CoolingAndSensorMount.vent_box_width
        blower_box = Part.makeBox(blower_width, blower_y - blower_box_y_offset,
                                  sensor_holder_width)
        blower_box.translate(
            Vector(-cooling_and_sensor_slanted_side_width - blower_width,
                   blower_box_y_offset, 0))

        motor = make_motor()
        motor.translate(Vector(0, 0, MainExtruderPart.base_height))

        parts = [
            main_part, cooling_and_sensor_mount, blower, blower_box, motor
        ]
        dimensions = (main_part_width, main_part_length,
                      MainExtruderPart.base_height)
        move_parts(parts, initial_placement, origin_translation_offset,
                   dimensions)

        extruder = reduce(lambda union, part: union.fuse(part), parts)

        # removeSplitter() refines shape
        return extruder.removeSplitter()
Beispiel #33
0
 def execute(self, obj):
     import Part
     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
Beispiel #34
0
def isDrillable(obj, candidate, tooldiameter=None, includePartials=False):
    """
    Checks candidates to see if they can be drilled.
    Candidates can be either faces - circular or cylindrical or circular edges.
    The tooldiameter can be optionally passed.  if passed, the check will return
    False for any holes smaller than the tooldiameter.
    obj=Shape
    candidate = Face or Edge
    tooldiameter=float
    """
    PathLog.track('obj: {} candidate: {} tooldiameter {}'.format(obj, candidate, tooldiameter))
    drillable = False
    if candidate.ShapeType == 'Face':
        face = candidate
        # eliminate flat faces
        if (round(face.ParameterRange[0], 8) == 0.0) and (round(face.ParameterRange[1], 8) == round(math.pi * 2, 8)):
            for edge in face.Edges:  # Find seam edge and check if aligned to Z axis.
                if (isinstance(edge.Curve, Part.Line)):
                    PathLog.debug("candidate is a circle")
                    v0 = edge.Vertexes[0].Point
                    v1 = edge.Vertexes[1].Point
                    #check if the cylinder seam is vertically aligned.  Eliminate tilted holes
                    if (numpy.isclose(v1.sub(v0).x, 0, rtol=1e-05, atol=1e-06)) and \
                            (numpy.isclose(v1.sub(v0).y, 0, rtol=1e-05, atol=1e-06)):
                        drillable = True
                        # vector of top center
                        lsp = Vector(face.BoundBox.Center.x, face.BoundBox.Center.y, face.BoundBox.ZMax)
                        # vector of bottom center
                        lep = Vector(face.BoundBox.Center.x, face.BoundBox.Center.y, face.BoundBox.ZMin)
                        # check if the cylindrical 'lids' are inside the base
                        # object.  This eliminates extruded circles but allows
                        # actual holes.
                        if obj.isInside(lsp, 1e-6, False) or obj.isInside(lep, 1e-6, False):
                            PathLog.track("inside check failed. lsp: {}  lep: {}".format(lsp,lep))
                            drillable = False
                        # eliminate elliptical holes
                        elif not hasattr(face.Surface, "Radius"):
                            PathLog.debug("candidate face has no radius attribute")
                            drillable = False
                        else:
                            if tooldiameter is not None:
                                drillable = face.Surface.Radius >= tooldiameter/2
                            else:
                                drillable = True
    else:
        for edge in candidate.Edges:
            if isinstance(edge.Curve, Part.Circle) and (includePartials or edge.isClosed()):
                PathLog.debug("candidate is a circle or ellipse")
                if not hasattr(edge.Curve, "Radius"):
                    PathLog.debug("No radius.  Ellipse.")
                    drillable = False
                else:
                    PathLog.debug("Has Radius, Circle")
                    if tooldiameter is not None:
                        drillable = edge.Curve.Radius >= tooldiameter/2
                        if not drillable:
                            FreeCAD.Console.PrintMessage(
                                    "Found a drillable hole with diameter: {}: "
                                    "too small for the current tool with "
                                    "diameter: {}".format(edge.Curve.Radius*2, tooldiameter))
                    else:
                        drillable = True
    PathLog.debug("candidate is drillable: {}".format(drillable))
    return drillable
    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)
            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 the wall shape")))
                                return
                            base = base.removeSplitter()
                            obj.Shape = base
                if not DraftGeomUtils.isNull(pl):
                    obj.Placement = pl
Beispiel #36
0
 def update(self, L, B, T, sectionsL, sectionsB, sectionsT, shape):
     """ Update the 3D view annotations.
     @param L Ship Lpp.
     @param B Ship beam.
     @param T Ship draft.
     @param sectionsL Transversal sections.
     @param sectionsB Longitudinal sections.
     @param sectionsT Water lines.
     @param shape Ship surfaces shell
     @return Sections object. None if errors happens.
     """
     msg = QtGui.QApplication.translate(
         "ship_console",
         "Computing sections",
         None)
     FreeCAD.Console.PrintMessage(msg + '...\n')
     # Destroy all previous entities
     self.clean()
     # Receive data
     nL = len(sectionsL)
     nB = len(sectionsB)
     nT = len(sectionsT)
     if not (nL or nB or nT):
         return None
     # Found sections
     sections = []
     for i in range(0, nL):
         pos = sectionsL[i] * Units.Metre.Value
         # Cut ship
         section = shape.slice(Vector(1.0, 0.0, 0.0), pos)
         for j in range(0, len(section)):
             edges = section[j].Edges
             # We have 3 cases,
             # * when the section is before midship (starboard side drawn)
             # * When the section is midship (both sides drawn)
             # * When the section is after midship (board side drawn)
             if pos > 0.01 * L * Units.Metre.Value:
                 for k in range(len(edges) - 1, -1, -1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMin < -0.01 * B * Units.Metre.Value:
                         del edges[k]
             elif pos < -0.01 * L * Units.Metre.Value:
                 for k in range(len(edges) - 1, -1, -1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMax > 0.01 * B * Units.Metre.Value:
                         del edges[k]
             sections.extend(edges)
     for i in range(0, nB):
         pos = sectionsB[i] * Units.Metre.Value
         section = shape.slice(Vector(0.0, 1.0, 0.0), pos)
         for j in range(0, len(section)):
             edges = section[j].Edges
             # The longitudinal sections are printed in both sides.
             section[j] = section[j].mirror(Vector(0.0, 0.0, 0.0),
                                            Vector(0.0, 1.0, 0.0))
             edges2 = section[j].Edges
             sections.extend(edges)
             sections.extend(edges2)
     for i in range(0, nT):
         pos = sectionsT[i] * Units.Metre.Value
         section = shape.slice(Vector(0.0, 0.0, 1.0), pos)
         for j in range(0, len(section)):
             edges = section[j].Edges
             # We have 3 cases,
             # * when the section is below draft (starboard side drawn)
             # * When the section is draft (both sides drawn)
             # * When the section is above draft (starboard side drawn)
             if pos > T * 1.01 * Units.Metre.Value:
                 for k in range(len(edges) - 1, -1, -1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMax > 0.01 * B * Units.Metre.Value:
                         del edges[k]
             elif pos < T * 0.99 * Units.Metre.Value:
                 for k in range(len(edges) - 1, -1, -1):
                     edge = edges[k]
                     bbox = edge.BoundBox
                     if bbox.YMin < -0.01 * B * Units.Metre.Value:
                         del edges[k]
             sections.extend(edges)
     # Transform and join all the B-splines into a shape
     if not sections:
         msg = QtGui.QApplication.translate(
             "ship_console",
             "Any valid ship section found",
             None)
         FreeCAD.Console.PrintWarning(msg + '\n')
         return
     obj = sections[0]
     for i in range(1, len(sections)):
         # Just create a group of edges
         obj = obj.oldFuse(sections[i])
     Part.show(obj)
     objs = FreeCAD.ActiveDocument.Objects
     self.obj = objs[len(objs) - 1]
     self.obj.Label = 'OutlineDraw'
     return self.obj
    def _zoom_camera(self, use_bound_box=True):
        """
        Fancy routine to smooth zoom the camera
        """
        print('zoom')
        _camera = ViewState().view.getCameraNode()

        _start_pos = Vector(_camera.position.getValue().getValue())
        _start_ht = _camera.height.getValue()

        _center = Vector(self.camera_state['position'])
        _height = self.camera_state['height']

        if use_bound_box:

            _bound_box = self.camera_state['bound box']

            #get the center of the camera, setting the z coordinate positive
            _center = Vector(_bound_box.Center)
            _center.z = 1.0

            #calculate the camera height = bounding box larger dim + 15%
            _height = _bound_box.XMax - _bound_box.XMin
            _dy = _bound_box.YMax - _bound_box.YMin

            if _dy > _height:
                _height = _dy

            _height += 0.15 * _height

        _frames = 60.0

        #calculate a total change value
        _pct_chg = abs(_height - _start_ht) / (_height + _start_ht)

        #at 50% change or more, use 60 frames,
        #otherwise scale frames to a minimum of 10 frames
        if _pct_chg < 0.5:
            _frames *= _pct_chg * 2.0

            if _frames < 10.0:
                _frames = 10.0

        #build cosine-based animation curve and reverse
        _steps = [
            math.cos((_i/_frames) * (math.pi/2.0)) * _frames\
                for _i in range(0, int(_frames))
        ]

        _steps = _steps[::-1]

        #calculate position and height deltas for transition loop
        _d_pos = _center - _start_pos
        _d_pos.multiply(1.0 / _frames)

        _d_ht = (_height - _start_ht) / _frames

        for _v in _steps:

            #set the camera
            ViewState().view.getCameraNode().position.setValue(
                tuple(_start_pos + (_d_pos * _v)))

            ViewState().view.getCameraNode().height.setValue(_start_ht +
                                                             (_d_ht * _v))

            Gui.updateGui()
            ViewState().view.redraw()
Beispiel #38
0
#*                                                                         *
#***************************************************************************

import FreeCADGui , WorkingPlane1, math, re
from pivy import coin
from FreeCAD import Vector
from drawGui import *
#from draftlibs import fcvec, fcgeo
import fcvec, fcgeo
from functools import partial
import Part
            
# sets the default working plane
plane = WorkingPlane1.plane()
FreeCAD.DDADockWidget = plane
plane.alignToPointAndAxis(Vector(0, 0, 0), Vector(0, 0, 1), 0)


#---------------------------------------------------------------------------
# Trackers
#---------------------------------------------------------------------------

class Tracker:
    "A generic Draft Tracker, to be used by other specific trackers"
    # 辅助绘图工具
    def __init__(self, dotted=False, scolor=None, swidth=None, children=[], ontop=False):
        self.ontop = ontop
        color = coin.SoBaseColor()
        color.rgb = scolor or FreeCADGui.DDADockWidget.getDefaultColor("ui")
        drawstyle = coin.SoDrawStyle()
        if swidth:
Beispiel #39
0
def displacement(ship, draft=None,
                       roll=Units.parseQuantity("0 deg"), 
                       trim=Units.parseQuantity("0 deg")):
    """Compute the ship displacement

    Position arguments:
    ship -- Ship object (see createShip)

    Keyword arguments:
    draft -- Ship draft (Design ship draft by default)
    roll -- Roll angle (0 degrees by default)
    trim -- Trim angle (0 degrees by default)

    Returned values:
    disp -- The ship displacement (a density of the water of 1025 kg/m^3 is
    assumed)
    B -- Bouyance application point, i.e. Center of mass of the underwater side
    Cb -- Block coefficient

    The Bouyance center is refered to the original ship position.
    """
    if draft is None:
        draft = ship.Draft

    shape, base_z = placeShipShape(ship.Shape.copy(), draft, roll, trim)
    shape = getUnderwaterSide(shape)

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

    bbox = shape.BoundBox
    Vol = (bbox.XMax - bbox.XMin) * (bbox.YMax - bbox.YMin) * abs(bbox.ZMin)

    # Undo the transformations on the bouyance point
    B = Part.Point(Vector(cog.x, cog.y, cog.z))
    m = Matrix()
    m.move(Vector(0.0, 0.0, draft))
    m.move(Vector(-draft * math.sin(trim.getValueAs("rad")), 0.0, 0.0))
    m.rotateY(trim.getValueAs("rad"))
    m.move(Vector(0.0,
                  -draft * math.sin(roll.getValueAs("rad")),
                  base_z))
    m.rotateX(-roll.getValueAs("rad"))
    B.transform(m)

    try:
        cb = vol / Vol
    except ZeroDivisionError:
        msg = QtGui.QApplication.translate(
            "ship_console",
            "ZeroDivisionError: Null volume found during the displacement"
            " computation!",
            None,
            QtGui.QApplication.UnicodeUTF8)
        App.Console.PrintError(msg + '\n')
        cb = 0.0


    # Return the computed data
    return (DENS * Units.Quantity(vol, Units.Volume),
            Vector(B.X, B.Y, B.Z),
            cb)
Beispiel #40
0
 def p1(self, point=None):
     "sets or gets the first point of the line"
     if point:
         self.coords.point.set1Value(0, point.x, point.y, point.z)
     else:
         return Vector(self.coords.point.getValues()[0].getValue())
Beispiel #41
0
 def getExtrusionData(self,obj):
     """returns (shape,extrusion vector,placement) or None"""
     import Part,DraftGeomUtils
     data = ArchComponent.Component.getExtrusionData(self,obj)
     if data:
         return data
     length  = obj.Length.Value
     width = obj.Width.Value
     height = obj.Height.Value
     normal = None
     if not height:
         for p in obj.InList:
             if Draft.getType(p) == "Floor":
                 if p.Height.Value:
                     height = p.Height.Value
     base = None
     placement = None
     if obj.Base:
         if obj.Base.isDerivedFrom("Part::Feature"):
             if obj.Base.Shape:
                 if obj.Base.Shape.Solids:
                     return None
                 elif obj.Base.Shape.Faces:
                     if not DraftGeomUtils.isCoplanar(obj.Base.Shape.Faces):
                         return None
                     else:
                         base,placement = self.rebase(obj.Base.Shape)
                         normal = obj.Base.Shape.Faces[0].normalAt(0,0)
                 elif obj.Base.Shape.Wires:
                     baseface = None
                     if hasattr(obj,"FaceMaker"):
                         if obj.FaceMaker != "None":
                             try:
                                 baseface = Part.makeFace(obj.Base.Shape.Wires,"Part::FaceMaker"+str(obj.FaceMaker))
                             except:
                                 FreeCAD.Console.PrintError(translate("Arch","Facemaker returned an error")+"\n")
                                 return None
                             if len(baseface.Faces) > 1:
                                 baseface = baseface.Faces[0]
                             normal = baseface.normalAt(0,0)
                     if not baseface:
                         for w in obj.Base.Shape.Wires:
                             w.fix(0.1,0,1) # fixes self-intersecting wires
                             f = Part.Face(w)
                             if baseface:
                                 baseface = baseface.fuse(f)
                             else:
                                 baseface = f
                                 normal = f.normalAt(0,0)
                     base,placement = self.rebase(baseface)
                 elif (len(obj.Base.Shape.Edges) == 1) and (len(obj.Base.Shape.Vertexes) == 1):
                     # closed edge
                     w = Part.Wire(obj.Base.Shape.Edges[0])
                     baseface = Part.Face(w)
                     base,placement = self.rebase(baseface)
     elif length and width and height:
         if (length > height) and (obj.Role != "Slab"):
             h2 = height/2 or 0.5
             w2 = width/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 = 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)
         import Part
         baseface = Part.Face(Part.makePolygon([v1,v2,v3,v4,v1]))
         base,placement = self.rebase(baseface)
     if base and placement:
         if obj.Normal == Vector(0,0,0):
             if not normal:
                 normal = Vector(0,0,1)
         else:
             normal = Vector(obj.Normal)
         if (length > height) and (obj.Role != "Slab"):
             extrusion = normal.multiply(length)
         else:
             extrusion = normal.multiply(height)
         return (base,extrusion,placement)
     return None
Beispiel #42
0
 def p2(self, point=None):
     "sets or gets the second point of the line"
     if point:
         self.coords.point.set1Value(1, point.x, point.y, point.z)
     else:
         return Vector(self.coords.point.getValues()[-1].getValue())
def setup(doc=None, solvertype="elmer"):

    # init FreeCAD document
    if doc is None:
        doc = init_doc()

    # explanation object
    # just keep the following line and change text string in get_explanation method
    manager.add_explanation_obj(
        doc, get_explanation(manager.get_header(get_information())))

    # geometric objects
    # name is important because the other method in this module use obj name
    geom_obj = doc.addObject("PartDesign::Body", "Body")
    base_sketch = geom_obj.newObject("Sketcher::SketchObject", "Base_Sketch")
    base_sketch.Support = (doc.getObject("XY_Plane"), [""])
    base_sketch.MapMode = "FlatFace"
    base_geoList = [
        Part.LineSegment(Vector(0.000000, 0.000000, 0),
                         Vector(57.407921, 0.000000, 0)),
        Part.LineSegment(Vector(57.407921, 0.000000, 0),
                         Vector(57.407921, 35.205284, 0)),
        Part.LineSegment(Vector(57.407921, 35.205284, 0),
                         Vector(0.000000, 35.205284, 0)),
        Part.LineSegment(Vector(0.000000, 35.205284, 0),
                         Vector(0.000000, 0.000000, 0))
    ]
    base_sketch.addGeometry(base_geoList, False)
    base_conList = [
        Sketcher.Constraint("Coincident", 0, 2, 1, 1),
        Sketcher.Constraint("Coincident", 1, 2, 2, 1),
        Sketcher.Constraint("Coincident", 2, 2, 3, 1),
        Sketcher.Constraint("Coincident", 3, 2, 0, 1),
        Sketcher.Constraint("Horizontal", 0),
        Sketcher.Constraint("Horizontal", 2),
        Sketcher.Constraint("Vertical", 1),
        Sketcher.Constraint("Vertical", 3),
        Sketcher.Constraint("Coincident", 0, 1, -1, 1),
        Sketcher.Constraint("DistanceY", 1, 1, 1, 2, 35.205284),
        Sketcher.Constraint("DistanceX", 0, 1, 0, 2, 57.407921)
    ]
    base_sketch.addConstraint(base_conList)
    base_sketch.setDatum(9, Units.Quantity("5000.000000 mm"))
    base_sketch.setDatum(10, Units.Quantity("5000.000000 mm"))

    pad = geom_obj.newObject("PartDesign::Pad", "Pad")
    pad.Profile = base_sketch
    pad.Length = 7500.0
    pad.Length2 = 1000.0

    upper_sketch = geom_obj.newObject("Sketcher::SketchObject", "Upper_Sketch")
    upper_sketch.Support = None
    upper_sketch.MapMode = "Deactivated"
    upper_sketch.Placement = FreeCAD.Placement(Vector(0, 0, 1000),
                                               Rotation(Vector(0, 0, 1), 0))
    upper_geoList = [
        Part.LineSegment(Vector(25.560951, 4958.778320, 0),
                         Vector(5068.406250, 4958.778320, 0)),
        Part.LineSegment(Vector(5068.406250, 4958.778320, 0),
                         Vector(5037.082520, -21.422216, 0)),
        Part.LineSegment(Vector(5037.082520, 0.000000, 0),
                         Vector(1309.763672, -21.422216, 0)),
        Part.LineSegment(Vector(1309.763672, 0.000000, 0),
                         Vector(1372.406982, 1544.678467, 0)),
        Part.LineSegment(Vector(1372.406982, 1544.678467, 0),
                         Vector(-37.083382, 1544.678467, 0)),
        Part.LineSegment(Vector(0.000000, 1544.678467, 0),
                         Vector(25.560951, 4958.778320, 0))
    ]
    upper_sketch.addGeometry(upper_geoList, False)
    upper_conList = [
        Sketcher.Constraint("Horizontal", 0),
        Sketcher.Constraint("Coincident", 1, 1, 0, 2),
        Sketcher.Constraint("PointOnObject", 1, 2, -1),
        Sketcher.Constraint("Vertical", 1),
        Sketcher.Constraint("Coincident", 2, 1, 1, 2),
        Sketcher.Constraint("PointOnObject", 2, 2, -1),
        Sketcher.Constraint("Coincident", 3, 1, 2, 2),
        Sketcher.Constraint("Coincident", 4, 1, 3, 2),
        Sketcher.Constraint("PointOnObject", 4, 2, -2),
        Sketcher.Constraint("Horizontal", 4),
        Sketcher.Constraint("Coincident", 5, 1, 4, 2),
        Sketcher.Constraint("Coincident", 5, 2, 0, 1),
        Sketcher.Constraint("Vertical", 5),
        Sketcher.Constraint("Vertical", 3),
        Sketcher.Constraint("DistanceX", 0, 1, 0, 2, 5037.082520),
        Sketcher.Constraint("DistanceY", 1, 2, 1, 1, 4958.778320),
        Sketcher.Constraint("DistanceY", 3, 1, 3, 2, 1544.678467),
        Sketcher.Constraint("DistanceX", 4, 2, 4, 1, 1309.763672)
    ]
    upper_sketch.addConstraint(upper_conList)
    upper_sketch.setDatum(14, Units.Quantity("5000.000000 mm"))
    upper_sketch.setDatum(15, Units.Quantity("5000.000000 mm"))
    upper_sketch.setDatum(16, Units.Quantity("1500.000000 mm"))
    upper_sketch.setDatum(17, Units.Quantity("1500.000000 mm"))

    pocket = geom_obj.newObject("PartDesign::Pocket", "Pocket")
    pocket.Profile = upper_sketch
    pocket.Length = 1500.0
    pocket.Length2 = 100.0
    pocket.Reversed = 1
    doc.recompute()

    if FreeCAD.GuiUp:
        geom_obj.ViewObject.Document.activeView().viewAxonometric()
        geom_obj.ViewObject.Document.activeView().fitAll()

    # analysis
    analysis = ObjectsFem.makeAnalysis(doc, "Analysis")

    # solver
    if solvertype == "elmer":
        solver_obj = ObjectsFem.makeSolverElmer(doc, "SolverElmer")
        ObjectsFem.makeEquationElectrostatic(doc, solver_obj)
        ObjectsFem.makeEquationElectricforce(doc, solver_obj)
    else:
        FreeCAD.Console.PrintWarning(
            "Not known or not supported solver type: {}. "
            "No solver object was created.\n".format(solvertype))
    analysis.addObject(solver_obj)

    # material
    material_obj = ObjectsFem.makeMaterialFluid(doc, "FemMaterial")
    mat = material_obj.Material
    mat["Name"] = "Air-Generic"
    mat["Density"] = "1.20 kg/m^3"
    mat["KinematicViscosity"] = "15.11 mm^2/s"
    mat["VolumetricThermalExpansionCoefficient"] = "0.00 mm/m/K"
    mat["ThermalConductivity"] = "0.03 W/m/K"
    mat["ThermalExpansionCoefficient"] = "0.0034/K"
    mat["SpecificHeat"] = "1.00 J/kg/K"
    mat["RelativePermittivity"] = "1.00"
    material_obj.Material = mat
    analysis.addObject(material_obj)

    # constraint potential 0V
    name_pot1 = "ElectrostaticPotential1"
    con_elect_pot1 = ObjectsFem.makeConstraintElectrostaticPotential(
        doc, name_pot1)
    con_elect_pot1.References = [(geom_obj, "Face2")]
    con_elect_pot1.Potential = "0 V"
    con_elect_pot1.CapacitanceBody = 1
    con_elect_pot1.CapacitanceBodyEnabled = True
    con_elect_pot1.PotentialEnabled = True
    analysis.addObject(con_elect_pot1)

    # constraint potential 1V
    name_pot2 = "ElectrostaticPotential2"
    con_elect_pot2 = ObjectsFem.makeConstraintElectrostaticPotential(
        doc, name_pot2)
    con_elect_pot2.References = [(geom_obj, "Face4"), (geom_obj, "Face5"),
                                 (geom_obj, "Face6"), (geom_obj, "Face11")]
    con_elect_pot2.Potential = "1 V"
    con_elect_pot2.CapacitanceBody = 2
    con_elect_pot2.CapacitanceBodyEnabled = True
    con_elect_pot2.PotentialEnabled = True
    con_elect_pot2.ElectricForcecalculation = True
    analysis.addObject(con_elect_pot2)

    # mesh
    from .meshes.mesh_electricforce_elmer_nongui6_tetra10 import create_nodes, create_elements
    fem_mesh = Fem.FemMesh()
    control = create_nodes(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating nodes.\n")
    control = create_elements(fem_mesh)
    if not control:
        FreeCAD.Console.PrintError("Error on creating elements.\n")
    femmesh_obj = analysis.addObject(
        ObjectsFem.makeMeshGmsh(doc, get_meshname()))[0]
    femmesh_obj.FemMesh = fem_mesh
    femmesh_obj.Part = geom_obj
    femmesh_obj.SecondOrderLinear = False

    # mesh_region
    mesh_region = ObjectsFem.makeMeshRegion(doc,
                                            femmesh_obj,
                                            name="MeshRegion")
    mesh_region.CharacteristicLength = "300 mm"
    mesh_region.References = [(geom_obj, "Face4"), (geom_obj, "Face5"),
                              (geom_obj, "Face6"), (geom_obj, "Face11")]

    doc.recompute()
    return doc
Beispiel #44
0
 def getLength(self):
     "returns the length of the line"
     p1 = Vector(self.coords.point.getValues()[0].getValue())
     p2 = Vector(self.coords.point.getValues()[-1].getValue())
     return (p2.sub(p1)).Length
Beispiel #45
0
 def externalFaces(self, shape):
     """ Returns detected external faces.
     @param shape Shape where external faces wanted.
     @return List of external faces detected.
     """
     result = []
     faces = shape.Faces
     bbox = shape.BoundBox
     L = bbox.XMax - bbox.XMin
     B = bbox.YMax - bbox.YMin
     T = bbox.ZMax - bbox.ZMin
     dist = math.sqrt(L*L + B*B + T*T)
     msg = QtGui.QApplication.translate(
         "ship_console",
         "Computing external faces",
         None)
     App.Console.PrintMessage(msg + '...\n')
     # Valid/unvalid faces detection loop
     for i in range(len(faces)):
         App.Console.PrintMessage("\t{} / {}\n".format(i + 1, len(faces)))
         f = faces[i]
         # Create a line normal to surface at middle point
         u = 0.0
         v = 0.0
         try:
             surf = f.Surface
             u = 0.5*(surf.getUKnots()[0]+surf.getUKnots()[-1])
             v = 0.5*(surf.getVKnots()[0]+surf.getVKnots()[-1])
         except:
             cog = f.CenterOfMass
             [u, v] = f.Surface.parameter(cog)
         p0 = f.valueAt(u, v)
         try:
             n = f.normalAt(u, v).normalize()
         except:
             continue
         p1 = p0 + n.multiply(1.5 * dist)
         line = Part.makeLine(p0, p1)
         # Look for faces in front of this
         nPoints = 0
         for j in range(len(faces)):
             f2 = faces[j]
             section = self.lineFaceSection(line, f2)
             if len(section) <= 2:
                 continue
             # Add points discarding start and end
             nPoints = nPoints + len(section) - 2
         # In order to avoid special directions we can modify line
         # normal a little bit.
         angle = 5
         line.rotate(p0, Vector(1, 0, 0), angle)
         line.rotate(p0, Vector(0, 1, 0), angle)
         line.rotate(p0, Vector(0, 0, 1), angle)
         nPoints2 = 0
         for j in range(len(faces)):
             if i == j:
                 continue
             f2 = faces[j]
             section = self.lineFaceSection(line, f2)
             if len(section) <= 2:
                 continue
             # Add points discarding start and end
             nPoints2 = nPoints + len(section) - 2
         # If the number of intersection points is pair, is a
         # external face. So if we found an odd points intersection,
         # face must be discarded.
         if (nPoints % 2) or (nPoints2 % 2):
             continue
         result.append(f)
         self.timer.start(0.0)
         self.loop.exec_()
         if(not self.running):
             break
     return result
 def getSize(self):
     "returns (length,width) of the rectangle"
     p1 = Vector(self.coords.point.getValues()[0].getValue())
     p2 = Vector(self.coords.point.getValues()[2].getValue())
     diag = p2.sub(p1)
     return ((DraftVecUtils.project(diag,self.u)).Length,(DraftVecUtils.project(diag,self.v)).Length)
Beispiel #47
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)
Beispiel #48
0
 def p3(self, point=None):
     "sets or gets the opposite (diagonal) point of the rectangle"
     if point:
         self.update(point)
     else:
         return Vector(self.coords.point.getValues()[2].getValue())
Beispiel #49
0
    def execute(self, obj):
        "creates the structure shape"

        import Part, DraftGeomUtils

        if self.clone(obj):
            return

        normal, length, width, height = self.getDefaultValues(obj)

        # creating base shape
        pl = obj.Placement
        base = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.isNull():
                    return
                if not obj.Base.Shape.isValid():
                    if not obj.Base.Shape.Solids:
                        # let pass invalid objects if they have solids...
                        return
                if hasattr(obj, "Tool"):
                    if obj.Tool:
                        try:
                            base = obj.Tool.Shape.copy().makePipe(
                                obj.Base.Shape.copy())
                        except Part.OCCError:
                            FreeCAD.Console.PrintError(
                                translate(
                                    "Arch",
                                    "Error: The base shape couldn't be extruded along this tool object"
                                ))
                            return
                if not base:
                    if not height:
                        return
                    if obj.Normal == Vector(0, 0, 0):
                        p = FreeCAD.Placement(obj.Base.Placement)
                        normal = p.Rotation.multVec(normal)
                    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():
                            try:
                                base = Part.Face(base.Wires[0])
                                base = base.extrude(normal)
                            except Part.OCCError:
                                FreeCAD.Console.PrintError(
                                    obj.Label + " : " + str(
                                        translate(
                                            "Arch",
                                            "Unable to extrude the base shape\n"
                                        )))
                                return

            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 and (
                                not sh.isNull()):
                            base = sh
                        else:
                            FreeCAD.Console.PrintWarning(
                                str(
                                    translate(
                                        "Arch",
                                        "This mesh is an invalid solid")))
                            obj.Base.ViewObject.show()
        else:
            base = self.getProfiles(obj)
            if base:
                if length > height:
                    normal = normal.multiply(length)
                else:
                    normal = normal.multiply(height)
                base = Part.Face(base[0])
                base = base.extrude(normal)

        base = self.processSubShapes(obj, base, pl)
        self.applyShape(obj, base, pl)
Beispiel #50
0
 def p2(self):
     "gets the second point (on u axis) of the rectangle"
     return Vector(self.coords.point.getValues()[3].getValue())
Beispiel #51
0
    def execute(self,obj):
        "creates the structure shape"

        import Part, DraftGeomUtils
        
        if self.clone(obj):
            return

        normal,length,width,height = self.getDefaultValues(obj)

        # creating base shape
        pl = obj.Placement
        base = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.isNull():
                    return
                if not obj.Base.Shape.isValid():
                    if not obj.Base.Shape.Solids:
                        # let pass invalid objects if they have solids...
                        return
                if hasattr(obj,"Tool"):
                    if obj.Tool:
                        try:
                            base = obj.Tool.Shape.copy().makePipe(obj.Base.Shape.copy())
                        except Part.OCCError:
                            FreeCAD.Console.PrintError(translate("Arch","Error: The base shape couldn't be extruded along this tool object"))
                            return
                if not base:
                    if not height:
                        return
                    if obj.Normal == Vector(0,0,0):
                        p = FreeCAD.Placement(obj.Base.Placement)
                        normal = p.Rotation.multVec(normal)
                    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():
                            try:
                                base = Part.Face(base.Wires[0])
                                base = base.extrude(normal)
                            except Part.OCCError:
                                FreeCAD.Console.PrintError(obj.Label+" : "+str(translate("Arch","Unable to extrude the base shape\n")))
                                return

            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 and (not sh.isNull()):
                            base = sh
                        else:
                            FreeCAD.Console.PrintWarning(str(translate("Arch","This mesh is an invalid solid")))
                            obj.Base.ViewObject.show()
        else:
            base = self.getProfiles(obj)
            if base:
                if length > height:
                    normal = normal.multiply(length)
                else:
                    normal = normal.multiply(height)
                base = Part.Face(base[0])
                base = base.extrude(normal)

        base = self.processSubShapes(obj,base,pl)
        self.applyShape(obj,base,pl)
Beispiel #52
0
 def p1(self, point=None):
     "sets or gets the base point of the rectangle"
     if point:
         self.setorigin(point)
     else:
         return Vector(self.coords.point.getValues()[0].getValue())
class rectangleTracker(Tracker):
    "A Rectangle tracker, used by the rectangle tool"
    def __init__(self,dotted=False,scolor=None,swidth=None,face=False):
        self.origin = Vector(0,0,0)
        line = coin.SoLineSet()
        line.numVertices.setValue(5)
        self.coords = coin.SoCoordinate3() # this is the coordinate
        self.coords.point.setValues(0,50,[[0,0,0],[2,0,0],[2,2,0],[0,2,0],[0,0,0]])
        if face:
            m1 = coin.SoMaterial()
            m1.transparency.setValue(0.5)
            m1.diffuseColor.setValue([0.5,0.5,1.0])
            f = coin.SoIndexedFaceSet()
            f.coordIndex.setValues([0,1,2,3])
            Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line,m1,f],name="rectangleTracker")
        else:
            Tracker.__init__(self,dotted,scolor,swidth,[self.coords,line],name="rectangleTracker")
        self.u = FreeCAD.DraftWorkingPlane.u
        self.v = FreeCAD.DraftWorkingPlane.v

    def setorigin(self,point):
        "sets the base point of the rectangle"
        self.coords.point.set1Value(0,point.x,point.y,point.z)
        self.coords.point.set1Value(4,point.x,point.y,point.z)
        self.origin = point

    def update(self,point):
        "sets the opposite (diagonal) point of the rectangle"
        diagonal = point.sub(self.origin)
        inpoint1 = self.origin.add(DraftVecUtils.project(diagonal,self.v))
        inpoint2 = self.origin.add(DraftVecUtils.project(diagonal,self.u))
        self.coords.point.set1Value(1,inpoint1.x,inpoint1.y,inpoint1.z)
        self.coords.point.set1Value(2,point.x,point.y,point.z)
        self.coords.point.set1Value(3,inpoint2.x,inpoint2.y,inpoint2.z)

    def setPlane(self,u,v=None):
        '''sets given (u,v) vectors as working plane. You can give only u
        and v will be deduced automatically given current workplane'''
        self.u = u
        if v:
            self.v = v
        else:
            norm = FreeCAD.DraftWorkingPlane.u.cross(FreeCAD.DraftWorkingPlane.v)
            self.v = self.u.cross(norm)

    def p1(self,point=None):
        "sets or gets the base point of the rectangle"
        if point:
            self.setorigin(point)
        else:
            return Vector(self.coords.point.getValues()[0].getValue())

    def p2(self):
        "gets the second point (on u axis) of the rectangle"
        return Vector(self.coords.point.getValues()[3].getValue())

    def p3(self,point=None):
        "sets or gets the opposite (diagonal) point of the rectangle"
        if point:
            self.update(point)
        else:
            return Vector(self.coords.point.getValues()[2].getValue())

    def p4(self):
        "gets the fourth point (on v axis) of the rectangle"
        return Vector(self.coords.point.getValues()[1].getValue())
                
    def getSize(self):
        "returns (length,width) of the rectangle"
        p1 = Vector(self.coords.point.getValues()[0].getValue())
        p2 = Vector(self.coords.point.getValues()[2].getValue())
        diag = p2.sub(p1)
        return ((DraftVecUtils.project(diag,self.u)).Length,(DraftVecUtils.project(diag,self.v)).Length)

    def getNormal(self):
        "returns the normal of the rectangle"
        return (self.u.cross(self.v)).normalize()
Beispiel #54
0
class rectangleTracker(Tracker):
    "A Rectangle tracker, used by the rectangle tool"

    def __init__(self, dotted=False, scolor=None, swidth=None, face=False):
        self.origin = Vector(0, 0, 0)
        line = coin.SoLineSet()
        line.numVertices.setValue(5)
        self.coords = coin.SoCoordinate3()  # this is the coordinate
        self.coords.point.setValues(
            0, 50, [[0, 0, 0], [2, 0, 0], [2, 2, 0], [0, 2, 0], [0, 0, 0]])
        if face:
            m1 = coin.SoMaterial()
            m1.transparency.setValue(0.5)
            m1.diffuseColor.setValue([0.5, 0.5, 1.0])
            f = coin.SoIndexedFaceSet()
            f.coordIndex.setValues([0, 1, 2, 3])
            Tracker.__init__(self,
                             dotted,
                             scolor,
                             swidth, [self.coords, line, m1, f],
                             name="rectangleTracker")
        else:
            Tracker.__init__(self,
                             dotted,
                             scolor,
                             swidth, [self.coords, line],
                             name="rectangleTracker")
        self.u = FreeCAD.DraftWorkingPlane.u
        self.v = FreeCAD.DraftWorkingPlane.v

    def setorigin(self, point):
        "sets the base point of the rectangle"
        self.coords.point.set1Value(0, point.x, point.y, point.z)
        self.coords.point.set1Value(4, point.x, point.y, point.z)
        self.origin = point

    def update(self, point):
        "sets the opposite (diagonal) point of the rectangle"
        diagonal = point.sub(self.origin)
        inpoint1 = self.origin.add(DraftVecUtils.project(diagonal, self.v))
        inpoint2 = self.origin.add(DraftVecUtils.project(diagonal, self.u))
        self.coords.point.set1Value(1, inpoint1.x, inpoint1.y, inpoint1.z)
        self.coords.point.set1Value(2, point.x, point.y, point.z)
        self.coords.point.set1Value(3, inpoint2.x, inpoint2.y, inpoint2.z)

    def setPlane(self, u, v=None):
        '''sets given (u,v) vectors as working plane. You can give only u
        and v will be deduced automatically given current workplane'''
        self.u = u
        if v:
            self.v = v
        else:
            norm = FreeCAD.DraftWorkingPlane.u.cross(
                FreeCAD.DraftWorkingPlane.v)
            self.v = self.u.cross(norm)

    def p1(self, point=None):
        "sets or gets the base point of the rectangle"
        if point:
            self.setorigin(point)
        else:
            return Vector(self.coords.point.getValues()[0].getValue())

    def p2(self):
        "gets the second point (on u axis) of the rectangle"
        return Vector(self.coords.point.getValues()[3].getValue())

    def p3(self, point=None):
        "sets or gets the opposite (diagonal) point of the rectangle"
        if point:
            self.update(point)
        else:
            return Vector(self.coords.point.getValues()[2].getValue())

    def p4(self):
        "gets the fourth point (on v axis) of the rectangle"
        return Vector(self.coords.point.getValues()[1].getValue())

    def getSize(self):
        "returns (length,width) of the rectangle"
        p1 = Vector(self.coords.point.getValues()[0].getValue())
        p2 = Vector(self.coords.point.getValues()[2].getValue())
        diag = p2.sub(p1)
        return ((DraftVecUtils.project(diag, self.u)).Length,
                (DraftVecUtils.project(diag, self.v)).Length)

    def getNormal(self):
        "returns the normal of the rectangle"
        return (self.u.cross(self.v)).normalize()

    def isInside(self, point):
        "returns True if the given point is inside the rectangle"
        vp = point.sub(self.p1())
        uv = self.p2().sub(self.p1())
        vv = self.p4().sub(self.p1())
        uvp = DraftVecUtils.project(vp, uv)
        vvp = DraftVecUtils.project(vp, vv)
        if uvp.getAngle(uv) < 1:
            if vvp.getAngle(vv) < 1:
                if uvp.Length <= uv.Length:
                    if vvp.Length <= vv.Length:
                        return True
        return False
 def getSize(self):
     "returns (length,width) of the rectangle"
     p1 = Vector(self.coords.point.getValues()[0].getValue())
     p2 = Vector(self.coords.point.getValues()[2].getValue())
     diag = p2.sub(p1)
     return ((DraftVecUtils.project(diag,self.u)).Length,(DraftVecUtils.project(diag,self.v)).Length)
Beispiel #56
0
    def onChanged(self, vobj, prop):

        if prop == "LineColor":
            if hasattr(vobj, "LineColor"):
                l = vobj.LineColor
                self.mat1.diffuseColor.setValue([l[0], l[1], l[2]])
                self.mat2.diffuseColor.setValue([l[0], l[1], l[2]])
        elif prop == "Transparency":
            if hasattr(vobj, "Transparency"):
                self.mat2.transparency.setValue(vobj.Transparency / 100.0)
        elif prop in ["DisplayLength", "DisplayHeight", "ArrowSize"]:
            if hasattr(vobj, "DisplayLength") and hasattr(
                    vobj, "DisplayHeight"):
                ld = vobj.DisplayLength.Value / 2
                hd = vobj.DisplayHeight.Value / 2
            elif hasattr(vobj, "DisplaySize"):
                # old objects
                ld = vobj.DisplaySize.Value / 2
                hd = vobj.DisplaySize.Value / 2
            else:
                ld = 1
                hd = 1
            verts = []
            fverts = []
            for v in [[-ld, -hd], [ld, -hd], [ld, hd], [-ld, hd]]:
                if hasattr(vobj, "ArrowSize"):
                    l1 = vobj.ArrowSize.Value if vobj.ArrowSize.Value > 0 else 0.1
                else:
                    l1 = 0.1
                l2 = l1 / 3
                pl = FreeCAD.Placement(vobj.Object.Placement)
                p1 = pl.multVec(Vector(v[0], v[1], 0))
                p2 = pl.multVec(Vector(v[0], v[1], -l1))
                p3 = pl.multVec(Vector(v[0] - l2, v[1], -l1 + l2))
                p4 = pl.multVec(Vector(v[0] + l2, v[1], -l1 + l2))
                p5 = pl.multVec(Vector(v[0], v[1] - l2, -l1 + l2))
                p6 = pl.multVec(Vector(v[0], v[1] + l2, -l1 + l2))
                verts.extend([[p1.x, p1.y, p1.z], [p2.x, p2.y, p2.z]])
                fverts.append([p1.x, p1.y, p1.z])
                verts.extend([[p2.x, p2.y, p2.z], [p3.x, p3.y, p3.z],
                              [p4.x, p4.y, p4.z], [p2.x, p2.y, p2.z]])
                verts.extend([[p2.x, p2.y, p2.z], [p5.x, p5.y, p5.z],
                              [p6.x, p6.y, p6.z], [p2.x, p2.y, p2.z]])
            verts.extend(fverts + [fverts[0]])
            self.lcoords.point.setValues(verts)
            self.fcoords.point.setValues(fverts)
        elif prop == "LineWidth":
            self.drawstyle.lineWidth = vobj.LineWidth
        elif prop in ["CutView", "CutMargin"]:
            if hasattr(vobj,
                       "CutView") and FreeCADGui.ActiveDocument.ActiveView:
                sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
                if vobj.CutView:
                    if self.clip:
                        sg.removeChild(self.clip)
                        self.clip = None
                    for o in Draft.getGroupContents(vobj.Object.Objects,
                                                    walls=True):
                        if hasattr(o.ViewObject, "Lighting"):
                            o.ViewObject.Lighting = "One side"
                    self.clip = coin.SoClipPlane()
                    self.clip.on.setValue(True)
                    norm = vobj.Object.Proxy.getNormal(vobj.Object)
                    mp = vobj.Object.Shape.CenterOfMass
                    mp = DraftVecUtils.project(mp, norm)
                    dist = mp.Length  #- 0.1 # to not clip exactly on the section object
                    norm = norm.negative()
                    marg = 1
                    if hasattr(vobj, "CutMargin"):
                        marg = vobj.CutMargin.Value
                    if mp.getAngle(norm) > 1:
                        dist += marg
                        dist = -dist
                    else:
                        dist -= marg
                    plane = coin.SbPlane(coin.SbVec3f(norm.x, norm.y, norm.z),
                                         dist)
                    self.clip.plane.setValue(plane)
                    sg.insertChild(self.clip, 0)
                else:
                    if self.clip:
                        sg.removeChild(self.clip)
                        self.clip = None
        return
def FSMesh(obj, recompute=False):
	""" Get free surface mesh in matrix mode.
	@param obj Created Part::FeaturePython object.
	@param recompute True if mesh must be recomputed, False otherwise.
	@return Faces matrix
	"""
	nx = obj.FS_Nx
	ny = obj.FS_Ny
	if not recompute:
		faces = []
		for i in range(0,nx):
			faces.append([])
			for j in range(0,ny):
				faces[i].append(FreeSurfaceFace(obj.FS_Position[j + i*ny],
												obj.FS_Normal[j + i*ny],
												obj.FS_Area[j + i*ny]))
		return faces
	# Transform positions into a mesh
	pos = []
	for i in range(0,nx):
		pos.append([])
		for j in range(0,ny):
			pos[i].append(obj.FS_Position[j + i*ny])
	# Recompute normals and dimensions
	normal = []
	l	  = []
	b	  = []
	for i in range(0,nx):
		normal.append([])
		l.append([])
		b.append([])
		for j in range(0,ny):
			i0 = i-1
			i1 = i+1
			fi = 1.0
			j0 = j-1
			j1 = j+1
			fj = 1.0
			if i == 0:
				i0 = i
				i1 = i+1
				fi = 2.0
			if i == nx-1:
				i0 = i-1
				i1 = i
				fi = 2.0
			if j == 0:
				j0 = j
				j1 = j+1
				fj = 2.0
			if j == ny-1:
				j0 = j-1
				j1 = j
				fj = 2.0
			l[i].append(fi*(obj.FS_Position[j + i1*ny].x - obj.FS_Position[j + i0*ny].x))
			b[i].append(fj*(obj.FS_Position[j1 + i*ny].y - obj.FS_Position[j0 + i*ny].y))
			xvec = Vector(obj.FS_Position[j + i1*ny].x - obj.FS_Position[j + i0*ny].x,
						  obj.FS_Position[j + i1*ny].y - obj.FS_Position[j + i0*ny].y,
						  obj.FS_Position[j + i1*ny].z - obj.FS_Position[j + i0*ny].z)
			yvec = Vector(obj.FS_Position[j1 + i*ny].x - obj.FS_Position[j0 + i*ny].x,
						  obj.FS_Position[j1 + i*ny].y - obj.FS_Position[j0 + i*ny].y,
						  obj.FS_Position[j1 + i*ny].z - obj.FS_Position[j0 + i*ny].z)
			n = Vector(xvec.cross(yvec))	# Z positive
			normal[i].append(n.normalize())
	# Create faces
	faces = []
	for i in range(0,nx):
		faces.append([])
		for j in range(0,ny):
			faces[i].append(FreeSurfaceFace(pos[i][j], normal[i][j], l[i][j], b[i][j]))
	# Reconstruct mesh data
	for i in range(0,nx):
		for j in range(0,ny):
			obj.FS_Position[j + i*ny] = faces[i][j].pos
			obj.FS_Normal[j + i*ny]   = faces[i][j].normal
			obj.FS_Area[j + i*ny]	 = faces[i][j].area
	return faces
Beispiel #58
0
def xy(point):
    """(point)
    Convenience function to return the projection of the Vector in the XY-plane."""
    return Vector(point.x, point.y, 0)
 def transF(p):
     p0 = p - flatcentre
     return p0 * cs + Vector(-p0.y, p0.x, 0) * sn + uvcentre + explodev
Beispiel #60
0
 def p4(self):
     "gets the fourth point (on v axis) of the rectangle"
     return Vector(self.coords.point.getValues()[1].getValue())