def makeFlatFace(mobile=[], fixed=[], vert=False):

    import Part
    import DraftVecUtils
    import DraftGeomUtils
    if not fixed:
        pol = Part.makePolygon(mobile + [mobile[0]])
        pol = DraftGeomUtils.flattenWire(pol)
        return Part.Face(pol)
    elif len(fixed) == 3:
        tempf = Part.Face(Part.makePolygon(fixed + [fixed[0]]))
        v4 = mobile[0].add(
            DraftVecUtils.project(tempf.CenterOfMass.sub(mobile[0]),
                                  tempf.normalAt(0, 0)))
        pol = Part.makePolygon([fixed[0], fixed[1], v4, fixed[2], fixed[0]])
        pol = DraftGeomUtils.flattenWire(pol)
        return Part.Face(pol)
    elif len(fixed) == 2:
        tp = DraftGeomUtils.findMidpoint(
            Part.LineSegment(mobile[0], mobile[1]).toShape())
        tempf = Part.Face(Part.makePolygon(fixed + [tp, fixed[0]]))
        v4 = mobile[0].add(
            DraftVecUtils.project(tempf.CenterOfMass.sub(mobile[0]),
                                  tempf.normalAt(0, 0)))
        v5 = mobile[1].add(
            DraftVecUtils.project(tempf.CenterOfMass.sub(mobile[1]),
                                  tempf.normalAt(0, 0)))
        if vert:
            pol = Part.makePolygon([fixed[0], v4, v5, fixed[1], fixed[0]])
        else:
            pol = Part.makePolygon(fixed + [v4, v5, fixed[0]])
        pol = DraftGeomUtils.flattenWire(pol)
        return Part.Face(pol)
示例#2
0
def export(exportList, filename):
    "called when freecad exports a file"
    faces = []
    edges = []

    # getting faces and edges
    for ob in exportList:
        if ob.Shape.Faces:
            for f in ob.Shape.Faces:
                faces.append(f)
        else:
            for e in ob.Shape.Edges:
                edges.append(e)
    if not (edges or faces):
        print "oca: found no data to export"
        return

    # writing file
    oca = pythonopen(filename, 'wb')
    oca.write("#oca file generated from FreeCAD\r\n")
    oca.write("# edges\r\n")
    count = 1
    for e in edges:
        if DraftGeomUtils.geomType(e) == "Line":
            oca.write("L" + str(count) + "=")
            oca.write(writepoint(e.Vertexes[0].Point))
            oca.write(" ")
            oca.write(writepoint(e.Vertexes[-1].Point))
            oca.write("\r\n")
        elif DraftGeomUtils.geomType(e) == "Circle":
            if (len(e.Vertexes) > 1):
                oca.write("C" + str(count) + "=ARC ")
                oca.write(writepoint(e.Vertexes[0].Point))
                oca.write(" ")
                oca.write(writepoint(DraftGeomUtils.findMidpoint(e)))
                oca.write(" ")
                oca.write(writepoint(e.Vertexes[-1].Point))
            else:
                oca.write("C" + str(count) + "= ")
                oca.write(writepoint(e.Curve.Center))
                oca.write(" ")
                oca.write(str(e.Curve.Radius))
            oca.write("\r\n")
        count += 1
    oca.write("# faces\r\n")
    for f in faces:
        oca.write("A" + str(count) + "=S(POL")
        for v in f.Vertexes:
            oca.write(" ")
            oca.write(writepoint(v.Point))
        oca.write(" ")
        oca.write(writepoint(f.Vertexes[0].Point))
        oca.write(")\r\n")
        count += 1

    # closing
    oca.close()
    FreeCAD.Console.PrintMessage("successfully exported " + filename)
示例#3
0
def export(exportList, filename):
    "called when freecad exports a file"
    faces = []
    edges = []

    # getting faces and edges
    for ob in exportList:
        if ob.Shape.Faces:
            for f in ob.Shape.Faces:
                faces.append(f)
        else:
            for e in ob.Shape.Edges:
                edges.append(e)
    if not (edges or faces):
        print "oca: found no data to export"
        return

    # writing file
    oca = pythonopen(filename, "wb")
    oca.write("#oca file generated from FreeCAD\r\n")
    oca.write("# edges\r\n")
    count = 1
    for e in edges:
        if isinstance(e.Curve, Part.Line):
            oca.write("L" + str(count) + "=")
            oca.write(writepoint(e.Vertexes[0].Point))
            oca.write(" ")
            oca.write(writepoint(e.Vertexes[-1].Point))
            oca.write("\r\n")
        elif isinstance(e.Curve, Part.Circle):
            if len(e.Vertexes) > 1:
                oca.write("C" + str(count) + "=ARC ")
                oca.write(writepoint(e.Vertexes[0].Point))
                oca.write(" ")
                oca.write(writepoint(DraftGeomUtils.findMidpoint(e)))
                oca.write(" ")
                oca.write(writepoint(e.Vertexes[-1].Point))
            else:
                oca.write("C" + str(count) + "= ")
                oca.write(writepoint(e.Curve.Center))
                oca.write(" ")
                oca.write(str(e.Curve.Radius))
            oca.write("\r\n")
        count += 1
    oca.write("# faces\r\n")
    for f in faces:
        oca.write("A" + str(count) + "=S(POL")
        for v in f.Vertexes:
            oca.write(" ")
            oca.write(writepoint(v.Point))
        oca.write(" ")
        oca.write(writepoint(f.Vertexes[0].Point))
        oca.write(")\r\n")
        count += 1

    # closing
    oca.close()
    FreeCAD.Console.PrintMessage("successfully exported " + filename)
示例#4
0
 def snapToMidpoint(self,shape):
     "returns a list of midpoints snap locations"
     snaps = []
     if self.isEnabled("midpoint"):
         if isinstance(shape,Part.Edge):
             mp = DraftGeomUtils.findMidpoint(shape)
             if mp:
                 snaps.append([mp,'midpoint',mp])
     return snaps
示例#5
0
 def snapToMidpoint(self, shape):
     "returns a list of midpoints snap locations"
     snaps = []
     if self.isEnabled("midpoint"):
         if isinstance(shape, Part.Edge):
             mp = DraftGeomUtils.findMidpoint(shape)
             if mp:
                 snaps.append([mp, 'midpoint', mp])
     return snaps
示例#6
0
    def execute(self, obj):

        if self.clone(obj):
            return

        import Part, math, DraftGeomUtils
        pl = obj.Placement
        #self.baseface = None

        base = None
        w = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.Solids:
                    base = obj.Base.Shape
                    #pl = obj.Base.Placement
                else:
                    if (obj.Base.Shape.Faces and obj.Face):
                        w = obj.Base.Shape.Faces[obj.Face - 1].Wires[0]
                    elif obj.Base.Shape.Wires:
                        w = obj.Base.Shape.Wires[0]
        if w:
            if w.isClosed():
                self.profilsDico = []
                self.shps = []
                self.subVolshps = []
                heights = []
                edges = Part.__sortEdges__(w.Edges)
                l = len(edges)
                for i in range(l):
                    self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i],
                                            obj.IdRel[i], obj.Overhang[i],
                                            obj.Thickness[i])
                for i in range(l):
                    self.calcMissingData(i)
                for i in range(l):
                    self.calcEdgeGeometry(edges, i)
                for i in range(l):
                    self.calcDraftEdges(i)
                for i in range(l):
                    self.calcEave(i)
                for p in self.profilsDico:
                    heights.append(p["height"])
                obj.Heights = heights
                for i in range(l):
                    self.getRoofPaneProject(i)
                    profilCurrent = self.findProfil(i)
                    midpoint = DraftGeomUtils.findMidpoint(
                        profilCurrent["edge"])
                    ptsPaneProject = profilCurrent["points"]
                    lp = len(ptsPaneProject)
                    if lp != 0:
                        ptsPaneProject.append(ptsPaneProject[0])
                        edgesWire = []
                        for p in range(lp):
                            edge = Part.makeLine(ptsPaneProject[p],
                                                 ptsPaneProject[p + 1])
                            edgesWire.append(edge)
                        wire = Part.Wire(edgesWire)
                        d = wire.BoundBox.DiagonalLength
                        thicknessV = profilCurrent["thickness"] / (math.cos(
                            math.radians(profilCurrent["angle"])))
                        overhangV = profilCurrent["overhang"] * math.tan(
                            math.radians(profilCurrent["angle"]))
                        if wire.isClosed():
                            f = Part.Face(wire)
                            f = f.extrude(
                                FreeCAD.Vector(
                                    0, 0, profilCurrent["height"] + 1000000.0))
                            f.translate(
                                FreeCAD.Vector(0.0, 0.0, -2 * overhangV))
                        ptsPaneProfil = [
                            FreeCAD.Vector(-profilCurrent["overhang"],
                                           -overhangV, 0.0),
                            FreeCAD.Vector(profilCurrent["run"],
                                           profilCurrent["height"], 0.0),
                            FreeCAD.Vector(
                                profilCurrent["run"],
                                profilCurrent["height"] + thicknessV, 0.0),
                            FreeCAD.Vector(-profilCurrent["overhang"],
                                           -overhangV + thicknessV, 0.0)
                        ]
                        self.shps.append(
                            self.createProfilShape(ptsPaneProfil, midpoint,
                                                   profilCurrent["rot"],
                                                   profilCurrent["vec"],
                                                   profilCurrent["run"], d, f))
                        ## subVolume shape
                        ptsSubVolumeProfil = [
                            FreeCAD.Vector(-profilCurrent["overhang"],
                                           -overhangV, 0.0),
                            FreeCAD.Vector(profilCurrent["run"],
                                           profilCurrent["height"], 0.0),
                            FreeCAD.Vector(profilCurrent["run"],
                                           profilCurrent["height"] + 900000.0,
                                           0.0),
                            FreeCAD.Vector(-profilCurrent["overhang"],
                                           profilCurrent["height"] + 900000.0,
                                           0.0)
                        ]
                        self.subVolshps.append(
                            self.createProfilShape(ptsSubVolumeProfil,
                                                   midpoint,
                                                   profilCurrent["rot"],
                                                   profilCurrent["vec"],
                                                   profilCurrent["run"], d, f))
                ## SubVolume
                self.sub = self.subVolshps.pop()
                for s in self.subVolshps:
                    self.sub = self.sub.fuse(s)
                self.sub = self.sub.removeSplitter()
                if not self.sub.isNull():
                    if not DraftGeomUtils.isNull(pl):
                        self.sub.Placement = pl
                ## BaseVolume
                base = Part.makeCompound(self.shps)
                base = self.processSubShapes(obj, base)
                self.applyShape(obj, base, pl)
        elif base:
            base = self.processSubShapes(obj, base)
            self.applyShape(obj, base, pl)
        else:
            FreeCAD.Console.PrintMessage(
                translate("Arch", "Unable to create a roof"))
示例#7
0
    def execute(self, obj):

        if self.clone(obj):
            return

        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return

        pl = obj.Placement
        if obj.Base.Shape.Solids:
            obj.Shape = obj.Base.Shape.copy()
            if not pl.isNull():
                obj.Placement = obj.Shape.Placement.multiply(pl)
        else:
            if not obj.Profile:
                return
            if not obj.Profile.isDerivedFrom("Part::Part2DObject"):
                return
            if not obj.Profile.Shape:
                return
            if not obj.Profile.Shape.Wires:
                return
            if not obj.Profile.Shape.Faces:
                for w in obj.Profile.Shape.Wires:
                    if not w.isClosed():
                        return
            import DraftGeomUtils, Part, math
            baseprofile = obj.Profile.Shape.copy()
            if not baseprofile.Faces:
                f = []
                for w in baseprofile.Wires:
                    f.append(Part.Face(w))
                if len(f) == 1:
                    baseprofile = f[0]
                else:
                    baseprofile = Part.makeCompound(f)
            shapes = []
            normal = DraftGeomUtils.getNormal(obj.Base.Shape)
            #for wire in obj.Base.Shape.Wires:
            for e in obj.Base.Shape.Edges:
                #e = wire.Edges[0]
                bvec = DraftGeomUtils.vec(e)
                bpoint = e.Vertexes[0].Point
                profile = baseprofile.copy()
                #basepoint = profile.Placement.Base
                if hasattr(obj, "BasePoint"):
                    edges = DraftGeomUtils.sortEdges(profile.Edges)
                    basepointliste = [profile.CenterOfMass]
                    for edge in edges:
                        basepointliste.append(
                            DraftGeomUtils.findMidpoint(edge))
                        basepointliste.append(edge.Vertexes[-1].Point)
                    try:
                        basepoint = basepointliste[obj.BasePoint]
                    except IndexError:
                        FreeCAD.Console.PrintMessage(
                            translate(
                                "Arch",
                                "Crossing point not found in profile.\n"))
                        basepoint = basepointliste[0]
                else:
                    basepoint = profile.CenterOfMass
                profile.translate(bpoint.sub(basepoint))
                if obj.Align:
                    axis = profile.Placement.Rotation.multVec(
                        FreeCAD.Vector(0, 0, 1))
                    angle = bvec.getAngle(axis)
                    if round(angle, Draft.precision()) != 0:
                        if round(angle, Draft.precision()) != round(
                                math.pi, Draft.precision()):
                            rotaxis = axis.cross(bvec)
                            profile.rotate(DraftVecUtils.tup(bpoint),
                                           DraftVecUtils.tup(rotaxis),
                                           math.degrees(angle))
                if obj.Rotation:
                    profile.rotate(
                        DraftVecUtils.tup(bpoint),
                        DraftVecUtils.tup(FreeCAD.Vector(bvec).normalize()),
                        obj.Rotation)
                #profile = wire.makePipeShell([profile],True,False,2) TODO buggy
                profile = profile.extrude(bvec)
                if obj.Offset:
                    if not DraftVecUtils.isNull(obj.Offset):
                        profile.translate(obj.Offset)
                shapes.append(profile)
            if shapes:
                obj.Shape = Part.makeCompound(shapes)
                obj.Placement = pl
示例#8
0
    def execute(self,obj):
        
        if self.clone(obj):
            return
        
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return

        pl = obj.Placement
        if obj.Base.Shape.Solids:
            obj.Shape = obj.Base.Shape.copy()
            if not pl.isNull():
                obj.Placement = obj.Shape.Placement.multiply(pl)
        else:
            if not obj.Profile:
                return
            if not obj.Profile.isDerivedFrom("Part::Part2DObject"):
                return
            if not obj.Profile.Shape:
                return
            if not obj.Profile.Shape.Wires:
                return
            if not obj.Profile.Shape.Faces:
                for w in obj.Profile.Shape.Wires:
                    if not w.isClosed():
                        return
            import DraftGeomUtils, Part, math
            baseprofile = obj.Profile.Shape.copy()
            if hasattr(obj,"ProfilePlacement"):
                if not obj.ProfilePlacement.isNull():
                    baseprofile.Placement = obj.ProfilePlacement.multiply(baseprofile.Placement)
            if not baseprofile.Faces:
                f = []
                for w in baseprofile.Wires:
                    f.append(Part.Face(w))
                if len(f) == 1:
                    baseprofile = f[0]
                else:
                    baseprofile = Part.makeCompound(f)
            shapes = []
            normal = DraftGeomUtils.getNormal(obj.Base.Shape)
            #for wire in obj.Base.Shape.Wires:
            edges = obj.Base.Shape.Edges
            if hasattr(obj,"Edges"):
                if obj.Edges == "Vertical edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,1,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                elif obj.Edges == "Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                elif obj.Edges == "Top Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                    edges = sorted(edges,key=lambda x: x.CenterOfMass.z,reverse=True)
                    z = edges[0].CenterOfMass.z
                    edges = [e for e in edges if abs(e.CenterOfMass.z-z) < 0.00001]
                elif obj.Edges == "Bottom Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                    edges = sorted(edges,key=lambda x: x.CenterOfMass.z)
                    z = edges[0].CenterOfMass.z
                    edges = [e for e in edges if abs(e.CenterOfMass.z-z) < 0.00001]
            for e in edges:
                #e = wire.Edges[0]
                bvec = DraftGeomUtils.vec(e)
                bpoint = e.Vertexes[0].Point
                profile = baseprofile.copy()
                #basepoint = profile.Placement.Base
                if hasattr(obj,"BasePoint"):
                    edges = Part.__sortEdges__(profile.Edges)
                    basepointliste = [profile.CenterOfMass]
                    for edge in edges:
                        basepointliste.append(DraftGeomUtils.findMidpoint(edge))
                        basepointliste.append(edge.Vertexes[-1].Point)
                    try:
                        basepoint = basepointliste[obj.BasePoint]
                    except IndexError:
                        FreeCAD.Console.PrintMessage(translate("Arch","Crossing point not found in profile.\n"))
                        basepoint = basepointliste[0]
                else :
                    basepoint = profile.CenterOfMass
                profile.translate(bpoint.sub(basepoint))
                if obj.Align:
                    axis = profile.Placement.Rotation.multVec(FreeCAD.Vector(0,0,1))
                    angle = bvec.getAngle(axis)
                    if round(angle,Draft.precision()) != 0:
                        if round(angle,Draft.precision()) != round(math.pi,Draft.precision()):
                            rotaxis = axis.cross(bvec)
                            profile.rotate(DraftVecUtils.tup(bpoint), DraftVecUtils.tup(rotaxis), math.degrees(angle))
                if obj.Rotation:
                    profile.rotate(DraftVecUtils.tup(bpoint), DraftVecUtils.tup(FreeCAD.Vector(bvec).normalize()), obj.Rotation)
                #profile = wire.makePipeShell([profile],True,False,2) TODO buggy
                profile = profile.extrude(bvec)
                if obj.Offset:
                    if not DraftVecUtils.isNull(obj.Offset):
                        profile.translate(obj.Offset)
                shapes.append(profile)
            if shapes:
                if hasattr(obj,"Fuse"):
                    if obj.Fuse:
                        if len(shapes) > 1:
                            s = shapes[0].multiFuse(shapes[1:])
                            s = s.removeSplitter()
                            obj.Shape = s
                            obj.Placement = pl
                            return
                obj.Shape = Part.makeCompound(shapes)
                obj.Placement = pl
示例#9
0
    def execute(self, obj):

        if self.clone(obj):
            return

        pl = obj.Placement
        #self.baseface = None
        self.flip = False
        if hasattr(obj, "Flip"):
            if obj.Flip:
                self.flip = True
        base = None
        baseWire = None
        if obj.Base:
            if hasattr(obj.Base, "Shape"):
                if obj.Base.Shape.Solids:
                    base = obj.Base.Shape
                    #pl = obj.Base.Placement
                else:
                    if (obj.Base.Shape.Faces and obj.Face):
                        baseWire = obj.Base.Shape.Faces[obj.Face - 1].Wires[0]
                    elif obj.Base.Shape.Wires:
                        baseWire = obj.Base.Shape.Wires[0]
        if baseWire:
            if baseWire.isClosed():
                self.profilsDico = []
                self.shps = []
                self.subVolShps = []
                heights = []
                edges = Part.__sortEdges__(baseWire.Edges)
                if self.flip:
                    edges = self.flipEdges(edges)

                ln = len(edges)

                obj.Angles = adjust_list_len(obj.Angles, ln, obj.Angles[0])
                obj.Runs = adjust_list_len(obj.Runs, ln, obj.Runs[0])
                obj.IdRel = adjust_list_len(obj.IdRel, ln, obj.IdRel[0])
                obj.Thickness = adjust_list_len(obj.Thickness, ln,
                                                obj.Thickness[0])
                obj.Overhang = adjust_list_len(obj.Overhang, ln,
                                               obj.Overhang[0])

                for i in range(ln):
                    self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i],
                                            obj.IdRel[i], obj.Overhang[i],
                                            obj.Thickness[i])
                for i in range(ln):
                    self.calcEdgeGeometry(i, edges[i])
                for i in range(ln):
                    self.calcApex(
                        i, ln)  # after calcEdgeGeometry as it uses vec data
                for i in range(ln):
                    self.calcMissingData(
                        i, ln
                    )  # after calcApex so it can use recalculated heights
                for i in range(ln):
                    self.calcDraftEdges(i)
                for i in range(ln):
                    self.calcEave(i)
                for profil in self.profilsDico:
                    heights.append(profil["height"])
                obj.Heights = heights
                for i in range(ln):
                    self.getRoofPaneProject(i)
                    profilCurr = self.profilsDico[i]
                    ptsPaneProject = profilCurr["points"]
                    if len(ptsPaneProject) == 0:
                        continue
                    face = face_from_points(ptsPaneProject)
                    if face:
                        diag = face.BoundBox.DiagonalLength
                        midpoint = DraftGeomUtils.findMidpoint(
                            profilCurr["edge"])
                        thicknessV = profilCurr["thickness"] / (math.cos(
                            math.radians(profilCurr["angle"])))
                        overhangV = profilCurr["overhang"] * math.tan(
                            math.radians(profilCurr["angle"]))
                        sol = face.extrude(
                            Vector(0.0, 0.0, profilCurr["height"] + 1000000.0))
                        sol.translate(Vector(0.0, 0.0, -2.0 * overhangV))

                        ## baseVolume shape
                        ptsPaneProfil = [
                            Vector(-profilCurr["overhang"], -overhangV, 0.0),
                            Vector(profilCurr["run"], profilCurr["height"],
                                   0.0),
                            Vector(profilCurr["run"],
                                   profilCurr["height"] + thicknessV, 0.0),
                            Vector(-profilCurr["overhang"],
                                   -overhangV + thicknessV, 0.0)
                        ]
                        self.shps.append(
                            self.createProfilShape(ptsPaneProfil, midpoint,
                                                   profilCurr["rot"],
                                                   profilCurr["vec"],
                                                   profilCurr["run"], diag,
                                                   sol))

                        ## subVolume shape
                        ptsSubVolProfil = [
                            Vector(-profilCurr["overhang"], -overhangV, 0.0),
                            Vector(profilCurr["run"], profilCurr["height"],
                                   0.0),
                            Vector(profilCurr["run"],
                                   profilCurr["height"] + 900000.0, 0.0),
                            Vector(-profilCurr["overhang"],
                                   profilCurr["height"] + 900000.0, 0.0)
                        ]
                        self.subVolShps.append(
                            self.createProfilShape(ptsSubVolProfil, midpoint,
                                                   profilCurr["rot"],
                                                   profilCurr["vec"],
                                                   profilCurr["run"], diag,
                                                   sol))

                if len(
                        self.shps
                ) == 0:  # occurs if all segments have angle=90 or run=0.
                    # create a flat roof using the eavePtLst outline:
                    ptsPaneProject = []
                    for i in range(ln):
                        ptsPaneProject.append(
                            self.profilsDico[i]["eavePtLst"][0])
                    face = face_from_points(ptsPaneProject)
                    if face:
                        thk = max(
                            1.0, self.profilsDico[0]["thickness"]
                        )  # FreeCAD will crash when extruding with a null vector here
                        self.shps = [face.extrude(Vector(0.0, 0.0, thk))]
                        self.subVolShps = [
                            face.extrude(Vector(0.0, 0.0, 1000000.0))
                        ]

                ## baseVolume
                base = self.shps.pop()
                for s in self.shps:
                    base = base.fuse(s)
                base = self.processSubShapes(obj, base, pl)
                self.applyShape(obj, base, pl, allownosolid=True)

                ## subVolume
                self.sub = self.subVolShps.pop()
                for s in self.subVolShps:
                    self.sub = self.sub.fuse(s)
                self.sub = self.sub.removeSplitter()
                if not self.sub.isNull():
                    if not DraftGeomUtils.isNull(pl):
                        self.sub.Placement = pl

        elif base:
            base = self.processSubShapes(obj, base, pl)
            self.applyShape(obj, base, pl, allownosolid=True)
        else:
            FreeCAD.Console.PrintMessage(
                translate("Arch", "Unable to create a roof"))
示例#10
0
    def execute(self,obj):
        import Part, math, DraftGeomUtils
        pl = obj.Placement
        self.baseface = None

        base = None
        if obj.Base and obj.Angles:
            w = None
            if obj.Base.isDerivedFrom("Part::Feature"):
                if (obj.Base.Shape.Faces and obj.Face):
                    w = obj.Base.Shape.Faces[obj.Face-1].Wires[0]
                elif obj.Base.Shape.Wires:
                    w = obj.Base.Shape.Wires[0]
            if w:
                if w.isClosed():
                    self.profilsDico = []
                    self.shps = []
                    self.subVolshps = []
                    heights = []
                    edges = DraftGeomUtils.sortEdges(w.Edges)
                    l = len(edges)
                    print("le contour contient "+str(l)+" aretes")
                    for i in range(l):
                        self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i], obj.IdRel[i], obj.Overhang[i], obj.Thickness[i])
                    for i in range(l):
                        self.calcMissingData(i)
                    for p in self.profilsDico:
                        heights.append(p["height"])
                    obj.Heights = heights
                    for i in range(l):
                        edgesForward = edges[:]
                        edgesForward.append(edges[0])
                        ptsPaneProject=[]
                        profil0 =self.profilsDico[i-1]
                        profil1 =self.profilsDico[i]
                        if i == l-1:
                            profil2 =self.profilsDico[0]
                        else:
                            profil2 =self.profilsDico[i+1]
                        vec0 = edges[i-1].Vertexes[-1].Point.sub(edges[i-1].Vertexes[0].Point)
                        vec1 = edges[i].Vertexes[-1].Point.sub(edges[i].Vertexes[0].Point)
                        vec2 = edgesForward[i+1].Vertexes[-1].Point.sub(edgesForward[i+1].Vertexes[0].Point)
                        rotEdge0 = math.degrees(DraftVecUtils.angle(vec0))
                        rotEdge1 = math.degrees(DraftVecUtils.angle(vec1))
                        rotEdge2 = math.degrees(DraftVecUtils.angle(vec2))
                        edgeEave0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["overhang"]).negative())
                        edgeEave1 = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,profil1["overhang"]).negative())
                        edgeEave2 = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,profil2["overhang"]).negative())
                        pt0Eave1 = DraftGeomUtils.findIntersection(edgeEave0,edgeEave1,infinite1=True,infinite2=True,)
                        pt1Eave1 = DraftGeomUtils.findIntersection(edgeEave1,edgeEave2,infinite1=True,infinite2=True,)
                        edgeEave1 = DraftGeomUtils.edg(FreeCAD.Vector(pt0Eave1[0]),FreeCAD.Vector(pt1Eave1[0]))
                        edgeRidge0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["run"]))
                        edgeRidge1 = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,profil1["run"]))
                        edgeRidge2 = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,profil2["run"]))
                        midpoint = DraftGeomUtils.findMidpoint(edges[i])
                        pt0Edge1 = edges[i].Vertexes[0].Point
                        pt1Edge1 = edges[i].Vertexes[-1].Point
                        print("Analyse profil " + str(i))
                        if profil1["angle"] != 90.:
                            if profil2["angle"] == 90. :
                                print("situation a droite : pignon")
                                ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                point = DraftGeomUtils.findIntersection(edgeRidge1,edgeEave2,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                            elif profil1["height"] == profil2["height"] :
                                print("situation a droite : ht1 = ht2")
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                            elif profil1["height"] > profil2["height"]:
                                print("situation a droite : ht1 > ht2")
                                dec = profil2["height"]/math.tan(math.radians(profil1["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge2,edgeRidge2OnPane,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [edgeRidge1.Edges[0],], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
                            elif profil1["height"] < profil2["height"]:
                                print("situation a droite : ht1 < ht2")
                                dec = profil1["height"]/math.tan(math.radians(profil2["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2OnPane,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            if profil0["angle"] == 90. :
                                print("situation a gauche : pignon")
                                point = DraftGeomUtils.findIntersection(edgeRidge1,edgeEave0,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                                ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil0["height"] == profil1["height"]:
                                print("situation a gauche : ht1 = ht0")
                                edgeRidge0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["run"]))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge0,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] > profil0["height"]:
                                print("situation a gauche : ht1 > ht0")
                                dec = profil0["height"]/math.tan(math.radians(profil1["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge0OnPane,edgeRidge0,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt0Edge1)
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [edgeRidge1.Edges[0],], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] < profil0["height"]:
                                print("situation a gauche : ht1 < ht0")
                                dec = profil1["height"]/math.tan(math.radians(profil0["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,dec))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge0OnPane,edgeRidge1,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            ptsPaneProject = DraftVecUtils.removeDoubles(ptsPaneProject)
                            print("ptsPaneProject",ptsPaneProject)
                            print("Fin Analyse profil " + str(i))
                            self.profilsDico[i]["points"] = ptsPaneProject
                            lp = len(ptsPaneProject)
                            ptsPaneProject.append(ptsPaneProject[0])
                            edgesWire = []
                            for i in range(lp):
                                edge = Part.makeLine(ptsPaneProject[i],ptsPaneProject[i+1])
                                edgesWire.append(edge)
                            wire = Part.Wire(edgesWire)
                            d = wire.BoundBox.DiagonalLength
                            thicknessV = profil1["thickness"]/(math.cos(math.radians(profil1["angle"])))
                            overhangV = profil1["overhang"]*math.tan(math.radians(profil1["angle"]))
                            if wire.isClosed():
                                f = Part.Face(wire)
                                f = f.extrude(FreeCAD.Vector(0,0,profil1["height"]+2*thicknessV+2*overhangV))
                                f.translate(FreeCAD.Vector(0.0,0.0,-2*overhangV))
                            ptsPaneProfil=[FreeCAD.Vector(-profil1["overhang"],-overhangV,0.0),FreeCAD.Vector(profil1["run"],profil1["height"],0.0),FreeCAD.Vector(profil1["run"],profil1["height"]+thicknessV,0.0),FreeCAD.Vector(-profil1["overhang"],-overhangV+thicknessV,0.0)]
                            self.createProfilShape (ptsPaneProfil, midpoint, rotEdge1, vec1, profil1["run"], d, self.shps, f)
                            ## subVolume shape
                            ptsSubVolumeProfil=[FreeCAD.Vector(-profil1["overhang"],-overhangV,0.0),FreeCAD.Vector(profil1["run"],profil1["height"],0.0),FreeCAD.Vector(profil1["run"],profil1["height"]+10000,0.0),FreeCAD.Vector(0.0,profil1["height"]+10000,0.0)]
                            self.createProfilShape (ptsSubVolumeProfil, midpoint, rotEdge1, vec1, profil1["run"], d, self.subVolshps, f)
                        else:
                            #TODO PIGNON
                            pass

                    ## SubVolume
                    self.sub = self.subVolshps.pop()
                    for s in self.subVolshps:
                        self.sub = self.sub.fuse(s)
                    self.sub = self.sub.removeSplitter()
                    if not self.sub.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            self.sub.Placement = pl
                    ## BaseVolume
                    base = Part.makeCompound(self.shps)
                    if not base.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            base.Placement = pl
        base = self.processSubShapes(obj,base)
        if base:
            if not base.isNull():
                obj.Shape = base
示例#11
0
def export(exportList, filename):
    """Export the OCA file with a given list of objects.

    The objects must be edges or faces, in order to be processed
    and exported.

    Parameters
    ----------
    exportList : list
        List of document objects to export.
    filename : str
        Path to the new file.

    Returns
    -------
    None
        If `exportList` doesn't have shapes to export.
    """
    faces = []
    edges = []

    # getting faces and edges
    for ob in exportList:
        if ob.Shape.Faces:
            for f in ob.Shape.Faces:
                faces.append(f)
        else:
            for e in ob.Shape.Edges:
                edges.append(e)
    if not (edges or faces):
        FCC.PrintMessage(
            translate("importOCA", "OCA: found no data to export") + "\n")
        return

    # writing file
    oca = pythonopen(filename, 'w')
    oca.write("#oca file generated from FreeCAD\r\n")
    oca.write("# edges\r\n")
    count = 1
    for e in edges:
        if DraftGeomUtils.geomType(e) == "Line":
            oca.write("L" + str(count) + "=")
            oca.write(writepoint(e.Vertexes[0].Point))
            oca.write(" ")
            oca.write(writepoint(e.Vertexes[-1].Point))
            oca.write("\r\n")
        elif DraftGeomUtils.geomType(e) == "Circle":
            if len(e.Vertexes) > 1:
                oca.write("C" + str(count) + "=ARC ")
                oca.write(writepoint(e.Vertexes[0].Point))
                oca.write(" ")
                oca.write(writepoint(DraftGeomUtils.findMidpoint(e)))
                oca.write(" ")
                oca.write(writepoint(e.Vertexes[-1].Point))
            else:
                oca.write("C" + str(count) + "= ")
                oca.write(writepoint(e.Curve.Center))
                oca.write(" ")
                oca.write(str(e.Curve.Radius))
            oca.write("\r\n")
        count += 1
    oca.write("# faces\r\n")
    for f in faces:
        oca.write("A" + str(count) + "=S(POL")
        for v in f.Vertexes:
            oca.write(" ")
            oca.write(writepoint(v.Point))
        oca.write(" ")
        oca.write(writepoint(f.Vertexes[0].Point))
        oca.write(")\r\n")
        count += 1

    # closing
    oca.close()
    FCC.PrintMessage(
        translate("importOCA", "successfully exported") + " " + filename +
        "\n")
def getEdgesAngleSVG(
    edge1: Part.Edge,
    edge2: Part.Edge,
    arc_radius: float,
    view_plane: WorkingPlane.Plane,
    font_family: str,
    font_size: Union[float, str],
    bent_angle_exclude_list: Tuple[float, ...] = (90, 180),
    stroke_width: Union[float, str] = 0.2,
    stroke_color: str = "black",
) -> ElementTree.Element:
    """Returns svg representation for angle between two edges by drawing an arc
    of given radius and adding angle text svg.
    It returns empty svg if edges doesn't intersect when extended infinitely.

    Parameters
    ----------
    edge1: Part.Edge
        The first edge to get its angle dimension svg with edge2.
    edge2:
        The second edge to get its angle dimension svg with edge1.
    arc_radius: float
        The radius of dimension arc.
    view_plane: WorkingPlane.Plane
        The view plane acting as svg plane.
    font_family: str
        The font-family of angle dimension.
    font_size: float or str
        The font-size of angle dimension.
    bent_angle_exclude_list: tuple of float, optional
        If angle between two edges is present in bent_angle_exclude_list,
        then empty svg element will be returned.
        Default is (90, 180)
    stroke_width: float or str, optional
        The stroke-width of arc svg.
        Default is 0.2
    stroke_color: str, optional
        The stroke color of arc svg.
        Default is "black".

    Returns
    -------
    ElementTree.Element
        The generated edges angle dimension svg.
    """
    intersection = DraftGeomUtils.findIntersection(edge1, edge2, True, True)
    if not intersection:
        return ElementTree.Element("g")
    else:
        intersection = intersection[0]

    p1 = max(
        DraftGeomUtils.getVerts(edge1),
        key=lambda x: x.distanceToPoint(intersection),
    )
    p2 = max(
        DraftGeomUtils.getVerts(edge2),
        key=lambda x: x.distanceToPoint(intersection),
    )
    angle = round(
        math.degrees(
            abs(DraftVecUtils.angle(p2.sub(intersection),
                                    p1.sub(intersection)))))
    if angle in bent_angle_exclude_list:
        return ElementTree.Element("g")

    arc_p1 = intersection.add(arc_radius * p2.sub(intersection).normalize())
    arc_p2 = intersection.add(arc_radius * p1.sub(intersection).normalize())
    arc_edge = DraftGeomUtils.arcFrom2Pts(arc_p1, arc_p2, intersection)
    arc_svg = getRoundEdgeSVG(arc_edge, view_plane, stroke_width, stroke_color)

    arc_mid_point = DraftGeomUtils.findMidpoint(arc_edge)

    proj_intersection = getProjectionToSVGPlane(intersection, view_plane)
    proj_mid_point = getProjectionToSVGPlane(arc_mid_point, view_plane)

    if round(proj_intersection.x) < round(proj_mid_point.x):
        text_anchor = "start"
    elif round(proj_intersection.x) > round(proj_mid_point.x):
        text_anchor = "end"
    else:
        text_anchor = "middle"

    if round(proj_intersection.y) < round(proj_mid_point.y):
        text_y = proj_mid_point.y + font_size
    elif round(proj_intersection.y) > round(proj_mid_point.y):
        text_y = proj_mid_point.y
    else:
        text_y = proj_mid_point.y + font_size / 2

    angle_text_svg = getSVGTextElement(
        "{}°".format(angle),
        proj_mid_point.x,
        text_y,
        font_family,
        font_size,
        text_anchor,
    )

    bent_angle_svg = ElementTree.Element("g")
    bent_angle_svg.extend([arc_svg, angle_text_svg])
    return bent_angle_svg
示例#13
0
    def execute(self,obj):
        import Part, math, DraftGeomUtils
        pl = obj.Placement
        self.baseface = None

        base = None
        if obj.Base: 
            if not obj.Angles:
                if obj.Base.isDerivedFrom("Part::Feature"):
                    if obj.Base.Shape.Solids:
                        base = obj.Base.Shape.copy()
            else:
                w = None
                if obj.Base.isDerivedFrom("Part::Feature"):
                    if (obj.Base.Shape.Faces and obj.Face):
                        w = obj.Base.Shape.Faces[obj.Face-1].Wires[0]
                    elif obj.Base.Shape.Wires:
                        w = obj.Base.Shape.Wires[0]
                if w:
                    if w.isClosed():
                        self.profilsDico = []
                        self.shps = []
                        self.subVolshps = []
                        heights = []
                        edges = DraftGeomUtils.sortEdges(w.Edges)
                        l = len(edges)
                        print("le contour contient "+str(l)+" aretes")
                        for i in range(l):
                            self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i], obj.IdRel[i], obj.Overhang[i], obj.Thickness[i])
                        for i in range(l):
                            self.calcMissingData(i)
                        for i in range(l):
                            self.calcEdgeGeometry(edges, i)
                        for i in range(l):
                            self.calcDraftEdges(i)
                        for i in range(l):
                            self.calcEave(i)
                        for p in self.profilsDico:
                            heights.append(p["height"])
                        obj.Heights = heights
                        for i in range(l):
                            self.getRoofPaneProject(i)
                            profilCurrent = self.findProfil(i)
                            midpoint = DraftGeomUtils.findMidpoint(profilCurrent["edge"])
                            ptsPaneProject = profilCurrent["points"]
                            lp = len(ptsPaneProject)
                            if lp != 0:
                                #print FreeCAD.Vector(ptsPaneProject[0])
                                ptsPaneProject.append(ptsPaneProject[0])
                                edgesWire = []
                                for p in range(lp):
                                    edge = Part.makeLine(ptsPaneProject[p],ptsPaneProject[p+1])
                                    edgesWire.append(edge)
                                wire = Part.Wire(edgesWire)
                                d = wire.BoundBox.DiagonalLength
                                thicknessV = profilCurrent["thickness"]/(math.cos(math.radians(profilCurrent["angle"])))
                                overhangV = profilCurrent["overhang"]*math.tan(math.radians(profilCurrent["angle"]))
                                if wire.isClosed():
                                    f = Part.Face(wire)
                                    #Part.show(f)
                                    f = f.extrude(FreeCAD.Vector(0,0,profilCurrent["height"]+2*thicknessV+2*overhangV))
                                    f.translate(FreeCAD.Vector(0.0,0.0,-2*overhangV))
                                ptsPaneProfil=[FreeCAD.Vector(-profilCurrent["overhang"],-overhangV,0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"],0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"]+thicknessV,0.0),FreeCAD.Vector(-profilCurrent["overhang"],-overhangV+thicknessV,0.0)]
                                self.createProfilShape (ptsPaneProfil, midpoint, profilCurrent["rot"], profilCurrent["vec"], profilCurrent["run"], d, self.shps, f)
                                ## subVolume shape
                                ptsSubVolumeProfil=[FreeCAD.Vector(-profilCurrent["overhang"],-overhangV,0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"],0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"]+10000,0.0),FreeCAD.Vector(0.0,profilCurrent["height"]+10000,0.0)]
                                self.createProfilShape (ptsSubVolumeProfil, midpoint, profilCurrent["rot"], profilCurrent["vec"], profilCurrent["run"], d, self.subVolshps, f)
    
                        ## SubVolume
                        self.sub = self.subVolshps.pop()
                        for s in self.subVolshps:
                            self.sub = self.sub.fuse(s)
                        self.sub = self.sub.removeSplitter()
                        if not self.sub.isNull():
                            if not DraftGeomUtils.isNull(pl):
                                self.sub.Placement = pl
                        ## BaseVolume
                        base = Part.makeCompound(self.shps)
                        if not base.isNull():
                            if not DraftGeomUtils.isNull(pl):
                                base.Placement = pl
        base = self.processSubShapes(obj,base)
        if base:
            if not base.isNull():
                obj.Shape = base
示例#14
0
    def execute(self, obj):
        import Part, math, DraftGeomUtils
        pl = obj.Placement
        self.baseface = None

        base = None
        if obj.Base and obj.Angles:
            w = None
            if obj.Base.isDerivedFrom("Part::Feature"):
                if (obj.Base.Shape.Faces and obj.Face):
                    w = obj.Base.Shape.Faces[obj.Face - 1].Wires[0]
                elif obj.Base.Shape.Wires:
                    w = obj.Base.Shape.Wires[0]
            if w:
                if w.isClosed():
                    self.profilsDico = []
                    self.shps = []
                    self.subVolshps = []
                    heights = []
                    edges = DraftGeomUtils.sortEdges(w.Edges)
                    l = len(edges)
                    print("le contour contient " + str(l) + " aretes")
                    for i in range(l):
                        self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i],
                                                obj.IdRel[i], obj.Overhang[i],
                                                obj.Thickness[i])
                    for i in range(l):
                        self.calcMissingData(i)
                    for p in self.profilsDico:
                        heights.append(p["height"])
                    obj.Heights = heights
                    for i in range(l):
                        edgesForward = edges[:]
                        edgesForward.append(edges[0])
                        ptsPaneProject = []
                        profil0 = self.profilsDico[i - 1]
                        profil1 = self.profilsDico[i]
                        if i == l - 1:
                            profil2 = self.profilsDico[0]
                        else:
                            profil2 = self.profilsDico[i + 1]
                        vec0 = edges[i - 1].Vertexes[-1].Point.sub(
                            edges[i - 1].Vertexes[0].Point)
                        vec1 = edges[i].Vertexes[-1].Point.sub(
                            edges[i].Vertexes[0].Point)
                        vec2 = edgesForward[i + 1].Vertexes[-1].Point.sub(
                            edgesForward[i + 1].Vertexes[0].Point)
                        rotEdge0 = math.degrees(DraftVecUtils.angle(vec0))
                        rotEdge1 = math.degrees(DraftVecUtils.angle(vec1))
                        rotEdge2 = math.degrees(DraftVecUtils.angle(vec2))
                        edgeEave0 = DraftGeomUtils.offset(
                            edges[i - 1],
                            self.getPerpendicular(
                                vec0, rotEdge0,
                                profil0["overhang"]).negative())
                        edgeEave1 = DraftGeomUtils.offset(
                            edges[i],
                            self.getPerpendicular(
                                vec1, rotEdge1,
                                profil1["overhang"]).negative())
                        edgeEave2 = DraftGeomUtils.offset(
                            edgesForward[i + 1],
                            self.getPerpendicular(
                                vec2, rotEdge2,
                                profil2["overhang"]).negative())
                        pt0Eave1 = DraftGeomUtils.findIntersection(
                            edgeEave0,
                            edgeEave1,
                            infinite1=True,
                            infinite2=True,
                        )
                        pt1Eave1 = DraftGeomUtils.findIntersection(
                            edgeEave1,
                            edgeEave2,
                            infinite1=True,
                            infinite2=True,
                        )
                        edgeEave1 = DraftGeomUtils.edg(
                            FreeCAD.Vector(pt0Eave1[0]),
                            FreeCAD.Vector(pt1Eave1[0]))
                        edgeRidge0 = DraftGeomUtils.offset(
                            edges[i - 1],
                            self.getPerpendicular(vec0, rotEdge0,
                                                  profil0["run"]))
                        edgeRidge1 = DraftGeomUtils.offset(
                            edges[i],
                            self.getPerpendicular(vec1, rotEdge1,
                                                  profil1["run"]))
                        edgeRidge2 = DraftGeomUtils.offset(
                            edgesForward[i + 1],
                            self.getPerpendicular(vec2, rotEdge2,
                                                  profil2["run"]))
                        midpoint = DraftGeomUtils.findMidpoint(edges[i])
                        pt0Edge1 = edges[i].Vertexes[0].Point
                        pt1Edge1 = edges[i].Vertexes[-1].Point
                        print("Analyse profil " + str(i))
                        if profil1["angle"] != 90.:
                            if profil2["angle"] == 90.:
                                print("situation a droite : pignon")
                                ptsPaneProject.append(
                                    FreeCAD.Vector(pt1Eave1[0]))
                                point = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeEave2,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                            elif profil1["height"] == profil2["height"]:
                                print("situation a droite : ht1 = ht2")
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge2,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInterRidges[0]), pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave1:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave2,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                            elif profil1["height"] > profil2["height"]:
                                print("situation a droite : ht1 > ht2")
                                dec = profil2["height"] / math.tan(
                                    math.radians(profil1["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(
                                    edges[i],
                                    self.getPerpendicular(vec1, rotEdge1, dec))
                                ptInter1 = DraftGeomUtils.findIntersection(
                                    edgeRidge2,
                                    edgeRidge2OnPane,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInter1[0]), pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave1:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave2,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInter1[0]))
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(
                                    ptInter2, [
                                        edgeRidge1.Edges[0],
                                    ], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges))
                            elif profil1["height"] < profil2["height"]:
                                print("situation a droite : ht1 < ht2")
                                dec = profil1["height"] / math.tan(
                                    math.radians(profil2["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(
                                    edgesForward[i + 1],
                                    self.getPerpendicular(vec2, rotEdge2, dec))
                                ptInter1 = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge2OnPane,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInter1[0]), pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave1:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave2,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInter1[0]))
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge2,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            if profil0["angle"] == 90.:
                                print("situation a gauche : pignon")
                                point = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeEave0,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(pt0Eave1[0]))
                            elif profil0["height"] == profil1["height"]:
                                print("situation a gauche : ht1 = ht0")
                                edgeRidge0 = DraftGeomUtils.offset(
                                    edges[i - 1],
                                    self.getPerpendicular(
                                        vec0, rotEdge0, profil0["run"]))
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge1,
                                    edgeRidge0,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInterRidges[0]), pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave3:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave0,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] > profil0["height"]:
                                print("situation a gauche : ht1 > ht0")
                                dec = profil0["height"] / math.tan(
                                    math.radians(profil1["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(
                                    edges[i],
                                    self.getPerpendicular(vec1, rotEdge1, dec))
                                ptInter1 = DraftGeomUtils.findIntersection(
                                    edgeRidge0OnPane,
                                    edgeRidge0,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInter1[0]), pt0Edge1)
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(
                                    ptInter2, [
                                        edgeRidge1.Edges[0],
                                    ], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges))
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInter1[0]))
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave3:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave0,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] < profil0["height"]:
                                print("situation a gauche : ht1 < ht0")
                                dec = profil1["height"] / math.tan(
                                    math.radians(profil0["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(
                                    edges[i - 1],
                                    self.getPerpendicular(vec0, rotEdge0, dec))
                                ptInterRidges = DraftGeomUtils.findIntersection(
                                    edgeRidge0OnPane,
                                    edgeRidge1,
                                    infinite1=True,
                                    infinite2=True,
                                )
                                ptsPaneProject.append(
                                    FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(
                                    FreeCAD.Vector(ptInterRidges[0]), pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(
                                    edgeHip,
                                    edgeEave1,
                                    infinite1=True,
                                    infinite2=False,
                                )
                                if ptInterHipEave3:
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(
                                        edgeHip,
                                        edgeEave0,
                                        infinite1=True,
                                        infinite2=True,
                                    )
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(
                                        FreeCAD.Vector(pt0Eave1[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            ptsPaneProject = DraftVecUtils.removeDoubles(
                                ptsPaneProject)
                            print("ptsPaneProject", ptsPaneProject)
                            print("Fin Analyse profil " + str(i))
                            self.profilsDico[i]["points"] = ptsPaneProject
                            lp = len(ptsPaneProject)
                            ptsPaneProject.append(ptsPaneProject[0])
                            edgesWire = []
                            for i in range(lp):
                                edge = Part.makeLine(ptsPaneProject[i],
                                                     ptsPaneProject[i + 1])
                                edgesWire.append(edge)
                            wire = Part.Wire(edgesWire)
                            d = wire.BoundBox.DiagonalLength
                            thicknessV = profil1["thickness"] / (math.cos(
                                math.radians(profil1["angle"])))
                            overhangV = profil1["overhang"] * math.tan(
                                math.radians(profil1["angle"]))
                            if wire.isClosed():
                                f = Part.Face(wire)
                                f = f.extrude(
                                    FreeCAD.Vector(
                                        0, 0, profil1["height"] +
                                        2 * thicknessV + 2 * overhangV))
                                f.translate(
                                    FreeCAD.Vector(0.0, 0.0, -2 * overhangV))
                            ptsPaneProfil = [
                                FreeCAD.Vector(-profil1["overhang"],
                                               -overhangV, 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"], 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"] + thicknessV,
                                               0.0),
                                FreeCAD.Vector(-profil1["overhang"],
                                               -overhangV + thicknessV, 0.0)
                            ]
                            self.createProfilShape(ptsPaneProfil, midpoint,
                                                   rotEdge1, vec1,
                                                   profil1["run"], d,
                                                   self.shps, f)
                            ## subVolume shape
                            ptsSubVolumeProfil = [
                                FreeCAD.Vector(-profil1["overhang"],
                                               -overhangV, 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"], 0.0),
                                FreeCAD.Vector(profil1["run"],
                                               profil1["height"] + 10000, 0.0),
                                FreeCAD.Vector(0.0, profil1["height"] + 10000,
                                               0.0)
                            ]
                            self.createProfilShape(ptsSubVolumeProfil,
                                                   midpoint, rotEdge1, vec1,
                                                   profil1["run"], d,
                                                   self.subVolshps, f)
                        else:
                            #TODO PIGNON
                            pass

                    ## SubVolume
                    self.sub = self.subVolshps.pop()
                    for s in self.subVolshps:
                        self.sub = self.sub.fuse(s)
                    self.sub = self.sub.removeSplitter()
                    if not self.sub.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            self.sub.Placement = pl
                    ## BaseVolume
                    base = Part.makeCompound(self.shps)
                    if not base.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            base.Placement = pl
        base = self.processSubShapes(obj, base)
        if base:
            if not base.isNull():
                obj.Shape = base
示例#15
0
    def execute(self,obj):

        if self.clone(obj):
            return

        import Part, math, DraftGeomUtils
        pl = obj.Placement
        #self.baseface = None

        base = None
        w = None
        if obj.Base:
            if obj.Base.isDerivedFrom("Part::Feature"):
                if obj.Base.Shape.Solids:
                    base = obj.Base.Shape
                    #pl = obj.Base.Placement
                else:
                    if (obj.Base.Shape.Faces and obj.Face):
                        w = obj.Base.Shape.Faces[obj.Face-1].Wires[0]
                    elif obj.Base.Shape.Wires:
                        w = obj.Base.Shape.Wires[0]
        if w:
            if w.isClosed():
                self.profilsDico = []
                self.shps = []
                self.subVolshps = []
                heights = []
                edges = Part.__sortEdges__(w.Edges)
                l = len(edges)
                for i in range(l):
                    self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i], obj.IdRel[i], obj.Overhang[i], obj.Thickness[i])
                for i in range(l):
                    self.calcMissingData(i)
                for i in range(l):
                    self.calcEdgeGeometry(edges, i)
                for i in range(l):
                    self.calcDraftEdges(i)
                for i in range(l):
                    self.calcEave(i)
                for p in self.profilsDico:
                    heights.append(p["height"])
                obj.Heights = heights
                for i in range(l):
                    self.getRoofPaneProject(i)
                    profilCurrent = self.findProfil(i)
                    midpoint = DraftGeomUtils.findMidpoint(profilCurrent["edge"])
                    ptsPaneProject = profilCurrent["points"]
                    lp = len(ptsPaneProject)
                    if lp != 0:
                        ptsPaneProject.append(ptsPaneProject[0])
                        edgesWire = []
                        for p in range(lp):
                            edge = Part.makeLine(ptsPaneProject[p],ptsPaneProject[p+1])
                            edgesWire.append(edge)
                        wire = Part.Wire(edgesWire)
                        d = wire.BoundBox.DiagonalLength
                        thicknessV = profilCurrent["thickness"]/(math.cos(math.radians(profilCurrent["angle"])))
                        overhangV = profilCurrent["overhang"]*math.tan(math.radians(profilCurrent["angle"]))
                        if wire.isClosed():
                            f = Part.Face(wire)
                            f = f.extrude(FreeCAD.Vector(0,0,profilCurrent["height"]+1000000.0))
                            f.translate(FreeCAD.Vector(0.0,0.0,-2*overhangV))
                        ptsPaneProfil=[FreeCAD.Vector(-profilCurrent["overhang"],-overhangV,0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"],0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"]+thicknessV,0.0),FreeCAD.Vector(-profilCurrent["overhang"],-overhangV+thicknessV,0.0)]
                        self.shps.append(self.createProfilShape(ptsPaneProfil, midpoint, profilCurrent["rot"], profilCurrent["vec"], profilCurrent["run"], d, f))
                        ## subVolume shape
                        ptsSubVolumeProfil=[FreeCAD.Vector(-profilCurrent["overhang"],-overhangV,0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"],0.0),FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"]+900000.0,0.0),FreeCAD.Vector(-profilCurrent["overhang"],profilCurrent["height"]+900000.0,0.0)]
                        self.subVolshps.append(self.createProfilShape(ptsSubVolumeProfil, midpoint, profilCurrent["rot"], profilCurrent["vec"], profilCurrent["run"], d, f))
                ## SubVolume
                self.sub = self.subVolshps.pop()
                for s in self.subVolshps:
                    self.sub = self.sub.fuse(s)
                self.sub = self.sub.removeSplitter()
                if not self.sub.isNull():
                    if not DraftGeomUtils.isNull(pl):
                        self.sub.Placement = pl
                ## BaseVolume
                base = self.shps.pop()
                for s in self.shps :
                    base = base.fuse(s)
                base = self.processSubShapes(obj,base)
                self.applyShape(obj,base,pl,allownosolid=True)
        elif base :
            base = self.processSubShapes(obj,base)
            self.applyShape(obj,base,pl,allownosolid=True)
        else:
            FreeCAD.Console.PrintMessage(translate("Arch","Unable to create a roof"))
示例#16
0
    def execute(self,obj):
        
        if self.clone(obj):
            return
        
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return

        pl = obj.Placement
        if obj.Base.Shape.Solids:
            obj.Shape = obj.Base.Shape.copy()
            if not pl.isNull():
                obj.Placement = obj.Shape.Placement.multiply(pl)
        else:
            if not obj.Profile:
                return
            if not obj.Profile.isDerivedFrom("Part::Part2DObject"):
                return
            if not obj.Profile.Shape:
                return
            if not obj.Profile.Shape.Wires:
                return
            if not obj.Profile.Shape.Faces:
                for w in obj.Profile.Shape.Wires:
                    if not w.isClosed():
                        return
            import DraftGeomUtils, Part, math
            baseprofile = obj.Profile.Shape.copy()
            if hasattr(obj,"ProfilePlacement"):
                if not obj.ProfilePlacement.isNull():
                    baseprofile.Placement = obj.ProfilePlacement.multiply(baseprofile.Placement)
            if not baseprofile.Faces:
                f = []
                for w in baseprofile.Wires:
                    f.append(Part.Face(w))
                if len(f) == 1:
                    baseprofile = f[0]
                else:
                    baseprofile = Part.makeCompound(f)
            shapes = []
            normal = DraftGeomUtils.getNormal(obj.Base.Shape)
            #for wire in obj.Base.Shape.Wires:
            edges = obj.Base.Shape.Edges
            if hasattr(obj,"Edges"):
                if obj.Edges == "Vertical edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,1,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                elif obj.Edges == "Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                elif obj.Edges == "Top Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                    edges = sorted(edges,key=lambda x: x.CenterOfMass.z,reverse=True)
                    z = edges[0].CenterOfMass.z
                    edges = [e for e in edges if abs(e.CenterOfMass.z-z) < 0.00001]
                elif obj.Edges == "Bottom Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(1,0,0))
                    edges = [e for e in edges if round(rv.getAngle(e.tangentAt(e.FirstParameter)),4) in [0,3.1416]]
                    edges = sorted(edges,key=lambda x: x.CenterOfMass.z)
                    z = edges[0].CenterOfMass.z
                    edges = [e for e in edges if abs(e.CenterOfMass.z-z) < 0.00001]
            for e in edges:
                #e = wire.Edges[0]
                bvec = DraftGeomUtils.vec(e)
                bpoint = e.Vertexes[0].Point
                profile = baseprofile.copy()
                #basepoint = profile.Placement.Base
                if hasattr(obj,"BasePoint"):
                    edges = Part.__sortEdges__(profile.Edges)
                    basepointliste = [profile.CenterOfMass]
                    for edge in edges:
                        basepointliste.append(DraftGeomUtils.findMidpoint(edge))
                        basepointliste.append(edge.Vertexes[-1].Point)
                    try:
                        basepoint = basepointliste[obj.BasePoint]
                    except IndexError:
                        FreeCAD.Console.PrintMessage(translate("Arch","Crossing point not found in profile.")+"\n")
                        basepoint = basepointliste[0]
                else :
                    basepoint = profile.CenterOfMass
                profile.translate(bpoint.sub(basepoint))
                if obj.Align:
                    axis = profile.Placement.Rotation.multVec(FreeCAD.Vector(0,0,1))
                    angle = bvec.getAngle(axis)
                    if round(angle,Draft.precision()) != 0:
                        if round(angle,Draft.precision()) != round(math.pi,Draft.precision()):
                            rotaxis = axis.cross(bvec)
                            profile.rotate(DraftVecUtils.tup(bpoint), DraftVecUtils.tup(rotaxis), math.degrees(angle))
                if obj.Rotation:
                    profile.rotate(DraftVecUtils.tup(bpoint), DraftVecUtils.tup(FreeCAD.Vector(bvec).normalize()), obj.Rotation)
                #profile = wire.makePipeShell([profile],True,False,2) TODO buggy
                profile = profile.extrude(bvec)
                if obj.Offset:
                    if not DraftVecUtils.isNull(obj.Offset):
                        profile.translate(obj.Offset)
                shapes.append(profile)
            if shapes:
                if hasattr(obj,"Fuse"):
                    if obj.Fuse:
                        if len(shapes) > 1:
                            s = shapes[0].multiFuse(shapes[1:])
                            s = s.removeSplitter()
                            obj.Shape = s
                            obj.Placement = pl
                            return
                obj.Shape = Part.makeCompound(shapes)
                obj.Placement = pl
示例#17
0
    def execute(self,obj):
        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return

        pl = obj.Placement
        if obj.Base.Shape.Solids:
            obj.Shape = obj.Base.Shape.copy()
            if not pl.isNull():
                obj.Placement = obj.Shape.Placement.multiply(pl)
        else:
            if not obj.Profile:
                return
            if not obj.Profile.isDerivedFrom("Part::Part2DObject"):
                return
            if not obj.Profile.Shape:
                return
            if not obj.Profile.Shape.Wires:
                return
            if not obj.Profile.Shape.Faces:
                for w in obj.Profile.Shape.Wires:
                    if not w.isClosed():
                        return
            import DraftGeomUtils, Part, math
            baseprofile = obj.Profile.Shape.copy()
            if not baseprofile.Faces:
                f = []
                for w in baseprofile.Wires:
                    f.append(Part.Face(w))
                if len(f) == 1:
                    baseprofile = f[0]
                else:
                    baseprofile = Part.makeCompound(f)
            shapes = []
            normal = DraftGeomUtils.getNormal(obj.Base.Shape)
            #for wire in obj.Base.Shape.Wires:
            for e in obj.Base.Shape.Edges:
                #e = wire.Edges[0]
                bvec = DraftGeomUtils.vec(e)
                bpoint = e.Vertexes[0].Point
                profile = baseprofile.copy()
                #basepoint = profile.Placement.Base
                if hasattr(obj,"BasePoint"):
                    edges = DraftGeomUtils.sortEdges(profile.Edges)
                    basepointliste = [profile.CenterOfMass]
                    for edge in edges:
                        basepointliste.append(DraftGeomUtils.findMidpoint(edge))
                        basepointliste.append(edge.Vertexes[-1].Point)
                    try:
                        basepoint = basepointliste[obj.BasePoint]
                    except IndexError:
                        FreeCAD.Console.PrintMessage(translate("Arch","Crossing point not found in profile.\n"))
                        basepoint = basepointliste[0]
                else :
                    basepoint = profile.CenterOfMass
                profile.translate(bpoint.sub(basepoint))
                if obj.Align:
                    axis = profile.Placement.Rotation.multVec(FreeCAD.Vector(0,0,1))
                    angle = bvec.getAngle(axis)
                    if round(angle,Draft.precision()) != 0:
                        if round(angle,Draft.precision()) != round(math.pi,Draft.precision()):
                            rotaxis = axis.cross(bvec)
                            profile.rotate(DraftVecUtils.tup(bpoint), DraftVecUtils.tup(rotaxis), math.degrees(angle))
                if obj.Rotation:
                    profile.rotate(DraftVecUtils.tup(bpoint), DraftVecUtils.tup(FreeCAD.Vector(bvec).normalize()), obj.Rotation)
                #profile = wire.makePipeShell([profile],True,False,2) TODO buggy
                profile = profile.extrude(bvec)
                if obj.Offset:
                    if not DraftVecUtils.isNull(obj.Offset):
                        profile.translate(obj.Offset)
                shapes.append(profile)
            if shapes:
                obj.Shape = Part.makeCompound(shapes)
                obj.Placement = pl
示例#18
0
    def updateData(self, obj, prop):
        if hasattr(self, "arc"):
            from pivy import coin
            import Part, DraftGeomUtils
            import DraftGui
            arcsegs = 24

            # calculate the arc data
            if DraftVecUtils.isNull(obj.Normal):
                norm = App.Vector(0, 0, 1)
            else:
                norm = obj.Normal
            radius = (obj.Dimline.sub(obj.Center)).Length
            self.circle = Part.makeCircle(radius, obj.Center, norm,
                                          obj.FirstAngle.Value,
                                          obj.LastAngle.Value)
            self.p2 = self.circle.Vertexes[0].Point
            self.p3 = self.circle.Vertexes[-1].Point
            mp = DraftGeomUtils.findMidpoint(self.circle.Edges[0])
            ray = mp.sub(obj.Center)

            # set text value
            if obj.LastAngle.Value > obj.FirstAngle.Value:
                a = obj.LastAngle.Value - obj.FirstAngle.Value
            else:
                a = (360 - obj.FirstAngle.Value) + obj.LastAngle.Value
            su = True
            if hasattr(obj.ViewObject, "ShowUnit"):
                su = obj.ViewObject.ShowUnit
            if hasattr(obj.ViewObject, "Decimals"):
                self.string = DraftGui.displayExternal(a,
                                                       obj.ViewObject.Decimals,
                                                       'Angle', su)
            else:
                self.string = DraftGui.displayExternal(a, None, 'Angle', su)
            if obj.ViewObject.Override:
                self.string = obj.ViewObject.Override.replace("$dim",\
                    self.string)
            self.text.string = self.text3d.string = utils.string_encode_coin(
                self.string)

            # check display mode
            try:
                m = obj.ViewObject.DisplayMode
            except:  # swallow all exceptions here since it always fails on first run (Displaymode enum no set yet)
                m = ["2D", "3D"][utils.get_param("dimstyle", 0)]

            # set the arc
            if m == "3D":
                # calculate the spacing of the text
                spacing = (len(self.string) *
                           obj.ViewObject.FontSize.Value) / 8.0
                pts1 = []
                cut = None
                pts2 = []
                for i in range(arcsegs + 1):
                    p = self.circle.valueAt(self.circle.FirstParameter + (
                        (self.circle.LastParameter -
                         self.circle.FirstParameter) / arcsegs) * i)
                    if (p.sub(mp)).Length <= spacing:
                        if cut is None:
                            cut = i
                    else:
                        if cut is None:
                            pts1.append([p.x, p.y, p.z])
                        else:
                            pts2.append([p.x, p.y, p.z])
                self.coords.point.setValues(pts1 + pts2)
                i1 = len(pts1)
                i2 = i1 + len(pts2)
                self.arc.coordIndex.setValues(
                    0,
                    len(pts1) + len(pts2) + 1,
                    list(range(len(pts1))) + [-1] + list(range(i1, i2)))
                if (len(pts1) >= 3) and (len(pts2) >= 3):
                    self.circle1 = Part.Arc(
                        App.Vector(pts1[0][0], pts1[0][1], pts1[0][2]),
                        App.Vector(pts1[1][0], pts1[1][1], pts1[1][2]),
                        App.Vector(pts1[-1][0], pts1[-1][1],
                                   pts1[-1][2])).toShape()
                    self.circle2 = Part.Arc(
                        App.Vector(pts2[0][0], pts2[0][1], pts2[0][2]),
                        App.Vector(pts2[1][0], pts2[1][1], pts2[1][2]),
                        App.Vector(pts2[-1][0], pts2[-1][1],
                                   pts2[-1][2])).toShape()
            else:
                pts = []
                for i in range(arcsegs + 1):
                    p = self.circle.valueAt(self.circle.FirstParameter + (
                        (self.circle.LastParameter -
                         self.circle.FirstParameter) / arcsegs) * i)
                    pts.append([p.x, p.y, p.z])
                self.coords.point.setValues(pts)
                self.arc.coordIndex.setValues(0, arcsegs + 1,
                                              list(range(arcsegs + 1)))

            # set the arrow coords and rotation
            self.trans1.translation.setValue((self.p2.x, self.p2.y, self.p2.z))
            self.coord1.point.setValue((self.p2.x, self.p2.y, self.p2.z))
            self.trans2.translation.setValue((self.p3.x, self.p3.y, self.p3.z))
            self.coord2.point.setValue((self.p3.x, self.p3.y, self.p3.z))
            # calculate small chords to make arrows look better
            arrowlength = 4 * obj.ViewObject.ArrowSize.Value
            u1 = (self.circle.valueAt(self.circle.FirstParameter + arrowlength)
                  ).sub(self.circle.valueAt(
                      self.circle.FirstParameter)).normalize()
            u2 = (self.circle.valueAt(self.circle.LastParameter)).sub(
                self.circle.valueAt(self.circle.LastParameter -
                                    arrowlength)).normalize()
            if hasattr(obj.ViewObject, "FlipArrows"):
                if obj.ViewObject.FlipArrows:
                    u1 = u1.negative()
                    u2 = u2.negative()
            w2 = self.circle.Curve.Axis
            w1 = w2.negative()
            v1 = w1.cross(u1)
            v2 = w2.cross(u2)
            q1 = App.Placement(DraftVecUtils.getPlaneRotation(u1, v1,
                                                              w1)).Rotation.Q
            q2 = App.Placement(DraftVecUtils.getPlaneRotation(u2, v2,
                                                              w2)).Rotation.Q
            self.trans1.rotation.setValue((q1[0], q1[1], q1[2], q1[3]))
            self.trans2.rotation.setValue((q2[0], q2[1], q2[2], q2[3]))

            # setting text pos & rot
            self.tbase = mp
            if hasattr(obj.ViewObject, "TextPosition"):
                if not DraftVecUtils.isNull(obj.ViewObject.TextPosition):
                    self.tbase = obj.ViewObject.TextPosition

            u3 = ray.cross(norm).normalize()
            v3 = norm.cross(u3)
            r = App.Placement(DraftVecUtils.getPlaneRotation(u3, v3,
                                                             norm)).Rotation
            offset = r.multVec(App.Vector(0, 1, 0))

            if hasattr(obj.ViewObject, "TextSpacing"):
                offset = DraftVecUtils.scaleTo(
                    offset, obj.ViewObject.TextSpacing.Value)
            else:
                offset = DraftVecUtils.scaleTo(offset, 0.05)
            if m == "3D":
                offset = offset.negative()
            self.tbase = self.tbase.add(offset)
            q = r.Q
            self.textpos.translation.setValue(
                [self.tbase.x, self.tbase.y, self.tbase.z])
            self.textpos.rotation = coin.SbRotation(q[0], q[1], q[2], q[3])

            # set the angle property
            if round(obj.Angle, utils.precision()) != round(
                    a, utils.precision()):
                obj.Angle = a
示例#19
0
    def execute(self, obj):

        if self.clone(obj):
            return

        if not obj.Base:
            return
        if not obj.Base.Shape:
            return
        if not obj.Base.Shape.Wires:
            return

        pl = obj.Placement
        if obj.Base.Shape.Solids:
            obj.Shape = obj.Base.Shape.copy()
            if not pl.isNull():
                obj.Placement = obj.Shape.Placement.multiply(pl)
        else:
            if not obj.Profile:
                return
            if not obj.Profile.Shape:
                return
            if obj.Profile.Shape.findPlane() is None:
                return
            if not obj.Profile.Shape.Wires:
                return
            if not obj.Profile.Shape.Faces:
                for w in obj.Profile.Shape.Wires:
                    if not w.isClosed():
                        return
            import DraftGeomUtils, Part, math
            baseprofile = obj.Profile.Shape.copy()
            if hasattr(obj, "ProfilePlacement"):
                if not obj.ProfilePlacement.isNull():
                    baseprofile.Placement = obj.ProfilePlacement.multiply(
                        baseprofile.Placement)
            if not baseprofile.Faces:
                f = []
                for w in baseprofile.Wires:
                    f.append(Part.Face(w))
                if len(f) == 1:
                    baseprofile = f[0]
                else:
                    baseprofile = Part.makeCompound(f)
            shapes = []
            normal = DraftGeomUtils.getNormal(obj.Base.Shape)
            edges = obj.Base.Shape.Edges
            if hasattr(obj, "Edges"):
                if obj.Edges == "Vertical edges":
                    rv = obj.Base.Placement.Rotation.multVec(
                        FreeCAD.Vector(0, 1, 0))
                    edges = [
                        e for e in edges
                        if round(rv.getAngle(e.tangentAt(e.FirstParameter)), 4)
                        in [0, 3.1416]
                    ]
                elif obj.Edges == "Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(
                        FreeCAD.Vector(1, 0, 0))
                    edges = [
                        e for e in edges
                        if round(rv.getAngle(e.tangentAt(e.FirstParameter)), 4)
                        in [0, 3.1416]
                    ]
                elif obj.Edges == "Top Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(
                        FreeCAD.Vector(1, 0, 0))
                    edges = [
                        e for e in edges
                        if round(rv.getAngle(e.tangentAt(e.FirstParameter)), 4)
                        in [0, 3.1416]
                    ]
                    edges = sorted(edges,
                                   key=lambda x: x.CenterOfMass.z,
                                   reverse=True)
                    z = edges[0].CenterOfMass.z
                    edges = [
                        e for e in edges if abs(e.CenterOfMass.z - z) < 0.00001
                    ]
                elif obj.Edges == "Bottom Horizontal edges":
                    rv = obj.Base.Placement.Rotation.multVec(
                        FreeCAD.Vector(1, 0, 0))
                    edges = [
                        e for e in edges
                        if round(rv.getAngle(e.tangentAt(e.FirstParameter)), 4)
                        in [0, 3.1416]
                    ]
                    edges = sorted(edges, key=lambda x: x.CenterOfMass.z)
                    z = edges[0].CenterOfMass.z
                    edges = [
                        e for e in edges if abs(e.CenterOfMass.z - z) < 0.00001
                    ]
            for e in edges:
                bvec = DraftGeomUtils.vec(e)
                bpoint = e.Vertexes[0].Point
                profile = baseprofile.copy()
                rot = None  # New rotation.
                # Supplying FreeCAD.Rotation() with two parallel vectors and
                # a null vector may seem strange, but the function is perfectly
                # able to handle this. Its algorithm will use default axes in
                # such cases.
                if obj.Align:
                    if normal is None:
                        rot = FreeCAD.Rotation(FreeCAD.Vector(), bvec, bvec,
                                               "ZYX")
                    else:
                        rot = FreeCAD.Rotation(FreeCAD.Vector(), normal, bvec,
                                               "ZYX")
                    profile.Placement.Rotation = rot
                if hasattr(obj, "BasePoint"):
                    edges = Part.__sortEdges__(profile.Edges)
                    basepointliste = [profile.Placement.Base]
                    for edge in edges:
                        basepointliste.append(
                            DraftGeomUtils.findMidpoint(edge))
                        basepointliste.append(edge.Vertexes[-1].Point)
                    try:
                        basepoint = basepointliste[obj.BasePoint]
                    except IndexError:
                        FreeCAD.Console.PrintMessage(
                            translate("Arch",
                                      "Crossing point not found in profile.") +
                            "\n")
                        basepoint = basepointliste[0]
                else:
                    basepoint = profile.Placement.Base
                delta = bpoint.sub(basepoint)  # Translation vector.
                if obj.Offset and (not DraftVecUtils.isNull(obj.Offset)):
                    if rot is None:
                        delta = delta + obj.Offset
                    else:
                        delta = delta + rot.multVec(obj.Offset)
                profile.translate(delta)
                if obj.Rotation:
                    profile.rotate(bpoint, bvec, obj.Rotation)
                # profile = wire.makePipeShell([profile], True, False, 2) TODO buggy
                profile = profile.extrude(bvec)
                shapes.append(profile)
            if shapes:
                if hasattr(obj, "Fuse"):
                    if obj.Fuse:
                        if len(shapes) > 1:
                            s = shapes[0].multiFuse(shapes[1:])
                            s = s.removeSplitter()
                            obj.Shape = s
                            obj.Placement = pl
                            return
                obj.Shape = Part.makeCompound(shapes)
                obj.Placement = pl