예제 #1
0
def split_open_wire(wire, newPoint, edgeIndex):
    wire1Points = []
    wire2Points = []
    for index, point in enumerate(wire.Points):
        if index == edgeIndex:
            wire1Points.append(wire.Placement.inverse().multVec(newPoint))
            wire2Points.append(newPoint)
            wire2Points.append(wire.Placement.multVec(point))
        elif index < edgeIndex:
            wire1Points.append(point)
        elif index > edgeIndex:
            wire2Points.append(wire.Placement.multVec(point))
    wire.Points = wire1Points
    make_wire.make_wire(wire2Points, placement=wire.Placement)
예제 #2
0
def make_line(first_param, last_param=None):
    """makeLine(first_param, p2)
    
    Creates a line from 2 points or from a given object.

    Parameters
    ----------
    first_param : 
        Base.Vector -> First point of the line (if p2 == None)
        Part.LineSegment -> Line is created from the given Linesegment
        Shape -> Line is created from the give Shape

    last_param : Base.Vector
        Second point of the line, if not set the function evaluates 
        the first_param to look for a Part.LineSegment or a Shape
    """
    if last_param:
        p1 = first_param
        p2 = last_param
    else:
        if hasattr(first_param, "StartPoint") and hasattr(first_param, "EndPoint"):
            p2 = first_param.EndPoint
            p1 = first_param.StartPoint
        elif hasattr(p1,"Vertexes"):
            p2 = first_param.Vertexes[-1].Point
            p1 = first_param.Vertexes[0].Point
        else:
            _err = "Unable to create a line from the given parameters"
            App.Console.PrintError(_err + "\n")
            return

    obj = make_wire([p1,p2])

    return obj
예제 #3
0
파일: draftify.py 프로젝트: zero804/FreeCAD
def draftify_shape(shape):

    nobj = None
    if DraftGeomUtils.hasCurves(shape):
        if (len(shape.Edges) == 1):
            edge = shape.Edges[0]
            edge_type = DraftGeomUtils.geomType(edge)
            if edge_type == "Circle":
                if edge.isClosed():
                    nobj = make_circle.make_circle(edge)
                else:
                    first_parameter = edge.FirstParameter
                    last_parameter = edge.LastParameter
                    points = [
                        edge.Curve.value(first_parameter),
                        edge.Curve.value(
                            (first_parameter + last_parameter) / 2),
                        edge.Curve.value(last_parameter)
                    ]
                    nobj = make_arc_3points.make_arc_3points(points)
        # TODO: take into consideration trimmed curves and capture the specific
        # type of BSpline and Bezier that can be converted to a draft object.
        # elif edge_type == "BSplineCurve":
        #     knots = [edge.Curve.value(p) for p in edge.Curve.getKnots()]
        #     nobj = make_bspline.make_bspline(knots, closed=edge.isClosed())
        # elif edge_type == "BezierCurve":
        #     nobj = make_bezcurve.make_bezcurve(edge.Curve.getPoles(),
        #                                        closed=edge.isClosed())
    else:
        nobj = make_wire.make_wire(shape)

    return nobj
예제 #4
0
def split_closed_wire(wire, edgeIndex):
    wire.Closed = False
    if edgeIndex == len(wire.Points):
        make_wire.make_wire([
            wire.Placement.multVec(wire.Points[0]),
            wire.Placement.multVec(wire.Points[-1])
        ],
                            placement=wire.Placement)
    else:
        make_wire.make_wire([
            wire.Placement.multVec(wire.Points[edgeIndex - 1]),
            wire.Placement.multVec(wire.Points[edgeIndex])
        ],
                            placement=wire.Placement)
        wire.Points = list(reversed(wire.Points[0:edgeIndex])) + list(
            reversed(wire.Points[edgeIndex:]))
예제 #5
0
 def makeSketchFace(obj):
     """Make a Draft Wire closed and filled out of a sketch."""
     newobj = make_wire.make_wire(obj.Shape, closed=True)
     if newobj:
         newobj.Base = obj
         add_list.append(newobj)
         if App.GuiUp:
             obj.ViewObject.Visibility = False
         return newobj
     return None
예제 #6
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 = make_circle.make_circle(w.Edges[0])
                    else:
                        nobj = App.ActiveDocument.addObject(
                            "Part::Feature", obj.Name)
                        nobj.Shape = w
                else:
                    nobj = make_wire.make_wire(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 make_block.make_block(newobjlist)
    else:
        if len(newobjlist) == 1:
            return newobjlist[0]
        return newobjlist
예제 #7
0
    def joinFaces(objectslist, coplanarity=False, checked=False):
        """Make one big face from selected objects, if possible."""
        faces = []
        for obj in objectslist:
            faces.extend(obj.Shape.Faces)

        # check coplanarity if needed
        if not checked:
            coplanarity = DraftGeomUtils.is_coplanar(faces, 1e-3)
        if not coplanarity:
            _err(_tr("Faces must be coplanar to be refined"))
            return None

        # fuse faces
        fuse_face = faces.pop(0)
        for face in faces:
            fuse_face = fuse_face.fuse(face)

        face = DraftGeomUtils.concatenate(fuse_face)
        # to prevent create new object if concatenate fails
        if face.isEqual(fuse_face):
            face = None

        if face:
            # several coplanar and non-curved faces,
            # they can become a Draft Wire
            if (not DraftGeomUtils.hasCurves(face) and len(face.Wires) == 1):
                newobj = make_wire.make_wire(face.Wires[0],
                                             closed=True,
                                             face=True)
            # if not possible, we do a non-parametric union
            else:
                newobj = doc.addObject("Part::Feature", "Union")
                newobj.Shape = face
            add_list.append(newobj)
            delete_list.extend(objectslist)
            return newobj
        return None
예제 #8
0
 def joinFaces(objectslist):
     """Make 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 = make_wire.make_wire(u.Wires[0],
                                          closed=True, face=True)
         else:
             # if not possible, we do a non-parametric union
             newobj = doc.addObject("Part::Feature", "Union")
             newobj.Shape = u
         add_list.append(newobj)
         delete_list.extend(objectslist)
         return newobj
     return None
예제 #9
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