Beispiel #1
0
 def getBase(self, obj, wire, normal, width, height):
     "returns a full shape from a base wire"
     import DraftGeomUtils, Part
     flat = False
     if hasattr(obj.ViewObject, "DisplayMode"):
         flat = (obj.ViewObject.DisplayMode == "Flat 2D")
     dvec = DraftGeomUtils.vec(wire.Edges[0]).cross(normal)
     if not DraftVecUtils.isNull(dvec):
         dvec.normalize()
     if obj.Align == "Left":
         dvec = dvec.multiply(width)
         w2 = DraftGeomUtils.offsetWire(wire, dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1, w2)
     elif obj.Align == "Right":
         dvec = dvec.multiply(width)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire, dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1, w2)
     elif obj.Align == "Center":
         dvec = dvec.multiply(width / 2)
         w1 = DraftGeomUtils.offsetWire(wire, dvec)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire, dvec)
         sh = DraftGeomUtils.bind(w1, w2)
     # fixing self-intersections
     sh.fix(0.1, 0, 1)
     if height and (not flat):
         norm = Vector(normal).multiply(height)
         sh = sh.extrude(norm)
     return sh
Beispiel #2
0
 def getbase(wire):
     "returns a full shape from a base wire"
     dvec = DraftGeomUtils.vec(wire.Edges[0]).cross(normal)
     dvec.normalize()
     if obj.Align == "Left":
         dvec = dvec.multiply(width)
         w2 = DraftGeomUtils.offsetWire(wire, dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1, w2)
     elif obj.Align == "Right":
         dvec = dvec.multiply(width)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire, dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1, w2)
     elif obj.Align == "Center":
         dvec = dvec.multiply(width / 2)
         w1 = DraftGeomUtils.offsetWire(wire, dvec)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire, dvec)
         sh = DraftGeomUtils.bind(w1, w2)
     # fixing self-intersections
     sh.fix(0.1, 0, 1)
     if height and (not flat):
         norm = Vector(normal).multiply(height)
         sh = sh.extrude(norm)
     return sh
Beispiel #3
0
 def calc(self):
     import Part
     if (self.p1 != None) and (self.p2 != None):
         points = [DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True),\
                       DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True)]
         if self.p3 != None:
             p1 = self.p1
             p4 = self.p2
             if DraftVecUtils.equals(p1, p4):
                 proj = None
             else:
                 base = Part.Line(p1, p4).toShape()
                 proj = DraftGeomUtils.findDistance(self.p3, base)
             if not proj:
                 p2 = p1
                 p3 = p4
             else:
                 p2 = p1.add(DraftVecUtils.neg(proj))
                 p3 = p4.add(DraftVecUtils.neg(proj))
             points = [
                 DraftVecUtils.tup(p1),
                 DraftVecUtils.tup(p2),
                 DraftVecUtils.tup(p3),
                 DraftVecUtils.tup(p4)
             ]
         self.coords.point.setValues(0, 4, points)
Beispiel #4
0
 def snapToPolar(self,point,last):
     "snaps to polar lines from the given point"
     if self.isEnabled('ortho') and (not self.mask): 
         if last:
             vecs = []
             if hasattr(FreeCAD,"DraftWorkingPlane"):
                 ax = [FreeCAD.DraftWorkingPlane.u,
                        FreeCAD.DraftWorkingPlane.v,
                        FreeCAD.DraftWorkingPlane.axis]
             else:
                 ax = [FreeCAD.Vector(1,0,0),
                       FreeCAD.Vector(0,1,0),
                       FreeCAD.Vector(0,0,1)]
             for a in self.polarAngles:
                     if a == 90:
                         vecs.extend([ax[0],DraftVecUtils.neg(ax[0])])
                         vecs.extend([ax[1],DraftVecUtils.neg(ax[1])])
                     else:
                         v = DraftVecUtils.rotate(ax[0],math.radians(a),ax[2])
                         vecs.extend([v,DraftVecUtils.neg(v)])
                         v = DraftVecUtils.rotate(ax[1],math.radians(a),ax[2])
                         vecs.extend([v,DraftVecUtils.neg(v)])
             for v in vecs:
                 de = Part.Line(last,last.add(v)).toShape()  
                 np = self.getPerpendicular(de,point)
                 if ((self.radius == 0) and (point.sub(last).getAngle(v) < 0.087)) \
                 or ((np.sub(point)).Length < self.radius):
                     if self.tracker:
                         self.tracker.setCoords(np)
                         self.tracker.setMarker(self.mk['parallel'])
                         self.tracker.on()
                         self.setCursor('ortho')
                     return np,de
     return point,None
 def snapToPolar(self,point,last):
     "snaps to polar lines from the given point"
     if self.isEnabled('ortho') and (not self.mask): 
         if last:
             vecs = []
             if hasattr(FreeCAD,"DraftWorkingPlane"):
                 ax = [FreeCAD.DraftWorkingPlane.u,
                        FreeCAD.DraftWorkingPlane.v,
                        FreeCAD.DraftWorkingPlane.axis]
             else:
                 ax = [FreeCAD.Vector(1,0,0),
                       FreeCAD.Vector(0,1,0),
                       FreeCAD.Vector(0,0,1)]
             for a in self.polarAngles:
                     if a == 90:
                         vecs.extend([ax[0],DraftVecUtils.neg(ax[0])])
                         vecs.extend([ax[1],DraftVecUtils.neg(ax[1])])
                     else:
                         v = DraftVecUtils.rotate(ax[0],math.radians(a),ax[2])
                         vecs.extend([v,DraftVecUtils.neg(v)])
                         v = DraftVecUtils.rotate(ax[1],math.radians(a),ax[2])
                         vecs.extend([v,DraftVecUtils.neg(v)])
             for v in vecs:
                 de = Part.Line(last,last.add(v)).toShape()  
                 np = self.getPerpendicular(de,point)
                 if ((self.radius == 0) and (point.sub(last).getAngle(v) < 0.087)) \
                 or ((np.sub(point)).Length < self.radius):
                     if self.tracker:
                         self.tracker.setCoords(np)
                         self.tracker.setMarker(self.mk['parallel'])
                         self.tracker.on()
                         self.setCursor('ortho')
                     return np,de
     return point,None
 def getbase(wire):
     "returns a full shape from a base wire"
     dvec = DraftGeomUtils.vec(wire.Edges[0]).cross(normal)
     dvec.normalize()
     if obj.Align == "Left":
         dvec = dvec.multiply(width)
         w2 = DraftGeomUtils.offsetWire(wire,dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1,w2)
     elif obj.Align == "Right":
         dvec = dvec.multiply(width)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire,dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1,w2)
     elif obj.Align == "Center":
         dvec = dvec.multiply(width/2)
         w1 = DraftGeomUtils.offsetWire(wire,dvec)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire,dvec)
         sh = DraftGeomUtils.bind(w1,w2)
     # fixing self-intersections
     sh.fix(0.1,0,1)
     if height and (not flat):
         norm = Vector(normal).multiply(height)
         sh = sh.extrude(norm)
     return sh
Beispiel #7
0
 def getBase(self,obj,wire,normal,width,height):
     "returns a full shape from a base wire"
     import DraftGeomUtils,Part
     flat = False
     if hasattr(obj.ViewObject,"DisplayMode"):
         flat = (obj.ViewObject.DisplayMode == "Flat 2D")
     dvec = DraftGeomUtils.vec(wire.Edges[0]).cross(normal)
     if not DraftVecUtils.isNull(dvec):
         dvec.normalize()
     if obj.Align == "Left":
         dvec = dvec.multiply(width)
         w2 = DraftGeomUtils.offsetWire(wire,dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1,w2)
     elif obj.Align == "Right":
         dvec = dvec.multiply(width)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire,dvec)
         w1 = Part.Wire(DraftGeomUtils.sortEdges(wire.Edges))
         sh = DraftGeomUtils.bind(w1,w2)
     elif obj.Align == "Center":
         dvec = dvec.multiply(width/2)
         w1 = DraftGeomUtils.offsetWire(wire,dvec)
         dvec = DraftVecUtils.neg(dvec)
         w2 = DraftGeomUtils.offsetWire(wire,dvec)
         sh = DraftGeomUtils.bind(w1,w2)
     # fixing self-intersections
     sh.fix(0.1,0,1)
     if height and (not flat):
         norm = Vector(normal).multiply(height)
         sh = sh.extrude(norm)
     return sh
Beispiel #8
0
 def execute(self, obj):
     if obj.Source:
         if hasattr(obj.Source.Proxy,"BaseProfile"):
             p = obj.Source.Proxy.BaseProfile
             n = obj.Source.Proxy.ExtrusionVector
             import Drawing
             svg1 = ""
             svg2 = ""
             result = ""
             svg1 = Drawing.projectToSVG(p,DraftVecUtils.neg(n))
             if svg1:
                 w = str(obj.LineWidth/obj.Scale) #don't let linewidth be influenced by the scale...
                 svg1 = svg1.replace('stroke-width="0.35"','stroke-width="'+w+'"')
                 svg1 = svg1.replace('stroke-width="1"','stroke-width="'+w+'"')
                 svg1 = svg1.replace('stroke-width:0.01','stroke-width:'+w)
                 svg1 = svg1.replace('scale(1,-1)','scale('+str(obj.Scale)+',-'+str(obj.Scale)+')')
             if obj.Source.Tag:
                 svg2 = '<text id="tag'+obj.Name+'"'
                 svg2 += ' fill="'+Draft.getrgb(obj.TextColor)+'"'
                 svg2 += ' font-size="'+str(obj.FontSize)+'"'
                 svg2 += ' style="text-anchor:start;text-align:left;'
                 svg2 += ' font-family:'+obj.FontName+'" '
                 svg2 += ' transform="translate(' + str(obj.TextX) + ',' + str(obj.TextY) + ')">'
                 svg2 += '<tspan>'+obj.Source.Tag+'</tspan></text>\n'
             result += '<g id="' + obj.Name + '"'
             result += ' transform="'
             result += 'rotate('+str(obj.Rotation)+','+str(obj.X)+','+str(obj.Y)+') '
             result += 'translate('+str(obj.X)+','+str(obj.Y)+')'
             result += '">\n  '
             result += svg1
             result += svg2
             result += '</g>'
             obj.ViewResult = result
Beispiel #9
0
    def updateSVG(self, obj, join=False):
        "encapsulates a svg fragment into a transformation node"
        import Part, DraftGeomUtils
        if hasattr(obj, "Source"):
            if obj.Source:
                if obj.Source.Objects:
                    objs = Draft.getGroupContents(obj.Source.Objects)
                    svg = ''

                    # generating SVG
                    linewidth = obj.LineWidth / obj.Scale
                    if obj.RenderingMode == "Solid":
                        # render using the Arch Vector Renderer
                        import ArchVRM
                        render = ArchVRM.Renderer()
                        render.setWorkingPlane(obj.Source.Placement)
                        render.addObjects(
                            Draft.getGroupContents(objs, walls=True))
                        render.cut(obj.Source.Shape)
                        svg += render.getViewSVG(linewidth=linewidth)
                        svg += render.getSectionSVG(linewidth=linewidth * 2)
                        # print render.info()

                    else:
                        # render using the Drawing module
                        import Drawing
                        shapes = []
                        for o in objs:
                            if o.isDerivedFrom("Part::Feature"):
                                shapes.append(o.Shape)
                        if shapes:
                            base = shape.pop()
                        for sh in shapes:
                            base = base.fuse(sh)
                        svgf = Drawing.projectToSVG(
                            base, DraftVecUtils.neg(direction))
                        if svgf:
                            svgf = svgf.replace(
                                'stroke-width="0.35"',
                                'stroke-width="' + str(linewidth) + 'px"')
                            svgf = svgf.replace(
                                'stroke-width:0.01',
                                'stroke-width:' + str(linewidth) + 'px')
                        svg += svgf

                    result = ''
                    result += '<g id="' + obj.Name + '"'
                    result += ' transform="'
                    result += 'rotate(' + str(obj.Rotation) + ',' + str(
                        obj.X) + ',' + str(obj.Y) + ') '
                    result += 'translate(' + str(obj.X) + ',' + str(
                        obj.Y) + ') '
                    result += 'scale(' + str(
                        obj.Scale) + ',' + str(-obj.Scale) + ')'
                    result += '">\n'
                    result += svg
                    result += '</g>\n'
                    # print "complete node:",result
                    return result
        return ''
Beispiel #10
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 = DraftVecUtils.neg(v1)
                    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 #11
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 = DraftVecUtils.neg(v1)
                    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 #12
0
 def execute(self, obj):
     if obj.Source:
         if hasattr(obj.Source.Proxy,"BaseProfile"):
             p = obj.Source.Proxy.BaseProfile
             n = obj.Source.Proxy.ExtrusionVector
             import Drawing
             svg1 = ""
             svg2 = ""
             result = ""
             svg1 = Drawing.projectToSVG(p,DraftVecUtils.neg(n))
             if svg1:
                 w = str(obj.LineWidth/obj.Scale) #don't let linewidth be influenced by the scale...
                 svg1 = svg1.replace('stroke-width="0.35"','stroke-width="'+w+'"')
                 svg1 = svg1.replace('stroke-width="1"','stroke-width="'+w+'"')
                 svg1 = svg1.replace('stroke-width:0.01','stroke-width:'+w)
                 svg1 = svg1.replace('scale(1,-1)','scale('+str(obj.Scale)+',-'+str(obj.Scale)+')')
             if obj.Source.Tag:
                 svg2 = '<text id="tag'+obj.Name+'"'
                 svg2 += ' fill="'+Draft.getrgb(obj.TextColor)+'"'
                 svg2 += ' font-size="'+str(obj.FontSize)+'"'
                 svg2 += ' style="text-anchor:start;text-align:left;'
                 svg2 += ' font-family:'+obj.FontName+'" '
                 svg2 += ' transform="translate(' + str(obj.TextX) + ',' + str(obj.TextY) + ')">'
                 svg2 += '<tspan>'+obj.Source.Tag+'</tspan></text>\n'
             result += '<g id="' + obj.Name + '"'
             result += ' transform="'
             result += 'rotate('+str(obj.Rotation)+','+str(obj.X)+','+str(obj.Y)+') '
             result += 'translate('+str(obj.X)+','+str(obj.Y)+')'
             result += '">\n  '
             result += svg1
             result += svg2
             result += '</g>'
             obj.ViewResult = result
 def makeStairsTread(self,basepoint,depthvec,widthvec,nosing=0,thickness=0):
     "returns the shape of a single tread"
     import Part
     if thickness:
         basepoint = basepoint.add(Vector(0,0,-abs(thickness)))
     if nosing:
         nosevec = DraftVecUtils.scaleTo(DraftVecUtils.neg(depthvec),nosing)
     else:
         nosevec = Vector(0,0,0)
     p1 = basepoint.add(nosevec)
     p2 = p1.add(DraftVecUtils.neg(nosevec)).add(depthvec)
     p3 = p2.add(widthvec)
     p4 = p3.add(DraftVecUtils.neg(depthvec)).add(nosevec)
     step = Part.Face(Part.makePolygon([p1,p2,p3,p4,p1]))
     if thickness:
         step = step.extrude(Vector(0,0,abs(thickness)))
     return step
Beispiel #14
0
 def makeStairsTread(self,basepoint,depthvec,widthvec,nosing=0,thickness=0):
     "returns the shape of a single tread"
     import Part
     if thickness:
         basepoint = basepoint.add(Vector(0,0,-abs(thickness)))
     if nosing:
         nosevec = DraftVecUtils.scaleTo(DraftVecUtils.neg(depthvec),nosing)
     else:
         nosevec = Vector(0,0,0)
     p1 = basepoint.add(nosevec)
     p2 = p1.add(DraftVecUtils.neg(nosevec)).add(depthvec)
     p3 = p2.add(widthvec)
     p4 = p3.add(DraftVecUtils.neg(depthvec)).add(nosevec)
     step = Part.Face(Part.makePolygon([p1,p2,p3,p4,p1]))
     if thickness:
         step = step.extrude(Vector(0,0,abs(thickness)))
     return step
Beispiel #15
0
 def getClosestAxis(self, point):
     "returns which of the workingplane axes is closest from the given vector"
     ax = point.getAngle(self.u)
     ay = point.getAngle(self.v)
     az = point.getAngle(self.axis)
     bx = point.getAngle(DraftVecUtils.neg(self.u))
     by = point.getAngle(DraftVecUtils.neg(self.v))
     bz = point.getAngle(DraftVecUtils.neg(self.axis))
     b = min(ax, ay, az, bx, by, bz)
     if b in [ax, bx]:
         return "x"
     elif b in [ay, by]:
         return "y"
     elif b in [az, bz]:
         return "z"
     else:
         return None
Beispiel #16
0
 def getClosestAxis(self, point):
     "returns which of the workingplane axes is closest from the given vector"
     ax = point.getAngle(self.u)
     ay = point.getAngle(self.v)
     az = point.getAngle(self.axis)
     bx = point.getAngle(DraftVecUtils.neg(self.u))
     by = point.getAngle(DraftVecUtils.neg(self.v))
     bz = point.getAngle(DraftVecUtils.neg(self.axis))
     b = min(ax, ay, az, bx, by, bz)
     if b in [ax, bx]:
         return "x"
     elif b in [ay, by]:
         return "y"
     elif b in [az, bz]:
         return "z"
     else:
         return None
 def calc(self):
     import Part
     if (self.p1 != None) and (self.p2 != None):
         points = [DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True),\
                       DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True)]
         if self.p3 != None:
             p1 = self.p1
             p4 = self.p2
             if DraftVecUtils.equals(p1,p4):
                 proj = None
             else:
                 base = Part.Line(p1,p4).toShape()
                 proj = DraftGeomUtils.findDistance(self.p3,base)
             if not proj:
                 p2 = p1
                 p3 = p4
             else:
                 p2 = p1.add(DraftVecUtils.neg(proj))
                 p3 = p4.add(DraftVecUtils.neg(proj))
             points = [DraftVecUtils.tup(p1),DraftVecUtils.tup(p2),DraftVecUtils.tup(p3),DraftVecUtils.tup(p4)]
         self.coords.point.setValues(0,4,points)
    def updateSVG(self, obj,join=False):
        "encapsulates a svg fragment into a transformation node"
        import Part, DraftGeomUtils
        if hasattr(obj,"Source"):
            if obj.Source:
                if obj.Source.Objects:
                    objs = Draft.getGroupContents(obj.Source.Objects)
                    svg = ''

                    # generating SVG
                    linewidth = obj.LineWidth/obj.Scale        
                    if obj.RenderingMode == "Solid":
                        # render using the Arch Vector Renderer                        
                        import ArchVRM
                        render = ArchVRM.Renderer()
                        render.setWorkingPlane(obj.Source.Placement)
                        render.addObjects(Draft.getGroupContents(objs,walls=True))
                        render.cut(obj.Source.Shape)
                        svg += render.getViewSVG(linewidth=linewidth)
                        svg += render.getSectionSVG(linewidth=linewidth*2)
                        # print render.info()
                        
                    else:
                        # render using the Drawing module
                        import Drawing
                        shapes = []
                        for o in objs:
                            if o.isDerivedFrom("Part::Feature"):
                                shapes.append(o.Shape)
                        if shapes:
                            base = shape.pop()
                        for sh in shapes:
                            base = base.fuse(sh)
                        svgf = Drawing.projectToSVG(base,DraftVecUtils.neg(direction))
                        if svgf:
                            svgf = svgf.replace('stroke-width="0.35"','stroke-width="' + str(linewidth) + 'px"')
                            svgf = svgf.replace('stroke-width:0.01','stroke-width:' + str(linewidth) + 'px')
                        svg += svgf

                    result = ''
                    result += '<g id="' + obj.Name + '"'
                    result += ' transform="'
                    result += 'rotate('+str(obj.Rotation)+','+str(obj.X)+','+str(obj.Y)+') '
                    result += 'translate('+str(obj.X)+','+str(obj.Y)+') '
                    result += 'scale('+str(obj.Scale)+','+str(-obj.Scale)+')'
                    result += '">\n'
                    result += svg
                    result += '</g>\n'
                    # print "complete node:",result
                    return result
        return ''
Beispiel #19
0
 def projectPoint(self, p, direction=None):
     '''project point onto plane, default direction is orthogonal'''
     if not direction:
         direction = self.axis
     lp = self.getLocalCoords(p)
     gp = self.getGlobalCoords(Vector(lp.x, lp.y, 0))
     a = direction.getAngle(gp.sub(p))
     if a > math.pi / 2:
         direction = DraftVecUtils.neg(direction)
         a = math.pi - a
     ld = self.getLocalRot(direction)
     gd = self.getGlobalRot(Vector(ld.x, ld.y, 0))
     hyp = abs(math.tan(a) * lp.z)
     return gp.add(DraftVecUtils.scaleTo(gd, hyp))
Beispiel #20
0
 def update(self,point):
     "this function is called by the Snapper when the mouse is moved"
     b = self.points[0]
     n = FreeCAD.DraftWorkingPlane.axis
     bv = point.sub(b)
     dv = bv.cross(n)
     dv = DraftVecUtils.scaleTo(dv,self.Width/2)
     if self.Align == "Center":
         self.tracker.update([b,point])
     elif self.Align == "Left":
         self.tracker.update([b.add(dv),point.add(dv)])
     else:
         dv = DraftVecUtils.neg(dv)
         self.tracker.update([b.add(dv),point.add(dv)])
Beispiel #21
0
 def projectPoint(self, p, direction=None):
     """project point onto plane, default direction is orthogonal"""
     if not direction:
         direction = self.axis
     lp = self.getLocalCoords(p)
     gp = self.getGlobalCoords(Vector(lp.x, lp.y, 0))
     a = direction.getAngle(gp.sub(p))
     if a > math.pi / 2:
         direction = DraftVecUtils.neg(direction)
         a = math.pi - a
     ld = self.getLocalRot(direction)
     gd = self.getGlobalRot(Vector(ld.x, ld.y, 0))
     hyp = abs(math.tan(a) * lp.z)
     return gp.add(DraftVecUtils.scaleTo(gd, hyp))
 def update(self, point):
     "this function is called by the Snapper when the mouse is moved"
     b = self.points[0]
     n = FreeCAD.DraftWorkingPlane.axis
     bv = point.sub(b)
     dv = bv.cross(n)
     dv = DraftVecUtils.scaleTo(dv, self.Width / 2)
     if self.Align == "Center":
         self.tracker.update([b, point])
     elif self.Align == "Left":
         self.tracker.update([b.add(dv), point.add(dv)])
     else:
         dv = DraftVecUtils.neg(dv)
         self.tracker.update([b.add(dv), point.add(dv)])
def getCutVolume(cutplane, shapes):
    """getCutVolume(cutplane,shapes): returns a cut face and a cut volume
    from the given shapes and the given cutting plane"""
    import Part

    placement = FreeCAD.Placement(cutplane.Placement)
    # building boundbox
    bb = shapes[0].BoundBox
    for sh in shapes[1:]:
        bb.add(sh.BoundBox)
    bb.enlarge(1)
    um = vm = wm = 0
    ax = placement.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    u = placement.Rotation.multVec(FreeCAD.Vector(1, 0, 0))
    v = placement.Rotation.multVec(FreeCAD.Vector(0, 1, 0))
    if not bb.isCutPlane(placement.Base, ax):
        FreeCAD.Console.PrintMessage(str(translate("Arch", "No objects are cut by the plane")))
        return None, None, None
    else:
        corners = [
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMax),
        ]
        for c in corners:
            dv = c.sub(placement.Base)
            um1 = DraftVecUtils.project(dv, u).Length
            um = max(um, um1)
            vm1 = DraftVecUtils.project(dv, v).Length
            vm = max(vm, vm1)
            wm1 = DraftVecUtils.project(dv, ax).Length
            wm = max(wm, wm1)
        p1 = FreeCAD.Vector(-um, vm, 0)
        p2 = FreeCAD.Vector(um, vm, 0)
        p3 = FreeCAD.Vector(um, -vm, 0)
        p4 = FreeCAD.Vector(-um, -vm, 0)
        cutface = Part.makePolygon([p1, p2, p3, p4, p1])
        cutface = Part.Face(cutface)
        cutface.Placement = placement
        cutnormal = DraftVecUtils.scaleTo(ax, wm)
        cutvolume = cutface.extrude(cutnormal)
        cutnormal = DraftVecUtils.neg(cutnormal)
        invcutvolume = cutface.extrude(cutnormal)
        return cutface, cutvolume, invcutvolume
def getCutVolume(cutplane, shapes):
    """getCutVolume(cutplane,shapes): returns a cut face and a cut volume
    from the given shapes and the given cutting plane"""
    import Part
    placement = FreeCAD.Placement(cutplane.Placement)
    # building boundbox
    bb = shapes[0].BoundBox
    for sh in shapes[1:]:
        bb.add(sh.BoundBox)
    bb.enlarge(1)
    um = vm = wm = 0
    ax = placement.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    u = placement.Rotation.multVec(FreeCAD.Vector(1, 0, 0))
    v = placement.Rotation.multVec(FreeCAD.Vector(0, 1, 0))
    if not bb.isCutPlane(placement.Base, ax):
        FreeCAD.Console.PrintMessage(
            str(translate("Arch", "No objects are cut by the plane")))
        return None, None, None
    else:
        corners = [
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMax)
        ]
        for c in corners:
            dv = c.sub(placement.Base)
            um1 = DraftVecUtils.project(dv, u).Length
            um = max(um, um1)
            vm1 = DraftVecUtils.project(dv, v).Length
            vm = max(vm, vm1)
            wm1 = DraftVecUtils.project(dv, ax).Length
            wm = max(wm, wm1)
        p1 = FreeCAD.Vector(-um, vm, 0)
        p2 = FreeCAD.Vector(um, vm, 0)
        p3 = FreeCAD.Vector(um, -vm, 0)
        p4 = FreeCAD.Vector(-um, -vm, 0)
        cutface = Part.makePolygon([p1, p2, p3, p4, p1])
        cutface = Part.Face(cutface)
        cutface.Placement = placement
        cutnormal = DraftVecUtils.scaleTo(ax, wm)
        cutvolume = cutface.extrude(cutnormal)
        cutnormal = DraftVecUtils.neg(cutnormal)
        invcutvolume = cutface.extrude(cutnormal)
        return cutface, cutvolume, invcutvolume
 def getSubVolume(self,base,width,plac=None):
     "returns a subvolume from a base object"
     import Part
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0,0)
         v1 = DraftVecUtils.scaleTo(n,width)
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1,-2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
Beispiel #26
0
 def getSubVolume(self, base, width, plac=None):
     "returns a subvolume from a base object"
     import Part
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0, 0)
         v1 = DraftVecUtils.scaleTo(n, width)
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1, -2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
def getBrepFacesData(obj,scale=1):
    """getBrepFacesData(obj,[scale]): returns a list(0) of lists(1) of lists(2) of lists(3), 
    list(3) being a list of vertices defining a loop, list(2) describing a face from one or 
    more loops, list(1) being the whole solid made of several faces, list(0) being the list
    of solids inside the object. Scale can indicate a scaling factor"""
    if hasattr(obj,"Shape"):
        if obj.Shape:
            if not obj.Shape.isNull():
                if obj.Shape.isValid():
                    sols = []
                    for sol in obj.Shape.Solids:
                        s = []
                        for face in obj.Shape.Faces:
                            f = []
                            f.append(getTuples(face.OuterWire,scale,normal=face.normalAt(0,0),close=False))
                            for wire in face.Wires:
                                if wire.hashCode() != face.OuterWire.hashCode():
                                    f.append(getTuples(wire,scale,normal=DraftVecUtils.neg(face.normalAt(0,0)),close=False))
                            s.append(f)
                        sols.append(s)
                    return sols
    return None
 def getSubVolume(self,base,width,plac=None):
     "returns a subvolume from a base object"
     import Part,DraftVecUtils
     
     # finding biggest wire in the base shape
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0,0)
         v1 = DraftVecUtils.scaleTo(n,width*1.1) # we extrude a little more to avoid face-on-face
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1,-2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
 def getSubVolume(self,base,width,plac=None):
     "returns a subvolume from a base object"
     import Part,DraftVecUtils
     
     # finding biggest wire in the base shape
     max_length = 0
     f = None
     for w in base.Shape.Wires:
         if w.BoundBox.DiagonalLength > max_length:
             max_length = w.BoundBox.DiagonalLength
             f = w
     if f:
         f = Part.Face(f)
         n = f.normalAt(0,0)
         v1 = DraftVecUtils.scaleTo(n,width*1.1) # we extrude a little more to avoid face-on-face
         f.translate(v1)
         v2 = DraftVecUtils.neg(v1)
         v2 = DraftVecUtils.scale(v1,-2)
         f = f.extrude(v2)
         if plac:
             f.Placement = plac
         return f
     return None
def getIfcBrepFacesData(obj,scale=1,tessellation=1):
    """getIfcBrepFacesData(obj,[scale,tesselation]): returns a list(0) of lists(1) of lists(2) of lists(3), 
    list(3) being a list of vertices defining a loop, list(2) describing a face from one or 
    more loops, list(1) being the whole solid made of several faces, list(0) being the list
    of solids inside the object. Scale can indicate a scaling factor. Tesselation is the tesselation
    factor to apply on curved faces."""
    if hasattr(obj,"Shape"):
        import Part
        if obj.Shape:
            if not obj.Shape.isNull():
                if obj.Shape.isValid():
                    sols = []
                    for sol in obj.Shape.Solids:
                        s = []
                        curves = False
                        for face in sol.Faces:
                            for e in face.Edges:
                                if not isinstance(e.Curve,Part.Line):
                                    curves = True
                        if curves:
                            tris = sol.tessellate(tessellation)
                            for tri in tris[1]:
                                f = []
                                for i in tri:
                                    f.append(getTuples(tris[0][i],scale))
                                s.append([f])
                        else:
                            for face in sol.Faces:
                                f = []
                                f.append(getTuples(face.OuterWire,scale,normal=face.normalAt(0,0),close=False))
                                for wire in face.Wires:
                                    if wire.hashCode() != face.OuterWire.hashCode():
                                        f.append(getTuples(wire,scale,normal=DraftVecUtils.neg(face.normalAt(0,0)),close=False))
                                s.append(f)
                        sols.append(s)
                    return sols
    return None
def getRepresentation(ifcfile,
                      context,
                      obj,
                      forcebrep=False,
                      subtraction=False,
                      tessellation=1):
    """returns an IfcShapeRepresentation object or None"""

    import Part, math, DraftGeomUtils, DraftVecUtils
    shapes = []
    placement = None
    productdef = None
    shapetype = "no shape"

    if not forcebrep:
        profile = None
        if hasattr(obj, "Proxy"):
            if hasattr(obj.Proxy, "getProfiles"):
                p = obj.Proxy.getProfiles(obj, noplacement=True)
                extrusionv = obj.Proxy.getExtrusionVector(obj,
                                                          noplacement=True)
                if (len(p) == 1) and extrusionv:
                    p = p[0]
                    r = obj.Proxy.getPlacement(obj)

                    if len(p.Edges) == 1:

                        pxvc = ifcfile.createIfcDirection((1.0, 0.0))
                        povc = ifcfile.createIfcCartesianPoint((0.0, 0.0))
                        pt = ifcfile.createIfcAxis2Placement2D(povc, pxvc)

                        # extruded circle
                        if isinstance(p.Edges[0].Curve, Part.Circle):
                            profile = ifcfile.createIfcCircleProfileDef(
                                "AREA", None, pt, p.Edges[0].Curve.Radius)

                        # extruded ellipse
                        elif isinstance(p.Edges[0].Curve, Part.Ellipse):
                            profile = ifcfile.createIfcEllipseProfileDef(
                                "AREA", None, pt, p.Edges[0].Curve.MajorRadius,
                                p.Edges[0].Curve.MinorRadius)

                    else:
                        curves = False
                        for e in p.Edges:
                            if isinstance(e.Curve, Part.Circle):
                                curves = True

                        # extruded polyline
                        if not curves:
                            w = Part.Wire(DraftGeomUtils.sortEdges(p.Edges))
                            pts = [
                                ifcfile.createIfcCartesianPoint(
                                    tuple(v.Point)[:2])
                                for v in w.Vertexes + [w.Vertexes[0]]
                            ]
                            pol = ifcfile.createIfcPolyline(pts)

                        # extruded composite curve
                        else:
                            segments = []
                            last = None
                            edges = DraftGeomUtils.sortEdges(p.Edges)
                            for e in edges:
                                if isinstance(e.Curve, Part.Circle):
                                    follow = True
                                    if last:
                                        if not DraftVecUtils.equals(
                                                last, e.Vertexes[0].Point):
                                            follow = False
                                            last = e.Vertexes[0].Point
                                        else:
                                            last = e.Vertexes[-1].Point
                                    else:
                                        last = e.Vertexes[-1].Point
                                    p1 = math.degrees(-DraftVecUtils.angle(
                                        e.Vertexes[0].Point.sub(
                                            e.Curve.Center)))
                                    p2 = math.degrees(-DraftVecUtils.angle(
                                        e.Vertexes[-1].Point.sub(
                                            e.Curve.Center)))
                                    da = DraftVecUtils.angle(
                                        e.valueAt(e.FirstParameter + 0.1).sub(
                                            e.Curve.Center),
                                        e.Vertexes[0].Point.sub(
                                            e.Curve.Center))
                                    if p1 < 0:
                                        p1 = 360 + p1
                                    if p2 < 0:
                                        p2 = 360 + p2
                                    if da > 0:
                                        follow = not (follow)
                                    xvc = ifcfile.createIfcDirection(
                                        (1.0, 0.0))
                                    ovc = ifcfile.createIfcCartesianPoint(
                                        tuple(e.Curve.Center)[:2])
                                    plc = ifcfile.createIfcAxis2Placement2D(
                                        ovc, xvc)
                                    cir = ifcfile.createIfcCircle(
                                        plc, e.Curve.Radius)
                                    curve = ifcfile.createIfcTrimmedCurve(
                                        cir, [
                                            ifcfile.create_entity(
                                                "IfcParameterValue", p1)
                                        ], [
                                            ifcfile.create_entity(
                                                "IfcParameterValue", p2)
                                        ], follow, "PARAMETER")

                                else:
                                    verts = [
                                        vertex.Point for vertex in e.Vertexes
                                    ]
                                    if last:
                                        if not DraftVecUtils.equals(
                                                last, verts[0]):
                                            verts.reverse()
                                            last = e.Vertexes[0].Point
                                        else:
                                            last = e.Vertexes[-1].Point
                                    else:
                                        last = e.Vertexes[-1].Point
                                    pts = [
                                        ifcfile.createIfcCartesianPoint(
                                            tuple(v)[:2]) for v in verts
                                    ]
                                    curve = ifcfile.createIfcPolyline(pts)
                                segment = ifcfile.createIfcCompositeCurveSegment(
                                    "CONTINUOUS", True, curve)
                                segments.append(segment)

                            pol = ifcfile.createIfcCompositeCurve(
                                segments, False)
                        profile = ifcfile.createIfcArbitraryClosedProfileDef(
                            "AREA", None, pol)

        if profile:
            xvc = ifcfile.createIfcDirection(
                tuple(r.Rotation.multVec(FreeCAD.Vector(1, 0, 0))))
            zvc = ifcfile.createIfcDirection(
                tuple(r.Rotation.multVec(FreeCAD.Vector(0, 0, 1))))
            ovc = ifcfile.createIfcCartesianPoint(tuple(r.Base))
            lpl = ifcfile.createIfcAxis2Placement3D(ovc, zvc, xvc)
            edir = ifcfile.createIfcDirection(
                tuple(FreeCAD.Vector(extrusionv).normalize()))
            shape = ifcfile.createIfcExtrudedAreaSolid(profile, lpl, edir,
                                                       extrusionv.Length)
            shapes.append(shape)
            solidType = "SweptSolid"
            shapetype = "extrusion"

    if not shapes:

        # brep representation
        fcshape = None
        solidType = "Brep"
        if subtraction:
            if hasattr(obj, "Proxy"):
                if hasattr(obj.Proxy, "getSubVolume"):
                    fcshape = obj.Proxy.getSubVolume(obj)
        if not fcshape:
            if hasattr(obj, "Shape"):
                if obj.Shape:
                    if not obj.Shape.isNull():
                        fcshape = obj.Shape
            elif hasattr(obj, "Terrain"):
                if obj.Terrain:
                    if hasattr(obj.Terrain, "Shape"):
                        if obj.Terrain.Shape:
                            if not obj.Terrain.Shape.isNull():
                                fcshape = obj.Terrain.Shape
        if fcshape:
            solids = []
            if fcshape.Solids:
                dataset = fcshape.Solids
            else:
                dataset = fcshape.Shells
                print "Warning! object contains no solids"
            for fcsolid in dataset:
                faces = []
                curves = False
                for fcface in fcsolid.Faces:
                    for e in fcface.Edges:
                        if not isinstance(e.Curve, Part.Line):
                            curves = True
                if curves:
                    tris = fcsolid.tessellate(tessellation)
                    for tri in tris[1]:
                        pts = [
                            ifcfile.createIfcCartesianPoint(tuple(tris[0][i]))
                            for i in tri
                        ]
                        loop = ifcfile.createIfcPolyLoop(pts)
                        bound = ifcfile.createIfcFaceOuterBound(loop, True)
                        face = ifcfile.createIfcFace([bound])
                        faces.append(face)
                else:
                    for fcface in fcsolid.Faces:
                        loops = []
                        verts = [
                            v.Point for v in Part.Wire(
                                DraftGeomUtils.sortEdges(
                                    fcface.OuterWire.Edges)).Vertexes
                        ]
                        c = fcface.CenterOfMass
                        v1 = verts[0].sub(c)
                        v2 = verts[1].sub(c)
                        n = fcface.normalAt(0, 0)
                        if DraftVecUtils.angle(v2, v1, n) >= 0:
                            verts.reverse(
                            )  # inverting verts order if the direction is couterclockwise
                        pts = [
                            ifcfile.createIfcCartesianPoint(tuple(v))
                            for v in verts
                        ]
                        loop = ifcfile.createIfcPolyLoop(pts)
                        bound = ifcfile.createIfcFaceOuterBound(loop, True)
                        loops.append(bound)
                        for wire in fcface.Wires:
                            if wire.hashCode() != fcface.OuterWire.hashCode():
                                verts = [
                                    v.Point for v in Part.Wire(
                                        DraftGeomUtils.sortEdges(
                                            wire.Edges)).Vertexes
                                ]
                                v1 = verts[0].sub(c)
                                v2 = verts[1].sub(c)
                                if DraftVecUtils.angle(
                                        v2, v1, DraftVecUtils.neg(n)) >= 0:
                                    verts.reverse()
                                pts = [
                                    ifcfile.createIfcCartesianPoint(tuple(v))
                                    for v in verts
                                ]
                                loop = ifcfile.createIfcPolyLoop(pts)
                                bound = ifcfile.createIfcFaceBound(loop, True)
                                loops.append(bound)
                        face = ifcfile.createIfcFace(loops)
                        faces.append(face)
                shell = ifcfile.createIfcClosedShell(faces)
                shape = ifcfile.createIfcFacetedBrep(shell)
                shapes.append(shape)
                shapetype = "brep"

    if shapes:

        if FreeCAD.GuiUp and (not subtraction) and hasattr(
                obj.ViewObject, "ShapeColor"):
            rgb = obj.ViewObject.ShapeColor
            col = ifcfile.createIfcColourRgb(None, rgb[0], rgb[1], rgb[2])
            ssr = ifcfile.createIfcSurfaceStyleRendering(
                col, None, None, None, None, None, None, None, "FLAT")
            iss = ifcfile.createIfcSurfaceStyle(None, "BOTH", [ssr])
            psa = ifcfile.createIfcPresentationStyleAssignment([iss])
            for shape in shapes:
                isi = ifcfile.createIfcStyledItem(shape, [psa], None)

        xvc = ifcfile.createIfcDirection((1.0, 0.0, 0.0))
        zvc = ifcfile.createIfcDirection((0.0, 0.0, 1.0))
        ovc = ifcfile.createIfcCartesianPoint((0.0, 0.0, 0.0))
        gpl = ifcfile.createIfcAxis2Placement3D(ovc, zvc, xvc)
        placement = ifcfile.createIfcLocalPlacement(None, gpl)
        representation = ifcfile.createIfcShapeRepresentation(
            context, 'Body', solidType, shapes)
        productdef = ifcfile.createIfcProductDefinitionShape(
            None, None, [representation])

    return productdef, placement, shapetype
Beispiel #32
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)
Beispiel #33
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 #34
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
        vHeight = Vector(0, 0, float(h) / numberofsteps)
        vWidth = DraftVecUtils.scaleTo(vLength.cross(Vector(0, 0, 1)),
                                       obj.Width)
        vBase = edge.Vertexes[0].Point
        vNose = DraftVecUtils.scaleTo(vLength, -abs(obj.Nosing))
        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)))
            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:
                step = step.extrude(Vector(0, 0, abs(obj.TreadThickness)))
            self.steps.append(step)

        # structure
        lProfile = []
        struct = None
        if obj.Structure == "Massive":
            if obj.StructureThickness:
                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)))
                    lProfile.append(last.add(vHeight))
                    lProfile.append(lProfile[-1].add(vLength))
                resHeight1 = obj.StructureThickness / math.cos(a)
                lProfile.append(lProfile[-1].add(Vector(0, 0, -resHeight1)))
                resHeight2 = ((numberofsteps - 1) * vHeight.Length) - (
                    resHeight1 + obj.TreadThickness)
                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:
                    mvec = DraftVecUtils.scaleTo(vWidth, obj.StructureOffset)
                    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 and obj.StructureThickness:
                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)))
                p1 = vBase.add(l1).add(h1)
                p1 = self.align(p1, obj.Align, vWidth)
                lProfile.append(p1)
                h2 = (obj.StructureThickness / 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 / 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)
                if obj.Structure == "One stringer":
                    if obj.StructureOffset:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset)
                    else:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     (vWidth.Length / 2) -
                                                     obj.StringerWidth / 2)
                    pol.translate(mvec)
                    struct = pol.extrude(evec)
                elif obj.Structure == "Two stringers":
                    pol2 = pol.copy()
                    if obj.StructureOffset:
                        mvec = DraftVecUtils.scaleTo(vWidth,
                                                     obj.StructureOffset)
                        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 #35
0
    def makeMultiEdgesLanding(self, obj, edges):

        "builds a 'multi-edges' landing from edges"  # 'copying' from makeStraightLanding()

        import Part, DraftGeomUtils

        v, vLength, vWidth, vBase = [], [], [], []
        p1o, p2o, p1, p2, p3, p4 = [], [], [], [], [], []
        outline, outlineP1P2, outlineP3P4 = [], [], []

        enum_edges = enumerate(edges)
        for i, edge in enum_edges:
            v.append(DraftGeomUtils.vec(edge))
            vLength.append(Vector(v[i].x, v[i].y, 0))
            # TODO obj.Width[i].Value for different 'edges' / 'sections' of the landing
            vWidth.append(
                DraftVecUtils.scaleTo(vLength[i].cross(Vector(0, 0, 1)),
                                      obj.Width.Value))
            vBase.append(edges[i].Vertexes[0].Point)
            vBase[i] = self.vbaseFollowLastSement(obj, vBase[i])

            # step + structure							# assume all left-align first # no nosing
            p1o.append(vBase[i].add(
                Vector(0, 0, -abs(obj.TreadThickness.Value))))
            p2o.append(p1o[i].add(vLength[i]))
            p1.append(
                self.align(vBase[i], obj.Align, vWidth[i]).add(
                    Vector(0, 0, -abs(obj.TreadThickness.Value))))
            p2.append(p1[i].add(vLength[i]))
            p3.append(p2[i].add(vWidth[i]))
            p4.append(p3[i].add(DraftVecUtils.neg(vLength[i])))

            if obj.Align == 'Left':
                outlineP1P2.append(p1[i])
                outlineP1P2.append(
                    p2[i]
                )  # can better skip 1 'supposedly' overlapping point every pair?
                if i > 0:
                    print("Debug - intersection calculation")
                    print(p3[i - 1])
                    print(p4[i - 1])
                    print(p3[i])
                    print(p4[i])
                    intersection = DraftGeomUtils.findIntersection(
                        p3[i - 1], p4[i - 1], p3[i], p4[i], True, True)
                    print(intersection)
                    outlineP3P4.insert(0, intersection[0])
                else:
                    outlineP3P4.insert(0, p4[i])

            elif obj.Align == 'Right':
                if i > 0:
                    intersection = DraftGeomUtils.findIntersection(
                        p1[i - 1], p2[i - 1], p1[i], p2[i], True, True)
                    outlineP1P2.append(intersection[0])
                else:
                    outlineP1P2.append(p1[i])
                outlineP3P4.insert(0, p4[i])
                outlineP3P4.insert(0, p3[i])

            elif obj.Align == 'Center':
                if i > 0:
                    intersection = DraftGeomUtils.findIntersection(
                        p1[i - 1], p2[i - 1], p1[i], p2[i], True, True)
                    outlineP1P2.append(intersection[0])
                    intersection = DraftGeomUtils.findIntersection(
                        p3[i - 1], p4[i - 1], p3[i], p4[i], True, True)
                    outlineP3P4.insert(0, intersection[0])
                else:
                    outlineP1P2.append(p1[i])
                    outlineP3P4.insert(0, p4[i])

            else:
                outlineP1P2.append(p1[i])
                outlineP1P2.append(p2[i])
                outlineP3P4.insert(0, p4[i])
                outlineP3P4.insert(0, p3[i])

        # add back last/first 'missing' point(s)
        if obj.Align in ['Left', 'Center']:
            outlineP3P4.insert(0, p3[i])
        if obj.Align in ['Right', 'Center']:
            outlineP1P2.append(p2[i])

        outline = outlineP1P2 + outlineP3P4
        outline.append(p1[0])
        print(outlineP1P2)
        print(outlineP3P4)
        print(outline)

        stepFace = Part.Face(Part.makePolygon(outline))

        if obj.TreadThickness.Value:
            step = stepFace.extrude(Vector(0, 0,
                                           abs(obj.TreadThickness.Value)))
            self.steps.append(step)
        else:
            self.pseudosteps.append(stepFace)

        if obj.StructureThickness.Value:
            landingFace = stepFace
            struct = landingFace.extrude(
                Vector(0, 0, -abs(obj.StructureThickness.Value)))

        if struct:
            self.structures.append(struct)

        obj.AbsTop = vBase[1]
Beispiel #36
0
def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tessellation=1):
    """returns an IfcShapeRepresentation object or None"""
    
    import Part,math,DraftGeomUtils,DraftVecUtils
    shapes = []
    placement = None
    productdef = None
    shapetype = "no shape"
        
    if not forcebrep:
        profile = None
        if hasattr(obj,"Proxy"):
            if hasattr(obj.Proxy,"getProfiles"):
                p = obj.Proxy.getProfiles(obj,noplacement=True)
                extrusionv = obj.Proxy.getExtrusionVector(obj,noplacement=True)
                if (len(p) == 1) and extrusionv:
                    p = p[0]
                    r = obj.Proxy.getPlacement(obj)
                    
                    if len(p.Edges) == 1:
                        
                        pxvc = ifcfile.createIfcDirection((1.0,0.0))
                        povc = ifcfile.createIfcCartesianPoint((0.0,0.0))
                        pt = ifcfile.createIfcAxis2Placement2D(povc,pxvc)
                        
                        # extruded circle
                        if isinstance(p.Edges[0].Curve,Part.Circle):
                            profile = ifcfile.createIfcCircleProfileDef("AREA",None,pt, p.Edges[0].Curve.Radius)
                            
                        # extruded ellipse
                        elif isinstance(p.Edges[0].Curve,Part.Ellipse):
                            profile = ifcfile.createIfcEllipseProfileDef("AREA",None,pt, p.Edges[0].Curve.MajorRadius, p.Edges[0].Curve.MinorRadius)     
                            
                    else:
                        curves = False
                        for e in p.Edges:
                            if isinstance(e.Curve,Part.Circle):
                                curves = True
                                
                        # extruded polyline
                        if not curves:
                            w = Part.Wire(DraftGeomUtils.sortEdges(p.Edges))
                            pts = [ifcfile.createIfcCartesianPoint(tuple(v.Point)[:2]) for v in w.Vertexes+[w.Vertexes[0]]]
                            pol = ifcfile.createIfcPolyline(pts)
                            
                        # extruded composite curve
                        else:
                            segments = []
                            last = None
                            edges = DraftGeomUtils.sortEdges(p.Edges)
                            for e in edges:
                                if isinstance(e.Curve,Part.Circle):
                                    follow = True
                                    if last:
                                        if not DraftVecUtils.equals(last,e.Vertexes[0].Point):
                                            follow = False
                                            last = e.Vertexes[0].Point
                                        else:
                                            last = e.Vertexes[-1].Point
                                    else:
                                        last = e.Vertexes[-1].Point
                                    p1 = math.degrees(-DraftVecUtils.angle(e.Vertexes[0].Point.sub(e.Curve.Center)))
                                    p2 = math.degrees(-DraftVecUtils.angle(e.Vertexes[-1].Point.sub(e.Curve.Center)))
                                    da = DraftVecUtils.angle(e.valueAt(e.FirstParameter+0.1).sub(e.Curve.Center),e.Vertexes[0].Point.sub(e.Curve.Center))
                                    if p1 < 0: 
                                        p1 = 360 + p1
                                    if p2 < 0:
                                        p2 = 360 + p2
                                    if da > 0:
                                        follow = not(follow)
                                    xvc =       ifcfile.createIfcDirection((1.0,0.0))
                                    ovc =       ifcfile.createIfcCartesianPoint(tuple(e.Curve.Center)[:2])
                                    plc =       ifcfile.createIfcAxis2Placement2D(ovc,xvc)
                                    cir =       ifcfile.createIfcCircle(plc,e.Curve.Radius)
                                    curve =     ifcfile.createIfcTrimmedCurve(cir,[ifcfile.create_entity("IfcParameterValue",p1)],[ifcfile.create_entity("IfcParameterValue",p2)],follow,"PARAMETER")
                                    
                                else:
                                    verts = [vertex.Point for vertex in e.Vertexes]
                                    if last:
                                        if not DraftVecUtils.equals(last,verts[0]):
                                            verts.reverse()
                                            last = e.Vertexes[0].Point
                                        else:
                                            last = e.Vertexes[-1].Point
                                    else:
                                        last = e.Vertexes[-1].Point
                                    pts =     [ifcfile.createIfcCartesianPoint(tuple(v)[:2]) for v in verts]
                                    curve =   ifcfile.createIfcPolyline(pts)
                                segment = ifcfile.createIfcCompositeCurveSegment("CONTINUOUS",True,curve)
                                segments.append(segment)
                                
                            pol = ifcfile.createIfcCompositeCurve(segments,False)
                        profile = ifcfile.createIfcArbitraryClosedProfileDef("AREA",None,pol)
                        
        if profile:
            xvc =       ifcfile.createIfcDirection(tuple(r.Rotation.multVec(FreeCAD.Vector(1,0,0))))
            zvc =       ifcfile.createIfcDirection(tuple(r.Rotation.multVec(FreeCAD.Vector(0,0,1))))
            ovc =       ifcfile.createIfcCartesianPoint(tuple(r.Base))
            lpl =       ifcfile.createIfcAxis2Placement3D(ovc,zvc,xvc)
            edir =      ifcfile.createIfcDirection(tuple(FreeCAD.Vector(extrusionv).normalize()))
            shape =     ifcfile.createIfcExtrudedAreaSolid(profile,lpl,edir,extrusionv.Length)
            shapes.append(shape)
            solidType = "SweptSolid"
            shapetype = "extrusion"
                
    if not shapes:
        
        # brep representation
        fcshape = None
        solidType = "Brep"
        if subtraction:
            if hasattr(obj,"Proxy"):
                if hasattr(obj.Proxy,"getSubVolume"):
                    fcshape = obj.Proxy.getSubVolume(obj)
        if not fcshape:
            if hasattr(obj,"Shape"):
                if obj.Shape:
                    if not obj.Shape.isNull():
                        fcshape = obj.Shape
            elif hasattr(obj,"Terrain"):
                if obj.Terrain:
                    if hasattr(obj.Terrain,"Shape"):
                        if obj.Terrain.Shape:
                            if not obj.Terrain.Shape.isNull():
                                    fcshape = obj.Terrain.Shape
        if fcshape:
            solids = []
            if fcshape.Solids:
                dataset = fcshape.Solids
            else:
                dataset = fcshape.Shells
                print "Warning! object contains no solids"
            for fcsolid in dataset:
                faces = []
                curves = False
                for fcface in fcsolid.Faces:
                    for e in fcface.Edges:
                        if not isinstance(e.Curve,Part.Line):
                            curves = True
                if curves:
                    tris = fcsolid.tessellate(tessellation)
                    for tri in tris[1]:
                        pts =   [ifcfile.createIfcCartesianPoint(tuple(tris[0][i])) for i in tri]
                        loop =  ifcfile.createIfcPolyLoop(pts)
                        bound = ifcfile.createIfcFaceOuterBound(loop,True)
                        face =  ifcfile.createIfcFace([bound])
                        faces.append(face)
                else:
                    for fcface in fcsolid.Faces:
                        loops = []
                        verts = [v.Point for v in Part.Wire(DraftGeomUtils.sortEdges(fcface.OuterWire.Edges)).Vertexes]
                        c = fcface.CenterOfMass
                        v1 = verts[0].sub(c)
                        v2 = verts[1].sub(c)
                        n = fcface.normalAt(0,0)
                        if DraftVecUtils.angle(v2,v1,n) >= 0:
                            verts.reverse() # inverting verts order if the direction is couterclockwise
                        pts =   [ifcfile.createIfcCartesianPoint(tuple(v)) for v in verts]
                        loop =  ifcfile.createIfcPolyLoop(pts)
                        bound = ifcfile.createIfcFaceOuterBound(loop,True)
                        loops.append(bound)
                        for wire in fcface.Wires:
                            if wire.hashCode() != fcface.OuterWire.hashCode():
                                verts = [v.Point for v in Part.Wire(DraftGeomUtils.sortEdges(wire.Edges)).Vertexes]
                                v1 = verts[0].sub(c)
                                v2 = verts[1].sub(c)
                                if DraftVecUtils.angle(v2,v1,DraftVecUtils.neg(n)) >= 0:
                                    verts.reverse()
                                pts =   [ifcfile.createIfcCartesianPoint(tuple(v)) for v in verts]
                                loop =  ifcfile.createIfcPolyLoop(pts)
                                bound = ifcfile.createIfcFaceBound(loop,True)
                                loops.append(bound)
                        face =  ifcfile.createIfcFace(loops)
                        faces.append(face)
                shell = ifcfile.createIfcClosedShell(faces)
                shape = ifcfile.createIfcFacetedBrep(shell)
                shapes.append(shape)
                shapetype = "brep"

    if shapes:
        
        if FreeCAD.GuiUp and (not subtraction) and hasattr(obj.ViewObject,"ShapeColor"):
            rgb = obj.ViewObject.ShapeColor
            col = ifcfile.createIfcColourRgb(None,rgb[0],rgb[1],rgb[2])
            ssr = ifcfile.createIfcSurfaceStyleRendering(col,None,None,None,None,None,None,None,"FLAT")
            iss = ifcfile.createIfcSurfaceStyle(None,"BOTH",[ssr])
            psa = ifcfile.createIfcPresentationStyleAssignment([iss])
            for shape in shapes:
                isi = ifcfile.createIfcStyledItem(shape,[psa],None)
                
                
        xvc = ifcfile.createIfcDirection((1.0,0.0,0.0))
        zvc = ifcfile.createIfcDirection((0.0,0.0,1.0))
        ovc = ifcfile.createIfcCartesianPoint((0.0,0.0,0.0))
        gpl = ifcfile.createIfcAxis2Placement3D(ovc,zvc,xvc)
        placement = ifcfile.createIfcLocalPlacement(None,gpl)
        representation = ifcfile.createIfcShapeRepresentation(context,'Body',solidType,shapes)
        productdef = ifcfile.createIfcProductDefinitionShape(None,None,[representation])
        
    return productdef,placement,shapetype
Beispiel #37
0
    def __init__(self,
                 size,
                 length,
                 shaft_l,
                 circle_r,
                 circle_h,
                 name="nemamotor",
                 chmf=1,
                 rshaft_l=0,
                 bolt_depth=3,
                 bolt_out=2,
                 container=1,
                 normal=VZ,
                 pos=V0):

        doc = FreeCAD.ActiveDocument
        self.base_place = (0, 0, 0)
        self.size = size
        self.width = kcomp.NEMA_W[size]
        self.length = length
        self.shaft_l = shaft_l
        self.circle_r = circle_r
        self.circle_h = circle_h
        self.chmf = chmf
        self.rshaft_l = rshaft_l
        self.bolt_depth = bolt_depth
        self.bolt_out = bolt_out
        self.container = container
        nnormal = DraftVecUtils.scaleTo(normal, 1)
        self.normal = nnormal
        self.pos = pos
        nemabolt_d = kcomp.NEMA_BOLT_D[size]
        self.nemabolt_d = nemabolt_d
        mtol = kcomp.TOL - 0.1

        lnormal = DraftVecUtils.scaleTo(nnormal, length)
        neg_lnormal = DraftVecUtils.neg(lnormal)

        # motor shape
        v1 = FreeCAD.Vector(self.width / 2. - chmf, self.width / 2., 0)
        v2 = FreeCAD.Vector(self.width / 2., self.width / 2. - chmf, 0)
        motorwire = fcfun.wire_sim_xy([v1, v2])
        # motor wire normal is VZ
        # DraftVecUtils doesnt work as well
        # rot = DraftVecUtils.getRotation(VZ, nnormal)
        # the order matter VZ, nnormal. It seems it doent matter VZ or VZN
        # this is valid:
        #rot = DraftGeomUtils.getRotation(VZ,nnormal)
        #print rot
        rot = FreeCAD.Rotation(VZ, nnormal)
        print rot
        motorwire.Placement.Rotation = rot
        motorwire.Placement.Base = pos
        motorface = Part.Face(motorwire)
        shp_motorbox = motorface.extrude(neg_lnormal)
        # shaft shape
        if rshaft_l == 0:  # no rear shaft
            shp_shaft = fcfun.shp_cyl(r=kcomp.NEMA_SHAFT_D[size] / 2.,
                                      h=shaft_l,
                                      normal=nnormal,
                                      pos=pos)
        else:
            rshaft_posend = DraftVecUtils.scaleTo(neg_lnormal,
                                                  rshaft_l + length)
            shp_shaft = fcfun.shp_cyl(r=kcomp.NEMA_SHAFT_D[size] / 2.,
                                      h=shaft_l + rshaft_l + length,
                                      normal=nnormal,
                                      pos=pos + rshaft_posend)

        shp_motorshaft = shp_motorbox.fuse(shp_shaft)
        # Bolt holes
        # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
        # There is something wrong with the position of these bolts
        #        bhole00_pos = FreeCAD.Vector(-kcomp.NEMA_BOLT_SEP[size]/2,
        #                                     -kcomp.NEMA_BOLT_SEP[size]/2,
        #                                     -bolt_depth) + pos
        #        bhole01_pos = FreeCAD.Vector(-kcomp.NEMA_BOLT_SEP[size]/2,
        #                                      kcomp.NEMA_BOLT_SEP[size]/2,
        #                                     -bolt_depth) + pos
        #        bhole10_pos = FreeCAD.Vector( kcomp.NEMA_BOLT_SEP[size]/2,
        #                                     -kcomp.NEMA_BOLT_SEP[size]/2,
        #                                     -bolt_depth) + pos
        #        bhole11_pos = FreeCAD.Vector( kcomp.NEMA_BOLT_SEP[size]/2,
        #                                      kcomp.NEMA_BOLT_SEP[size]/2,
        #                                     -bolt_depth) + pos
        #        bhole00_posrot = DraftVecUtils.rotate(bhole00_pos, rot.Angle, rot.Axis)
        #        bhole01_posrot = DraftVecUtils.rotate(bhole01_pos, rot.Angle, rot.Axis)
        #        bhole10_posrot = DraftVecUtils.rotate(bhole10_pos, rot.Angle, rot.Axis)
        #        bhole11_posrot = DraftVecUtils.rotate(bhole11_pos, rot.Angle, rot.Axis)
        #        shp_bolt00 = fcfun.shp_cyl (
        #                                   r=kcomp.NEMA_BOLT_D[size]/2.+kcomp.TOL/2.,
        #                                   h=bolt_depth + shaft_l,
        #                                   normal = nnormal,
        #                                   pos= bhole00_posrot)
        #        shp_bolt01 = fcfun.shp_cyl (
        #                                   r=kcomp.NEMA_BOLT_D[size]/2.+kcomp.TOL/2.,
        #                                   h=bolt_depth + shaft_l,
        #                                   normal = nnormal,
        #                                   pos= bhole01_posrot)
        #        shp_bolt10 = fcfun.shp_cyl (
        #                                   r=kcomp.NEMA_BOLT_D[size]/2.+kcomp.TOL/2.,
        #                                   h=bolt_depth + shaft_l,
        #                                   normal = nnormal,
        #                                   pos= bhole10_posrot)
        #        shp_bolt11 = fcfun.shp_cyl (
        #                                   r=kcomp.NEMA_BOLT_D[size]/2.+kcomp.TOL/2.,
        #                                   h=bolt_depth + shaft_l,
        #                                   normal = nnormal,
        #                                   pos= bhole11_posrot)
        #        shp_bolts = shp_bolt00.multiFuse([shp_bolt01, shp_bolt10, shp_bolt11])

        # list of shapes to make a fusion of the container
        shp_contfuselist = []
        #        shp_contfuselist.append(shp_bolts)

        b2hole00_pos = FreeCAD.Vector(-kcomp.NEMA_BOLT_SEP[size] / 2,
                                      -kcomp.NEMA_BOLT_SEP[size] / 2,
                                      -bolt_depth)
        b2hole01_pos = FreeCAD.Vector(-kcomp.NEMA_BOLT_SEP[size] / 2,
                                      kcomp.NEMA_BOLT_SEP[size] / 2,
                                      -bolt_depth)
        b2hole10_pos = FreeCAD.Vector(kcomp.NEMA_BOLT_SEP[size] / 2,
                                      -kcomp.NEMA_BOLT_SEP[size] / 2,
                                      -bolt_depth)
        b2hole11_pos = FreeCAD.Vector(kcomp.NEMA_BOLT_SEP[size] / 2,
                                      kcomp.NEMA_BOLT_SEP[size] / 2,
                                      -bolt_depth)

        b2hole00 = addBolt(r_shank=nemabolt_d / 2. + mtol / 2.,
                           l_bolt=bolt_out + bolt_depth,
                           r_head=kcomp.D912_HEAD_D[nemabolt_d] / 2. +
                           mtol / 2.,
                           l_head=kcomp.D912_HEAD_L[nemabolt_d] + mtol,
                           hex_head=0,
                           extra=1,
                           support=1,
                           headdown=0,
                           name="b2hole00")

        b2hole01 = Draft.clone(b2hole00)
        b2hole01.Label = "b2hole01"
        b2hole10 = Draft.clone(b2hole00)
        b2hole10.Label = "b2hole10"
        b2hole11 = Draft.clone(b2hole00)
        b2hole11.Label = "b2hole11"

        b2hole00.ViewObject.Visibility = False
        b2hole01.ViewObject.Visibility = False
        b2hole10.ViewObject.Visibility = False
        b2hole11.ViewObject.Visibility = False

        b2hole00.Placement.Base = b2hole00_pos
        b2hole01.Placement.Base = b2hole01_pos
        b2hole10.Placement.Base = b2hole10_pos
        b2hole11.Placement.Base = b2hole11_pos

        # it doesnt work if dont recompute here! probably the clones
        doc.recompute()

        b2holes_list = [b2hole00, b2hole01, b2hole10, b2hole11]
        # not an efficient way, either use shapes or fco, but not both
        shp_b2holes = b2hole00.Shape.multiFuse(
            [b2hole01.Shape, b2hole10.Shape, b2hole11.Shape])
        #Part.show(shp_b2holes)

        b2holes = doc.addObject("Part::MultiFuse", "b2holes")
        b2holes.Shapes = b2holes_list
        b2holes.ViewObject.Visibility = False

        shp_b2holes.Placement.Base = pos
        shp_b2holes.Placement.Rotation = rot
        shp_contfuselist.append(shp_b2holes)

        # Circle on the base of the shaft
        if circle_r == 0:
            calcircle_r = kcomp.NEMA_BOLT_SEP[size] / 2.
        else:
            calcircle_r = circle_r
        if circle_h != 0:
            shp_circle = fcfun.shp_cyl(
                r=calcircle_r,
                h=circle_h + 1,  #supperposition for union
                normal=nnormal,
                #supperposition for union
                pos=pos - nnormal)
            # fmotor: fused motor
            shp_fmotor = shp_motorshaft.fuse(shp_circle)
        else:
            shp_fmotor = shp_motorshaft

        #fmotor = doc.addObject("Part::Feature", "fmotor")
        #fmotor.Shape = shp_fmotor

        #shp_motor = shp_fmotor.cut(shp_bolts)
        shp_motor = shp_fmotor.cut(shp_b2holes)
        #Part.show(shp_bolts)

        # container
        if container == 1:
            # 2*TOL to make sure it fits
            v1 = FreeCAD.Vector(self.width / 2. - chmf / 2. + 2 * kcomp.TOL,
                                self.width / 2. + 2 * kcomp.TOL, 0)
            v2 = FreeCAD.Vector(self.width / 2. + 2 * kcomp.TOL,
                                self.width / 2. - chmf / 2. + 2 * kcomp.TOL, 0)
            cont_motorwire = fcfun.wire_sim_xy([v1, v2])
            cont_motorwire.Placement.Rotation = rot
            cont_motorwire.Placement.Base = pos
            cont_motorface = Part.Face(cont_motorwire)
            shp_contmotor_box = cont_motorface.extrude(neg_lnormal)

            # the container is much wider than the shaft

            if rshaft_l == 0:  # no rear shaft
                shp_contshaft = fcfun.shp_cyl(r=calcircle_r + kcomp.TOL,
                                              h=shaft_l + 1,
                                              normal=nnormal,
                                              pos=pos - nnormal)
            else:
                shp_contshaft = fcfun.shp_cyl(r=calcircle_r + kcomp.TOL,
                                              h=shaft_l + rshaft_l + length,
                                              normal=nnormal,
                                              pos=pos + rshaft_posend)
            shp_contfuselist.append(shp_contshaft)
            shp_contmotor = shp_contmotor_box.multiFuse(shp_contfuselist)
        else:
            shp_contmotor = shp_motor  # we put the same shape

        doc.recompute()

        #fco_motor = doc.addObject("Part::Cut", name)
        #fco_motor.Base = fmotor
        #fco_motor.Tool = b2holes
        fco_motor = doc.addObject("Part::Feature", name)
        fco_motor.Shape = shp_motor

        self.fco = fco_motor
        self.shp_cont = shp_contmotor
        #Part.show(shp_contmotor)

        doc.recompute()
Beispiel #38
0
    def makeStraightStairs(self, obj, edge, numberofsteps=None):

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

        # Upgrade obj if it is from an older version of FreeCAD
        if not (hasattr(obj, "StringerOverlap")):
            obj.addProperty(
                "App::PropertyLength", "StringerOverlap", "Structure",
                QT_TRANSLATE_NOOP(
                    "App::Property",
                    "The overlap of the stringers above the bottom of the treads"
                ))

        # 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) +
                        obj.StringerOverlap.Value))
                p1 = vBase.add(l1).add(h1)
                p1 = self.align(p1, obj.Align, vWidth)
                if obj.StringerOverlap.Value <= float(h) / numberofsteps:
                    lProfile.append(p1)
                else:
                    p1b = vBase.add(l1).add(Vector(0, 0, float(h)))
                    p1a = p1b.add(
                        Vector(vLength).multiply(
                            (p1b.z - p1.z) / vHeight.Length))
                    lProfile.append(p1a)
                    lProfile.append(p1b)
                h2 = (obj.StructureThickness.Value / vLength.Length) * hyp
                lProfile.append(p1.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)
Beispiel #39
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 #40
0
    def makeStraightLanding(self,obj,edge,numberofsteps=None, callByMakeStraightStairsWithLanding=False):	# what is use of numberofsteps ?
        "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

        # if not call by makeStraightStairsWithLanding() - not 're-base' in function there, then 're-base' here
        if not callByMakeStraightStairsWithLanding:
            vBase = self.vbaseFollowLastSement(obj, vBase)
            obj.AbsTop = vBase

        vNose = DraftVecUtils.scaleTo(vLength,-abs(obj.Nosing.Value))
        h = 0

        if obj.RiserHeightEnforce != 0:
            h = obj.RiserHeightEnforce * numberofsteps
        elif obj.Base: # TODO - should this happen? - though in original code
            if obj.Base.isDerivedFrom("Part::Feature"):
                #l = obj.Base.Shape.Length
                #if obj.Base.Shape.BoundBox.ZLength:
                if round(obj.Base.Shape.BoundBox.ZLength,Draft.precision()) != 0: # ? - need precision
                    h = obj.Base.Shape.BoundBox.ZLength #.Value?
                else:
                    print ("obj.Base has 0 z-value")
                    print (h)
        if h==0 and obj.Height.Value != 0:
            h = obj.Height.Value
        else:
            print (h)

        if obj.TreadDepthEnforce != 0:
                l = obj.TreadDepthEnforce.Value * (numberofsteps-2)
                if obj.LandingDepth:
                    l += obj.LandingDepth.Value
                else:
                    l += obj.Width.Value
        elif obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                l = obj.Base.Shape.Length #.Value?
        elif obj.Length.Value != 0:
            l = obj.Length.Value

        if obj.LandingDepth:
            fLength = float(l-obj.LandingDepth.Value)/(numberofsteps-2)
        else:
            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)
        p1o = p1.add(Vector(0,0,-abs(obj.TreadThickness.Value)))

        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)

        p4o = p3.add(DraftVecUtils.neg(vLength))
        if not callByMakeStraightStairsWithLanding:
            p2o = p2
            p3o = p3

        if callByMakeStraightStairsWithLanding:
            if obj.Flight == "HalfTurnLeft":
                p1 = p1.add(-vWidth)
                p2 = p2.add(-vWidth)
            elif obj.Flight == "HalfTurnRight":
                p3 = p3.add(vWidth)
                p4 = p4.add(vWidth)

        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:
            if obj.Flight == "Straight":
                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:
            if obj.Flight == "Straight":
                p5 = p6.add(DraftVecUtils.scaleTo(vLength,reslength))
            else:
                p5 = None
        resheight = obj.StructureThickness.Value + obj.TreadThickness.Value
        reslength = resheight/math.tan(a)
        if obj.Flight == "Straight":
            p4 = p5.add(DraftVecUtils.scaleTo(vLength,-reslength)).add(Vector(0,0,-resheight))
        else:
            p4 = p6.add(Vector(0,0,-obj.StructureThickness.Value))
        if obj.Structure == "Massive":
            if obj.StructureThickness.Value:
                if p7:
                    struct = Part.Face(Part.makePolygon([p1,p2,p3,p4,p5,p7,p6,p1]))
                elif p5:
                    struct = Part.Face(Part.makePolygon([p1,p2,p3,p4,p5,p6,p1]))
                else:
                    struct = Part.Face(Part.makePolygon([p1,p2,p3,p4,p6,p1]))
                evec = vWidth
                mvec = FreeCAD.Vector(0.0,0)
                if obj.StructureOffset.Value:
                    mvec = DraftVecUtils.scaleTo(vWidth,obj.StructureOffset.Value)
                    struct.translate(mvec)
                if obj.Flight in ["HalfTurnLeft","HalfTurnRight"]:
                    evec = DraftVecUtils.scaleTo(evec,2*evec.Length-2*mvec.Length)
                else:
                    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])

        # Overwriting result of above functions if case fit - should better avoid running the above in first place (better rewrite later)
        if not callByMakeStraightStairsWithLanding:
            if obj.StructureThickness.Value:
                struct = None
                landingFace = Part.Face(Part.makePolygon([p1o,p2o,p3o,p4o,p1o]))
                struct = landingFace.extrude(Vector(0,0,-abs(obj.StructureThickness.Value)))

        if struct:
            self.structures.append(struct)
Beispiel #41
0
    def returnOutlines(self, obj, edges, align="left", offsetH=0, offsetV=0):	# better omit 'obj' latter - 'currently' only for vbaseFollowLastSement()?

        import DraftGeomUtils

        v, vLength, vWidth, vBase = [], [], [], []
        p1o, p2o, p1, p2, p3, p4 = [], [], [], [], [], []
        outline, outlineP1P2, outlineP3P4 = [], [], []

        enum_edges = enumerate(edges)
        for i, edge in enum_edges:
            v.append(DraftGeomUtils.vec(edge))
            vLength.append(Vector(v[i].x,v[i].y,0))
            # TODO obj.Width[i].Value for different 'edges' / 'sections' of the landing

            netWidth = obj.Width.Value - 2*offsetH
            vWidth.append(DraftVecUtils.scaleTo(vLength[i].cross(Vector(0,0,1)),netWidth))

            vBase.append(edges[i].Vertexes[0].Point)
            vBase[i] = self.vbaseFollowLastSement(obj, vBase[i])

            if offsetV != 0:  # redundant?
                vBase[i] = vBase[i].add(Vector(0,0,offsetV))
            if offsetH != 0:  # redundant?
                vOffsetH = DraftVecUtils.scaleTo(vLength[i].cross(Vector(0,0,1)),offsetH)
                vBase[i] = self.align(vBase[i], "Right", -vOffsetH)

            # step + structure							# assume all left-align first # no nosing
            p1o.append(vBase[i].add(Vector(0,0,-abs(obj.TreadThickness.Value))))
            p2o.append(p1o[i].add(vLength[i]))
            p1.append(self.align(vBase[i],obj.Align,vWidth[i]).add(Vector(0,0,-abs(obj.TreadThickness.Value))))
            p2.append(p1[i].add(vLength[i]))
            p3.append(p2[i].add(vWidth[i]))
            p4.append(p3[i].add(DraftVecUtils.neg(vLength[i])))

            #if obj.Align == 'Left':
            if False:
                outlineP1P2.append(p1[i])
                outlineP1P2.append(p2[i])					# can better skip 1 'supposedly' overlapping point every pair?
                if i > 0:
                    print ("Debug - intersection calculation")
                    print (p3[i-1])
                    print (p4[i-1])
                    print (p3[i])
                    print (p4[i])
                    intersection = DraftGeomUtils.findIntersection(p3[i-1],p4[i-1],p3[i],p4[i],True,True)
                    print (intersection)
                    outlineP3P4.insert(0, intersection[0])
                else:
                    outlineP3P4.insert(0, p4[i])

            #elif obj.Align == 'Right':
            if False:

                if i > 0:
                    intersection = DraftGeomUtils.findIntersection(p1[i-1],p2[i-1],p1[i],p2[i],True,True)
                    outlineP1P2.append(intersection[0])
                else:
                    outlineP1P2.append(p1[i])
                outlineP3P4.insert(0, p4[i])
                outlineP3P4.insert(0, p3[i])

            #elif obj.Align == 'Center':
            if True:

                if i > 0:
                    intersection = DraftGeomUtils.findIntersection(p1[i-1],p2[i-1],p1[i],p2[i],True,True)
                    outlineP1P2.append(intersection[0])
                    intersection = DraftGeomUtils.findIntersection(p3[i-1],p4[i-1],p3[i],p4[i],True,True)
                    outlineP3P4.insert(0, intersection[0])
                else:
                    outlineP1P2.append(p1[i])
                    outlineP3P4.insert(0, p4[i])

            else:
                outlineP1P2.append(p1[i])
                outlineP1P2.append(p2[i])
                outlineP3P4.insert(0, p4[i])
                outlineP3P4.insert(0, p3[i])

        # add back last/first 'missing' point(s)
        outlineP3P4.insert(0, p3[i])
        outlineP1P2.append(p2[i])

        outline = outlineP1P2 + outlineP3P4
        outline.append(p1[0])
        print (outlineP1P2)
        print (outlineP3P4)
        print (outline)

        return outline, outlineP1P2, outlineP3P4, vBase