예제 #1
0
    def Activated(self):

        import FreeCADGui
        import Part
        import DraftGeomUtils

        objs = FreeCADGui.Selection.getSelection()
        names = []
        edges = []
        for obj in objs:
            if hasattr(obj, "Shape") and hasattr(obj.Shape,
                                                 "Edges") and obj.Shape.Edges:
                edges.extend(obj.Shape.Edges)
                names.append(obj.Name)
        wires = DraftGeomUtils.findWires(edges)
        FreeCAD.ActiveDocument.openTransaction("Rewire")
        selectlist = []
        for wire in wires:
            if DraftGeomUtils.hasCurves(wire):
                nobj = FreeCAD.ActiveDocument.addObject(
                    "Part::Feature", "Wire")
                nobj.shape = wire
                selectlist.append(nobj)
            else:
                selectlist.append(
                    Draft.makeWire([v.Point for v in wire.OrderedVertexes]))
        for name in names:
            FreeCAD.ActiveDocument.removeObject(name)
        FreeCAD.ActiveDocument.commitTransaction()
        FreeCADGui.Selection.clearSelection()
        for obj in selectlist:
            FreeCADGui.Selection.addSelection(obj)
        FreeCAD.ActiveDocument.recompute()
예제 #2
0
def draftify(objectslist, makeblock=False, delete=True):
    """draftify(objectslist,[makeblock],[delete])
    
    Turn each object of the given list (objectslist can also be a single 
    object) into a Draft parametric wire. 
    
    TODO: support more objects

    Parameters
    ----------
    objectslist :

    makeblock : bool
        If makeblock is True, multiple objects will be grouped in a block.
    
    delete : bool
        If delete = False, old objects are not deleted
    """
    import Part
    import DraftGeomUtils

    if not isinstance(objectslist, list):
        objectslist = [objectslist]
    newobjlist = []
    for obj in objectslist:
        if hasattr(obj, 'Shape'):
            for cluster in Part.getSortedClusters(obj.Shape.Edges):
                w = Part.Wire(cluster)
                if DraftGeomUtils.hasCurves(w):
                    if (len(w.Edges) == 1) and (DraftGeomUtils.geomType(
                            w.Edges[0]) == "Circle"):
                        nobj = makeCircle(w.Edges[0])
                    else:
                        nobj = App.ActiveDocument.addObject(
                            "Part::Feature", obj.Name)
                        nobj.Shape = w
                else:
                    nobj = makeWire(w)
                newobjlist.append(nobj)
                gui_utils.format_object(nobj, obj)
                # sketches are always in wireframe mode. In Draft we don't like that!
                if App.GuiUp:
                    nobj.ViewObject.DisplayMode = "Flat Lines"
            if delete:
                App.ActiveDocument.removeObject(obj.Name)

    if makeblock:
        return makeBlock(newobjlist)
    else:
        if len(newobjlist) == 1:
            return newobjlist[0]
        return newobjlist
예제 #3
0
 def joinFaces(objectslist):
     """makes one big face from selected objects, if possible"""
     faces = []
     for obj in objectslist:
         faces.extend(obj.Shape.Faces)
     u = faces.pop(0)
     for f in faces:
         u = u.fuse(f)
     if DraftGeomUtils.isCoplanar(faces):
         u = DraftGeomUtils.concatenate(u)
         if not DraftGeomUtils.hasCurves(u):
             # several coplanar and non-curved faces: they can become a Draft wire
             newobj = makeWire(u.Wires[0],closed=True,face=True)
         else:
             # if not possible, we do a non-parametric union
             newobj = App.ActiveDocument.addObject("Part::Feature","Union")
             newobj.Shape = u
         addList.append(newobj)
         deleteList.extend(objectslist)
         return newobj
     return None
예제 #4
0
def offset(obj, delta, copy=False, bind=False, sym=False, occ=False):
    """offset(object,delta,[copymode],[bind])

    Offset the given wire by applying the given delta Vector to its first
    vertex.

    Parameters
    ----------
    obj :

    delta : Base.Vector or list of Base.Vector
        If offsetting a BSpline, the delta must not be a Vector but a list
        of Vectors, one for each node of the spline.

    copy : bool
        If copymode is True, another object is created, otherwise the same
        object gets offsetted.

    copy : bool
        If bind is True, and provided the wire is open, the original
        and the offset wires will be bound by their endpoints, forming a face.

    sym : bool
        if sym is True, bind must be true too, and the offset is made on both
        sides, the total width being the given delta length.
    """
    import Part
    import DraftGeomUtils
    newwire = None
    delete = None

    if utils.get_type(obj).startswith("Part::") or utils.get_type(
            obj).startswith("Sketcher::"):
        copy = True
        print(
            "the offset tool is currently unable to offset a non-Draft object directly - Creating a copy"
        )

    def getRect(p, obj):
        """returns length,height,placement"""
        pl = obj.Placement.copy()
        pl.Base = p[0]
        diag = p[2].sub(p[0])
        bb = p[1].sub(p[0])
        bh = p[3].sub(p[0])
        nb = DraftVecUtils.project(diag, bb)
        nh = DraftVecUtils.project(diag, bh)
        if obj.Length.Value < 0: l = -nb.Length
        else: l = nb.Length
        if obj.Height.Value < 0: h = -nh.Length
        else: h = nh.Length
        return l, h, pl

    def getRadius(obj, delta):
        """returns a new radius for a regular polygon"""
        an = math.pi / obj.FacesNumber
        nr = DraftVecUtils.rotate(delta, -an)
        nr.multiply(1 / math.cos(an))
        nr = obj.Shape.Vertexes[0].Point.add(nr)
        nr = nr.sub(obj.Placement.Base)
        nr = nr.Length
        if obj.DrawMode == "inscribed":
            return nr
        else:
            return nr * math.cos(math.pi / obj.FacesNumber)

    newwire = None
    if utils.get_type(obj) == "Circle":
        pass
    elif utils.get_type(obj) == "BSpline":
        pass
    else:
        if sym:
            d1 = App.Vector(delta).multiply(0.5)
            d2 = d1.negative()
            n1 = DraftGeomUtils.offsetWire(obj.Shape, d1)
            n2 = DraftGeomUtils.offsetWire(obj.Shape, d2)
        else:
            if isinstance(delta, float) and (len(obj.Shape.Edges) == 1):
                # circle
                c = obj.Shape.Edges[0].Curve
                nc = Part.Circle(c.Center, c.Axis, delta)
                if len(obj.Shape.Vertexes) > 1:
                    nc = Part.ArcOfCircle(nc,
                                          obj.Shape.Edges[0].FirstParameter,
                                          obj.Shape.Edges[0].LastParameter)
                newwire = Part.Wire(nc.toShape())
                p = []
            else:
                newwire = DraftGeomUtils.offsetWire(obj.Shape, delta)
                if DraftGeomUtils.hasCurves(newwire) and copy:
                    p = []
                else:
                    p = DraftGeomUtils.getVerts(newwire)
    if occ:
        newobj = App.ActiveDocument.addObject("Part::Feature", "Offset")
        newobj.Shape = DraftGeomUtils.offsetWire(obj.Shape, delta, occ=True)
        gui_utils.formatObject(newobj, obj)
        if not copy:
            delete = obj.Name
    elif bind:
        if not DraftGeomUtils.isReallyClosed(obj.Shape):
            if sym:
                s1 = n1
                s2 = n2
            else:
                s1 = obj.Shape
                s2 = newwire
            if s1 and s2:
                w1 = s1.Edges
                w2 = s2.Edges
                w3 = Part.LineSegment(s1.Vertexes[0].Point,
                                      s2.Vertexes[0].Point).toShape()
                w4 = Part.LineSegment(s1.Vertexes[-1].Point,
                                      s2.Vertexes[-1].Point).toShape()
                newobj = App.ActiveDocument.addObject("Part::Feature",
                                                      "Offset")
                newobj.Shape = Part.Face(Part.Wire(w1 + [w3] + w2 + [w4]))
            else:
                print("Draft.offset: Unable to bind wires")
        else:
            newobj = App.ActiveDocument.addObject("Part::Feature", "Offset")
            newobj.Shape = Part.Face(obj.Shape.Wires[0])
        if not copy:
            delete = obj.Name
    elif copy:
        newobj = None
        if sym: return None
        if utils.get_type(obj) == "Wire":
            if p:
                newobj = make_wire(p)
                newobj.Closed = obj.Closed
            elif newwire:
                newobj = App.ActiveDocument.addObject("Part::Feature",
                                                      "Offset")
                newobj.Shape = newwire
            else:
                print("Draft.offset: Unable to duplicate this object")
        elif utils.get_type(obj) == "Rectangle":
            if p:
                length, height, plac = getRect(p, obj)
                newobj = make_rectangle(length, height, plac)
            elif newwire:
                newobj = App.ActiveDocument.addObject("Part::Feature",
                                                      "Offset")
                newobj.Shape = newwire
            else:
                print("Draft.offset: Unable to duplicate this object")
        elif utils.get_type(obj) == "Circle":
            pl = obj.Placement
            newobj = make_circle(delta)
            newobj.FirstAngle = obj.FirstAngle
            newobj.LastAngle = obj.LastAngle
            newobj.Placement = pl
        elif utils.get_type(obj) == "Polygon":
            pl = obj.Placement
            newobj = make_polygon(obj.FacesNumber)
            newobj.Radius = getRadius(obj, delta)
            newobj.DrawMode = obj.DrawMode
            newobj.Placement = pl
        elif utils.get_type(obj) == "BSpline":
            newobj = make_bspline(delta)
            newobj.Closed = obj.Closed
        else:
            # try to offset anyway
            try:
                if p:
                    newobj = make_wire(p)
                    newobj.Closed = obj.Shape.isClosed()
            except Part.OCCError:
                pass
            if (not newobj) and newwire:
                newobj = App.ActiveDocument.addObject("Part::Feature",
                                                      "Offset")
                newobj.Shape = newwire
            if not newobj:
                print("Draft.offset: Unable to create an offset")
        if newobj:
            gui_utils.formatObject(newobj, obj)
    else:
        newobj = None
        if sym: return None
        if utils.get_type(obj) == "Wire":
            if obj.Base or obj.Tool:
                App.Console.PrintWarning("Warning: object history removed\n")
                obj.Base = None
                obj.Tool = None
            obj.Placement = App.Placement(
            )  # p points are in the global coordinate system
            obj.Points = p
        elif utils.get_type(obj) == "BSpline":
            #print(delta)
            obj.Points = delta
            #print("done")
        elif utils.get_type(obj) == "Rectangle":
            length, height, plac = getRect(p, obj)
            obj.Placement = plac
            obj.Length = length
            obj.Height = height
        elif utils.get_type(obj) == "Circle":
            obj.Radius = delta
        elif utils.get_type(obj) == "Polygon":
            obj.Radius = getRadius(obj, delta)
        elif utils.get_type(obj) == 'Part':
            print("unsupported object")  # TODO
        newobj = obj
    if copy and utils.get_param("selectBaseObjects", False):
        gui_utils.select(newobj)
    else:
        gui_utils.select(obj)
    if delete:
        App.ActiveDocument.removeObject(delete)
    return newobj