Ejemplo n.º 1
0
def findEdge(anEdge, aList):
    """Return True if edge is found in list of edges."""
    for e in range(len(aList)):
        if str(anEdge.Curve) == str(aList[e].Curve):
            if DraftVecUtils.equals(anEdge.Vertexes[0].Point,
                                    aList[e].Vertexes[0].Point):
                if DraftVecUtils.equals(anEdge.Vertexes[-1].Point,
                                        aList[e].Vertexes[-1].Point):
                    return e
    return None
Ejemplo n.º 2
0
    def edge_to_path(lastpt, edge, Z):
        if isinstance(edge.Curve, Part.Circle):
            # FreeCAD.Console.PrintMessage("arc\n")
            arcstartpt = edge.valueAt(edge.FirstParameter)
            midpt = edge.valueAt(
                (edge.FirstParameter + edge.LastParameter) * 0.5)
            arcendpt = edge.valueAt(edge.LastParameter)
            # arcchkpt = edge.valueAt(edge.LastParameter * .99)

            if DraftVecUtils.equals(lastpt, arcstartpt):
                startpt = arcstartpt
                endpt = arcendpt
            else:
                startpt = arcendpt
                endpt = arcstartpt
            center = edge.Curve.Center
            relcenter = center.sub(lastpt)

            # start point and end point fall together in the given output precision?
            if fmt(startpt.x) == fmt(endpt.x) and fmt(startpt.y) == fmt(
                    endpt.y):
                if edge.Length < 0.5 * 2 * math.pi * edge.Curve.Radius:
                    # because it is a very small circle -> omit, as that gcode would produce a full circle
                    return endpt, ""
                else:
                    # it is an actual full circle, emit a line for this
                    pass

            # FreeCAD.Console.PrintMessage("arc  startpt= " + str(startpt)+ "\n")
            # FreeCAD.Console.PrintMessage("arc  midpt= " + str(midpt)+ "\n")
            # FreeCAD.Console.PrintMessage("arc  endpt= " + str(endpt)+ "\n")
            arc_cw = check_clockwise([(startpt.x, startpt.y),
                                      (midpt.x, midpt.y), (endpt.x, endpt.y)])
            # FreeCAD.Console.PrintMessage("arc_cw="+ str(arc_cw)+"\n")
            if arc_cw:
                output = "G2"
            else:
                output = "G3"
            output += " X" + str(fmt(endpt.x)) + " Y" + \
                str(fmt(endpt.y)) + " Z" + str(fmt(Z)) + " F" + str(hf)
            output += " I" + str(fmt(relcenter.x)) + " J" + \
                str(fmt(relcenter.y)) + " K" + str(fmt(relcenter.z))
            output += "\n"
            lastpt = endpt
            # FreeCAD.Console.PrintMessage("last pt arc= " + str(lastpt)+ "\n")
        else:
            point = edge.Vertexes[-1].Point
            if DraftVecUtils.equals(point, lastpt):  # edges can come flipped
                point = edge.Vertexes[0].Point
            output = "G1 X" + str(fmt(point.x)) + " Y" + str(fmt(point.y)) + \
                " Z" + str(fmt(Z)) + " F" + str(hf) + "\n"
            lastpt = point
            # FreeCAD.Console.PrintMessage("line\n")
            # FreeCAD.Console.PrintMessage("last pt line= " + str(lastpt)+ "\n")
        return lastpt, output
Ejemplo n.º 3
0
def convert(toolpath, Side, radius, clockwise=False, Z=0.0, firstedge=None, vf=1.0, hf=2.0):
    '''convert(toolpath,Side,radius,clockwise=False,Z=0.0,firstedge=None) Converts lines and arcs to G1,G2,G3 moves. Returns a string.'''
    last = None
    output = ""
    # create the path from the offset shape
    for edge in toolpath:
        if not last:
            # set the first point
            last = edge.Vertexes[0].Point
            # FreeCAD.Console.PrintMessage("last pt= " + str(last)+ "\n")
            output += "G1 X" + str(fmt(last.x)) + " Y" + str(fmt(last.y)) + \
                " Z" + str(fmt(Z)) + " F" + str(vf) + "\n"
        if isinstance(edge.Curve, Part.Circle):
            # FreeCAD.Console.PrintMessage("arc\n")
            arcstartpt = edge.valueAt(edge.FirstParameter)
            midpt = edge.valueAt(
                (edge.FirstParameter + edge.LastParameter) * 0.5)
            arcendpt = edge.valueAt(edge.LastParameter)
            # arcchkpt = edge.valueAt(edge.LastParameter * .99)

            if DraftVecUtils.equals(last, arcstartpt):
                startpt = arcstartpt
                endpt = arcendpt
            else:
                startpt = arcendpt
                endpt = arcstartpt
            center = edge.Curve.Center
            relcenter = center.sub(last)
            # FreeCAD.Console.PrintMessage("arc  startpt= " + str(startpt)+ "\n")
            # FreeCAD.Console.PrintMessage("arc  midpt= " + str(midpt)+ "\n")
            # FreeCAD.Console.PrintMessage("arc  endpt= " + str(endpt)+ "\n")
            arc_cw = check_clockwise(
                [(startpt.x, startpt.y), (midpt.x, midpt.y), (endpt.x, endpt.y)])
            # FreeCAD.Console.PrintMessage("arc_cw="+ str(arc_cw)+"\n")
            if arc_cw:
                output += "G2"
            else:
                output += "G3"
            output += " X" + str(fmt(endpt.x)) + " Y" + \
                str(fmt(endpt.y)) + " Z" + str(fmt(Z)) + " F" + str(hf)
            output += " I" + str(fmt(relcenter.x)) + " J" + \
                str(fmt(relcenter.y)) + " K" + str(fmt(relcenter.z))
            output += "\n"
            last = endpt
            # FreeCAD.Console.PrintMessage("last pt arc= " + str(last)+ "\n")
        else:
            point = edge.Vertexes[-1].Point
            if DraftVecUtils.equals(point, last):  # edges can come flipped
                point = edge.Vertexes[0].Point
            output += "G1 X" + str(fmt(point.x)) + " Y" + str(fmt(point.y)) + \
                " Z" + str(fmt(Z)) + " F" + str(hf) + "\n"
            last = point
            # FreeCAD.Console.PrintMessage("line\n")
            # FreeCAD.Console.PrintMessage("last pt line= " + str(last)+ "\n")
    return output
Ejemplo n.º 4
0
    def alignToFace(self, shape, offset=0):
        """Align the plane to a face.

        It uses the center of mass of the face as `position`,
        and its normal in the center of the face as `axis`,
        then calls `alignToPointAndAxis(position, axis, offset)`.

        If the face is a quadrilateral, then it adjusts the position
        of the plane according to its reported X direction and Y direction.

        Also set `weak` to `False`.

        Parameter
        --------
        shape : Part.Face
            A shape of type `'Face'`.

        offset : float
            Defaults to zero. A value which will be used to offset
            the plane in the direction of its `axis`.

        Returns
        -------
        bool
            `True` if the operation was successful, and `False` if the shape
            is not a `'Face'`.

        See Also
        --------
        alignToPointAndAxis, DraftGeomUtils.getQuad
        """
        # Set face to the unique selected face, if found
        if shape.ShapeType == 'Face':
            self.alignToPointAndAxis(shape.Faces[0].CenterOfMass,
                                     shape.Faces[0].normalAt(0, 0),
                                     offset)
            import DraftGeomUtils
            q = DraftGeomUtils.getQuad(shape)
            if q:
                self.u = q[1]
                self.v = q[2]
                if not DraftVecUtils.equals(self.u.cross(self.v), self.axis):
                    self.u = q[2]
                    self.v = q[1]
                if DraftVecUtils.equals(self.u, Vector(0, 0, 1)):
                    # the X axis is vertical: rotate 90 degrees
                    self.u, self.v = self.v.negative(), self.u
                elif DraftVecUtils.equals(self.u, Vector(0, 0, -1)):
                    self.u, self.v = self.v, self.u.negative()

            self.weak = False
            return True
        else:
            return False
Ejemplo n.º 5
0
    def edge_to_path(lastpt, edge, Z):
        if isinstance(edge.Curve, Part.Circle):
            # FreeCAD.Console.PrintMessage("arc\n")
            arcstartpt = edge.valueAt(edge.FirstParameter)
            midpt = edge.valueAt(
                (edge.FirstParameter + edge.LastParameter) * 0.5)
            arcendpt = edge.valueAt(edge.LastParameter)
            # arcchkpt = edge.valueAt(edge.LastParameter * .99)

            if DraftVecUtils.equals(lastpt, arcstartpt):
                startpt = arcstartpt
                endpt = arcendpt
            else:
                startpt = arcendpt
                endpt = arcstartpt
            center = edge.Curve.Center
            relcenter = center.sub(lastpt)

            # start point and end point fall together in the given output precision?
            if fmt(startpt.x) == fmt(endpt.x) and fmt(startpt.y) == fmt(endpt.y):
                if edge.Length < 0.5 * 2 * math.pi * edge.Curve.Radius:
                    # because it is a very small circle -> omit, as that gcode would produce a full circle
                    return endpt, ""
                else:
                    # it is an actual full circle, emit a line for this
                    pass

            # FreeCAD.Console.PrintMessage("arc  startpt= " + str(startpt)+ "\n")
            # FreeCAD.Console.PrintMessage("arc  midpt= " + str(midpt)+ "\n")
            # FreeCAD.Console.PrintMessage("arc  endpt= " + str(endpt)+ "\n")
            arc_cw = check_clockwise(
                [(startpt.x, startpt.y), (midpt.x, midpt.y), (endpt.x, endpt.y)])
            # FreeCAD.Console.PrintMessage("arc_cw="+ str(arc_cw)+"\n")
            if arc_cw:
                output = "G2"
            else:
                output = "G3"
            output += " X" + str(fmt(endpt.x)) + " Y" + \
                str(fmt(endpt.y)) + " Z" + str(fmt(Z)) + " F" + str(hf)
            output += " I" + str(fmt(relcenter.x)) + " J" + \
                str(fmt(relcenter.y)) + " K" + str(fmt(relcenter.z))
            output += "\n"
            lastpt = endpt
            # FreeCAD.Console.PrintMessage("last pt arc= " + str(lastpt)+ "\n")
        else:
            point = edge.Vertexes[-1].Point
            if DraftVecUtils.equals(point, lastpt):  # edges can come flipped
                point = edge.Vertexes[0].Point
            output = "G1 X" + str(fmt(point.x)) + " Y" + str(fmt(point.y)) + \
                " Z" + str(fmt(Z)) + " F" + str(hf) + "\n"
            lastpt = point
            # FreeCAD.Console.PrintMessage("line\n")
            # FreeCAD.Console.PrintMessage("last pt line= " + str(lastpt)+ "\n")
        return lastpt, output
Ejemplo n.º 6
0
def isSameEdge(e1, e2):
    """isSameEdge(e1,e2): return True if the 2 edges are both lines or arcs/circles and have the same
    points - inspired by Yorik's function isSameLine"""
    if not (isinstance(e1.Curve, Part.Line) or isinstance(e1.Curve, Part.Circle)):
        return False
    if not (isinstance(e2.Curve, Part.Line) or isinstance(e2.Curve, Part.Circle)):
        return False
    if type(e1.Curve) != type(e2.Curve):
        return False
    if isinstance(e1.Curve, Part.Line):
        if (DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[0].Point)) and \
           (DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[-1].Point)):
            return True
        elif (DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[0].Point)) and \
                (DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[-1].Point)):
            return True
    if isinstance(e1.Curve, Part.Circle):
        center = False
        radius = False
        endpts = False
        if e1.Curve.Center == e2.Curve.Center:
            center = True
        if e1.Curve.Radius == e2.Curve.Radius:
            radius = True
        if (DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[0].Point)) and \
           (DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[-1].Point)):
            endpts = True
        elif (DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[0].Point)) and \
                (DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[-1].Point)):
            endpts = True
        if (center and radius and endpts):
            return True
    return False
Ejemplo n.º 7
0
def isSameEdge(e1, e2):
    """isSameEdge(e1,e2): return True if the 2 edges are both lines or arcs/circles and have the same
    points - inspired by Yorik's function isSameLine"""
    if not (isinstance(e1.Curve, Part.Line)
            or isinstance(e1.Curve, Part.Circle)):
        return False
    if not (isinstance(e2.Curve, Part.Line)
            or isinstance(e2.Curve, Part.Circle)):
        return False
    if type(e1.Curve) <> type(e2.Curve):
        return False
    if isinstance(e1.Curve, Part.Line):
        if (DraftVecUtils.equals(e1.Vertexes[0].Point,e2.Vertexes[0].Point)) and \
           (DraftVecUtils.equals(e1.Vertexes[-1].Point,e2.Vertexes[-1].Point)):
            return True
        elif (DraftVecUtils.equals(e1.Vertexes[-1].Point,e2.Vertexes[0].Point)) and \
           (DraftVecUtils.equals(e1.Vertexes[0].Point,e2.Vertexes[-1].Point)):
            return True
    if isinstance(e1.Curve, Part.Circle):
        center = False
        radius = False
        endpts = False
        if e1.Curve.Center == e2.Curve.Center:
            center = True
        if e1.Curve.Radius == e2.Curve.Radius:
            radius = True
        if (DraftVecUtils.equals(e1.Vertexes[0].Point,e2.Vertexes[0].Point)) and \
           (DraftVecUtils.equals(e1.Vertexes[-1].Point,e2.Vertexes[-1].Point)):
            endpts = True
        elif (DraftVecUtils.equals(e1.Vertexes[-1].Point,e2.Vertexes[0].Point)) and \
           (DraftVecUtils.equals(e1.Vertexes[0].Point,e2.Vertexes[-1].Point)):
            endpts = True
        if (center and radius and endpts):
            return True
    return False
Ejemplo n.º 8
0
def join_two_wires(wire1, wire2):
    """join_two_wires(object, object): joins two wires if they share a common
    point as a start or an end.
    """
    wire1AbsPoints = [wire1.Placement.multVec(point) for point in wire1.Points]
    wire2AbsPoints = [wire2.Placement.multVec(point) for point in wire2.Points]
    if ((DraftVecUtils.equals(wire1AbsPoints[0], wire2AbsPoints[-1])
            and DraftVecUtils.equals(wire1AbsPoints[-1], wire2AbsPoints[0]))
        or (DraftVecUtils.equals(wire1AbsPoints[0], wire2AbsPoints[0])
            and DraftVecUtils.equals(wire1AbsPoints[-1], wire2AbsPoints[-1]))):
        wire2AbsPoints.pop()
        wire1.Closed = True
    elif DraftVecUtils.equals(wire1AbsPoints[0], wire2AbsPoints[0]):
        wire1AbsPoints = list(reversed(wire1AbsPoints))
    elif DraftVecUtils.equals(wire1AbsPoints[0], wire2AbsPoints[-1]):
        wire1AbsPoints = list(reversed(wire1AbsPoints))
        wire2AbsPoints = list(reversed(wire2AbsPoints))
    elif DraftVecUtils.equals(wire1AbsPoints[-1], wire2AbsPoints[-1]):
        wire2AbsPoints = list(reversed(wire2AbsPoints))
    elif DraftVecUtils.equals(wire1AbsPoints[-1], wire2AbsPoints[0]):
        pass
    else:
        return False
    wire2AbsPoints.pop(0)
    wire1.Points = ([wire1.Placement.inverse().multVec(point)
                     for point in wire1AbsPoints] +
                    [wire1.Placement.inverse().multVec(point)
                     for point in wire2AbsPoints])
    App.ActiveDocument.removeObject(wire2.Name)
    return True
Ejemplo n.º 9
0
 def touches(e1, e2):
     """Return True if two edges connect at the edges."""
     if len(e1.Vertexes) < 2:
         return False
     if len(e2.Vertexes) < 2:
         return False
     if DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[0].Point):
         return True
     if DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[-1].Point):
         return True
     if DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[0].Point):
         return True
     if DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[-1].Point):
         return True
     return False
Ejemplo n.º 10
0
def isSameLine(e1, e2):
    """Return True if the 2 edges are lines and have the same points."""
    if not isinstance(e1.Curve, Part.LineSegment):
        return False
    if not isinstance(e2.Curve, Part.LineSegment):
        return False

    if (DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[0].Point)
            and DraftVecUtils.equals(e1.Vertexes[-1].Point,
                                     e2.Vertexes[-1].Point)):
        return True
    elif (DraftVecUtils.equals(e1.Vertexes[-1].Point, e2.Vertexes[0].Point) and
          DraftVecUtils.equals(e1.Vertexes[0].Point, e2.Vertexes[-1].Point)):
        return True
    return False
Ejemplo n.º 11
0
    def calc(self):
        import Part

        if (self.p1 != None) and (self.p2 != None):
            points = [
                DraftVecUtils.tup(self.p1, True),
                DraftVecUtils.tup(self.p2, True),
                DraftVecUtils.tup(self.p1, True),
                DraftVecUtils.tup(self.p2, True),
            ]
            if self.p3 != None:
                p1 = self.p1
                p4 = self.p2
                if DraftVecUtils.equals(p1, p4):
                    proj = None
                else:
                    base = Part.Line(p1, p4).toShape()
                    proj = DraftGeomUtils.findDistance(self.p3, base)
                if not proj:
                    p2 = p1
                    p3 = p4
                else:
                    p2 = p1.add(proj.negative())
                    p3 = p4.add(proj.negative())
                points = [DraftVecUtils.tup(p1), DraftVecUtils.tup(p2), DraftVecUtils.tup(p3), DraftVecUtils.tup(p4)]
            self.coords.point.setValues(0, 4, points)
Ejemplo n.º 12
0
def circleInversion(circle, circle2):
    """Circle inversion of a circle, inverting the center point.

    Returns the new circle created from the inverted center of circle2.
    """
    if geomType(circle) != "Circle" or geomType(circle2) != "Circle":
        print("debug: circleInversion bad parameters! Must be circles.")
        return None

    cen1 = circle.Curve.Center

    cen2 = circle2.Curve.Center
    rad2 = circle2.Curve.Radius

    if DraftVecUtils.equals(cen1, cen2):
        return None

    invCen2 = pointInversion(circle, cen2)

    pointOnCircle2 = App.Vector.add(cen2, App.Vector(rad2, 0, 0))
    invPointOnCircle2 = pointInversion(circle, pointOnCircle2)

    return Part.Circle(invCen2,
                       NORM,
                       DraftVecUtils.dist(invCen2, invPointOnCircle2))
Ejemplo n.º 13
0
def pointInversion(circle, point):
    """Return the circle inversion of a point.

    It will return `None` if the given point is equal to the center
    of the circle.
    """
    if geomType(circle) != "Circle" or isinstance(point, App.Vector):
        print("debug: pointInversion bad parameters!")
        return None

    cen = circle.Curve.Center
    rad = circle.Curve.Radius

    if DraftVecUtils.equals(cen, point):
        return None

    # Inverse the distance of the point
    # dist(cen -> P) = r^2 / dist(cen -> invP)

    dist = DraftVecUtils.dist(point, cen)
    invDist = rad**2 / dist

    invPoint = App.Vector(0, 0, point.z)
    invPoint.x = cen.x + (point.x - cen.x) * invDist / dist
    invPoint.y = cen.y + (point.y - cen.y) * invDist / dist

    return invPoint
Ejemplo n.º 14
0
def edg(p1, p2):
    """Return an edge from 2 vectors."""
    if isinstance(p1, FreeCAD.Vector) and isinstance(p2, FreeCAD.Vector):
        if DraftVecUtils.equals(p1, p2):
            return None

        return Part.LineSegment(p1, p2).toShape()
Ejemplo n.º 15
0
 def execute(self,obj):
     import Part
     import DraftGeomUtils
     if obj.Base and obj.PathObj:
         pl = obj.Placement                  #placement of whole pathArray
         if obj.PathSubs:
             w = self.getWireFromSubs(obj)
         elif (hasattr(obj.PathObj.Shape,'Wires') and obj.PathObj.Shape.Wires):
             w = obj.PathObj.Shape.Wires[0]
         elif obj.PathObj.Shape.Edges:
             w = Part.Wire(obj.PathObj.Shape.Edges)
         else:
             App.Console.PrintLog ("PathArray.execute: path " + obj.PathObj.Name + " has no edges\n")
             return
         if (hasattr(obj, "TangentVector")) and (obj.AlignMode == "Tangent") and (obj.Align):
             basePlacement = obj.Base.Shape.Placement
             baseRotation = basePlacement.Rotation
             stdX = App.Vector(1.0, 0.0, 0.0)                          #default TangentVector
             if (not DraftVecUtils.equals(stdX, obj.TangentVector)):
                 preRotation = App.Rotation(stdX, obj.TangentVector)   #make rotation from X to TangentVector
                 netRotation = baseRotation.multiply(preRotation)
             else:
                 netRotation = baseRotation
             base = calculatePlacementsOnPath(
                     netRotation,w,obj.Count,obj.Xlate,obj.Align, obj.AlignMode, 
                         obj.ForceVertical, obj.VerticalVector)
         else:
             base = calculatePlacementsOnPath(
                     obj.Base.Shape.Placement.Rotation,w,obj.Count,obj.Xlate,obj.Align, obj.AlignMode,
                         obj.ForceVertical, obj.VerticalVector)
         return super(PathArray, self).buildShape(obj, pl, base)
Ejemplo n.º 16
0
    def numericRadius(self, rad):
        """Validate the entry radius in the user interface.

        This function is called by the toolbar or taskpanel interface
        when a valid radius has been entered in the input field.
        """
        import DraftGeomUtils
        plane = App.DraftWorkingPlane

        if self.step == 1:
            self.rad = rad
            if len(self.tangents) == 2:
                cir = DraftGeomUtils.circleFrom2tan1rad(self.tangents[0],
                                                        self.tangents[1],
                                                        rad)
                if self.center:
                    _c = DraftGeomUtils.findClosestCircle(self.center, cir)
                    self.center = _c.Center
                else:
                    self.center = cir[-1].Center
            elif self.tangents and self.tanpoints:
                cir = DraftGeomUtils.circleFrom1tan1pt1rad(self.tangents[0],
                                                           self.tanpoints[0],
                                                           rad)
                if self.center:
                    _c = DraftGeomUtils.findClosestCircle(self.center, cir)
                    self.center = _c.Center
                else:
                    self.center = cir[-1].Center
            if self.closedCircle:
                self.drawArc()
            else:
                self.step = 2
                self.arctrack.setCenter(self.center)
                self.ui.labelRadius.setText(translate("draft", "Start angle"))
                self.ui.radiusValue.setToolTip(translate("draft", "Start angle"))
                self.linetrack.p1(self.center)
                self.linetrack.on()
                self.ui.radiusValue.setText("")
                self.ui.radiusValue.setFocus()
                _msg(translate("draft", "Pick start angle"))
        elif self.step == 2:
            self.ui.labelRadius.setText(translate("draft", "Aperture angle"))
            self.ui.radiusValue.setToolTip(translate("draft", "Aperture angle"))
            self.firstangle = math.radians(rad)
            if DraftVecUtils.equals(plane.axis, App.Vector(1, 0, 0)):
                u = App.Vector(0, self.rad, 0)
            else:
                u = DraftVecUtils.scaleTo(App.Vector(1, 0, 0).cross(plane.axis), self.rad)
            urotated = DraftVecUtils.rotate(u, math.radians(rad), plane.axis)
            self.arctrack.setStartAngle(self.firstangle)
            self.step = 3
            self.ui.radiusValue.setText("")
            self.ui.radiusValue.setFocus()
            _msg(translate("draft", "Pick aperture angle"))
        else:
            self.updateAngle(rad)
            self.angle = math.radians(rad)
            self.step = 4
            self.drawArc()
Ejemplo n.º 17
0
    def execute(self, obj):
        """Method run when the object is recomputed.

        Move its children if its placement has changed since the previous
        recompute. Set any child Walls and Structures to have the height of
        the floor if they have not Height value set.
        """

        # move children with this floor
        if hasattr(obj, "Placement"):
            if not hasattr(self, "OldPlacement"):
                self.OldPlacement = obj.Placement.copy()
            else:
                pl = obj.Placement.copy()
                if not DraftVecUtils.equals(pl.Base, self.OldPlacement.Base):
                    print("placement moved")
                    delta = pl.Base.sub(self.OldPlacement.Base)
                    for o in obj.Group:
                        if hasattr(o, "Placement"):
                            o.Placement.move(delta)
                    self.OldPlacement = pl
        # adjust childrens heights
        if obj.Height.Value:
            for o in obj.Group:
                if Draft.getType(o) in ["Wall", "Structure"]:
                    if not o.Height.Value:
                        o.Proxy.execute(o)
Ejemplo n.º 18
0
def pointInversion(circle, point):
    """Circle inversion of a point.

    pointInversion(Circle, Vector)

    Will calculate the inversed point an return it.
    If the given point is equal to the center of the circle "None" will be returned.

    See also:
    http://en.wikipedia.org/wiki/Inversive_geometry
    """
    if (geomType(circle) == "Circle") and isinstance(point, FreeCAD.Vector):
        cen = circle.Curve.Center
        rad = circle.Curve.Radius

        if DraftVecUtils.equals(cen, point):
            return None

        # Inverse the distance of the point
        # dist(cen -> P) = r^2 / dist(cen -> invP)

        dist = DraftVecUtils.dist(point, cen)
        invDist = rad**2 / d

        invPoint = Vector(0, 0, point.z)
        invPoint.x = cen.x + (point.x - cen.x) * invDist / dist
        invPoint.y = cen.y + (point.y - cen.y) * invDist / dist

        return invPoint

    else:
        FreeCAD.Console.PrintMessage("debug: pointInversion bad parameters!\n")
        return None
Ejemplo n.º 19
0
def circleInversion(circle, circle2):
    """
    pointInversion(Circle, Circle)

    Circle inversion of a circle.
    """
    if (geomType(circle) == "Circle") and (geomType(circle2) == "Circle"):
        cen1 = circle.Curve.Center
        rad1 = circle.Curve.Radius

        if DraftVecUtils.equals(cen1, point):
            return None

        invCen2 = Inversion(circle, circle2.Curve.Center)

        pointOnCircle2 = Vector.add(circle2.Curve.Center,
                                    Vector(circle2.Curve.Radius, 0, 0))
        invPointOnCircle2 = Inversion(circle, pointOnCircle2)

        return Part.Circle(invCen2, norm,
                           DraftVecUtils.dist(invCen2, invPointOnCircle2))

    else:
        FreeCAD.Console.PrintMessage(
            "debug: circleInversion bad parameters!\n")
        return None
Ejemplo n.º 20
0
 def calc(self):
     import Part
     if (self.p1 != None) and (self.p2 != None):
         points = [DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True),\
                       DraftVecUtils.tup(self.p1,True),DraftVecUtils.tup(self.p2,True)]
         if self.p3 != None:
             p1 = self.p1
             p4 = self.p2
             if DraftVecUtils.equals(p1, p4):
                 proj = None
             else:
                 base = Part.LineSegment(p1, p4).toShape()
                 proj = DraftGeomUtils.findDistance(self.p3, base)
             if not proj:
                 p2 = p1
                 p3 = p4
             else:
                 p2 = p1.add(proj.negative())
                 p3 = p4.add(proj.negative())
             points = [
                 DraftVecUtils.tup(p1),
                 DraftVecUtils.tup(p2),
                 DraftVecUtils.tup(p3),
                 DraftVecUtils.tup(p4)
             ]
         self.coords.point.setValues(0, 4, points)
Ejemplo n.º 21
0
def circleFrom3LineTangents(edge1, edge2, edge3):
    """Return a list of circles from three edges.

    It calculates up to 6 possible centers.
    """
    def rot(ed):
        geo = Part.LineSegment(v1(ed),
                               v1(ed).add(DraftVecUtils.rotate(vec(ed),
                                                               math.pi/2)))
        return geo.toShape()

    bis12 = angleBisection(edge1, edge2)
    bis23 = angleBisection(edge2, edge3)
    bis31 = angleBisection(edge3, edge1)
    intersections = []

    intsec = findIntersection(bis12, bis23, True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(bis23, bis31, True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(bis31, bis12, True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(rot(bis12), rot(bis23), True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(rot(bis23), rot(bis31), True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(rot(bis31), rot(bis12), True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    circles = []
    for intsec in intersections:
        exists = False
        for cir in circles:
            if DraftVecUtils.equals(cir.Center, intsec.Center):
                exists = True
                break
        if not exists:
            circles.append(intsec)

    if circles:
        return circles
    else:
        return None
Ejemplo n.º 22
0
    def execute(self,obj):
        import Part
        pl = obj.Placement
        shapes = []
        if obj.isDerivedFrom("Part::Part2DObject"):
            # if our clone is 2D, make sure all its linked geometry is 2D too
            for o in obj.Objects:
                if not o.getLinkedObject(True).isDerivedFrom("Part::Part2DObject"):
                    App.Console.PrintWarning("Warning 2D Clone "+obj.Name+" contains 3D geometry")
                    return
        for o in obj.Objects:
            sh = Part.getShape(o)
            if not sh.isNull():
                shapes.append(sh)
        if shapes:
            sh = self.join(obj, shapes)
            m = App.Matrix()
            if hasattr(obj,"Scale") and not sh.isNull():
                sx,sy,sz = obj.Scale
                if not DraftVecUtils.equals(obj.Scale,App.Vector(1, 1, 1)):
                    op = sh.Placement
                    sh.Placement = App.Placement()
                    m.scale(obj.Scale)
                    if sx == sy == sz:
                        sh.transformShape(m)
                    else:
                        sh = sh.transformGeometry(m)
                    sh.Placement = op
            obj.Shape = sh

        obj.Placement = pl
        if hasattr(obj,"positionBySupport"):
            obj.positionBySupport()
Ejemplo n.º 23
0
    def execute(self, obj):
        """Execute when the object is created or recomputed."""
        if not obj.Base or not obj.PathObject:
            return

        # placement of entire PathArray object
        array_placement = obj.Placement

        w = self.get_wires(obj.PathObject, obj.PathSubelements)
        if not w:
            _err(obj.PathObject.Label +
                 translate("draft", ", path object doesn't have 'Edges'."))
            return

        base_rotation = obj.Base.Shape.Placement.Rotation
        final_rotation = base_rotation

        if (obj.Align and obj.AlignMode == "Tangent"
                and hasattr(obj, "TangentVector")):
            Xaxis = App.Vector(1.0, 0.0, 0.0)  # default TangentVector

            if not DraftVecUtils.equals(Xaxis, obj.TangentVector):
                # make rotation from TangentVector to X
                pre_rotation = App.Rotation(obj.TangentVector, Xaxis)
                final_rotation = base_rotation.multiply(pre_rotation)

        copy_placements = placements_on_path(final_rotation, w, obj.Count,
                                             obj.ExtraTranslation, obj.Align,
                                             obj.AlignMode, obj.ForceVertical,
                                             obj.VerticalVector)

        return super(PathArray, self).buildShape(obj, array_placement,
                                                 copy_placements)
Ejemplo n.º 24
0
def isReallyClosed(wire):
    """Check if a wire is really closed."""
    # TODO yet to find out why not use wire.isClosed() direct,
    # in isReallyClosed(wire)

    # Remark out below - Found not true if a vertex is used again
    # in a wire in sketch (e.g. wire with shape like 'd', 'b', 'g', ...)
    # if len(wire.Edges) == len(wire.Vertexes): return True

    # Found cases where Wire[-1] are not 'last' vertexes
    # e.g. Part.Wire( Part.__sortEdges__(<Rectangle Geometries>.toShape()))
    # aboveWire.isClosed() == True, but Wire[-1] are the 3rd vertex
    # for the rectangle - use Edges[i].Vertexes[0/1] instead
    length = len(wire.Edges)

    # Test if it is full circle / ellipse first
    if length == 1:
        if len(wire.Edges[0].Vertexes) == 1:
            return True  # This is a closed wire - full circle/ellipse
        else:
            # TODO Should be False if 1 edge but not single vertex, correct?
            # No need to test further below.
            return False

    # If more than 1 edge, further test below
    v1 = wire.Edges[0].Vertexes[0].Point  # v1 = wire.Vertexes[0].Point
    v2 = wire.Edges[length -
                    1].Vertexes[1].Point  # v2 = wire.Vertexes[-1].Point
    if DraftVecUtils.equals(v1, v2):
        return True

    return False
Ejemplo n.º 25
0
def findRadicalAxis(circle1, circle2):
    """Calculate the radical axis of two circles.

    On the radical axis (also called power line) of two circles any
    tangents drawn from a point on the axis to both circles have
    the same length.

    http://en.wikipedia.org/wiki/Radical_axis
    http://mathworld.wolfram.com/RadicalLine.html

    See Also
    --------
    findRadicalCenter
    """
    if (geomType(circle1) == "Circle") and (geomType(circle2) == "Circle"):
        print("debug: findRadicalAxis bad parameters! Must be circles.")
        return None

    if DraftVecUtils.equals(circle1.Curve.Center, circle2.Curve.Center):
        return None

    r1 = circle1.Curve.Radius
    r2 = circle1.Curve.Radius
    cen1 = circle1.Curve.Center
    # dist .. the distance from cen1 to cen2.
    dist = DraftVecUtils.dist(cen1, circle2.Curve.Center)
    cenDir = cen1.sub(circle2.Curve.Center)
    cenDir.normalize()

    # Get the perpedicular vector.
    perpCenDir = cenDir.cross(App.Vector(0, 0, 1))
    perpCenDir.normalize()

    # J ... The radical center.
    # K ... The point where the cadical axis crosses the line of cen1->cen2.
    # k1 ... Distance from cen1 to K.
    # k2 ... Distance from cen2 to K.
    # dist = k1 + k2

    k1 = (dist + (r1**2 - r2**2) / dist) / 2.0
    # k2 = dist - k1

    K = App.Vector.add(cen1, cenDir.multiply(k1))

    # K_ .. A point somewhere between K and J; actually with a distance
    # of 1 unit from K.
    K_ = App.Vector.add(K, perpCenDir)

    # Original code didn't specify the value of origin nor dir,
    # so this is a guess:
    # radicalAxis = Part.LineSegment(K, Vector.add(origin, dir))

    origin = App.Vector(0, 0, 0)
    radicalAxis = Part.LineSegment(K, App.Vector.add(origin, perpCenDir))

    if radicalAxis:
        return radicalAxis
    else:
        return None
Ejemplo n.º 26
0
def findHomotheticCenterOfCircles(circle1, circle2):
    """Calculate the homothetic center(s) of two circles.

    http://en.wikipedia.org/wiki/Homothetic_center
    http://mathworld.wolfram.com/HomotheticCenter.html
    """

    if (geomType(circle1) == "Circle") and (geomType(circle2) == "Circle"):
        if DraftVecUtils.equals(circle1.Curve.Center, circle2.Curve.Center):
            return None

        cen1_cen2 = Part.LineSegment(circle1.Curve.Center,
                                     circle2.Curve.Center).toShape()
        cenDir = vec(cen1_cen2)
        cenDir.normalize()

        # Get the perpedicular vector.
        perpCenDir = cenDir.cross(Vector(0, 0, 1))
        perpCenDir.normalize()

        # Get point on first circle
        p1 = Vector.add(circle1.Curve.Center,
                        Vector(perpCenDir).multiply(circle1.Curve.Radius))

        centers = []
        # Calculate inner homothetic center
        # Get point on second circle
        p2_inner = Vector.add(
            circle1.Curve.Center,
            Vector(perpCenDir).multiply(-circle1.Curve.Radius))
        hCenterInner = DraftVecUtils.intersect(circle1.Curve.Center,
                                               circle2.Curve.Center, p1,
                                               p2_inner, True, True)
        if hCenterInner:
            centers.append(hCenterInner)

        # Calculate outer homothetic center (only exists of the circles have different radii)
        if circle1.Curve.Radius != circle2.Curve.Radius:
            # Get point on second circle
            p2_outer = Vector.add(
                circle1.Curve.Center,
                Vector(perpCenDir).multiply(circle1.Curve.Radius))
            hCenterOuter = DraftVecUtils.intersect(circle1.Curve.Center,
                                                   circle2.Curve.Center, p1,
                                                   p2_outer, True, True)
            if hCenterOuter:
                centers.append(hCenterOuter)

        if len(centers):
            return centers
        else:
            return None

    else:
        FreeCAD.Console.PrintMessage(
            "debug: findHomotheticCenterOfCirclescleFrom3tan bad parameters!\n"
        )
        return None
Ejemplo n.º 27
0
def findHomotheticCenterOfCircles(circle1, circle2):
    """Calculate the homothetic centers from two circles.

    Return None if the objects are not circles, or if they are concentric.

    http://en.wikipedia.org/wiki/Homothetic_center
    http://mathworld.wolfram.com/HomotheticCenter.html
    """
    if (geomType(circle1) == "Circle" and geomType(circle2) == "Circle"):
        print("debug: findHomotheticCenterOfCircles bad parameters!")
        return None

    if DraftVecUtils.equals(circle1.Curve.Center,
                            circle2.Curve.Center):
        return None

    cen1_cen2 = Part.LineSegment(circle1.Curve.Center,
                                 circle2.Curve.Center).toShape()
    cenDir = vec(cen1_cen2)
    cenDir.normalize()

    # Get the perpedicular vector.
    perpCenDir = cenDir.cross(App.Vector(0, 0, 1))
    perpCenDir.normalize()

    # Get point on first circle
    p1 = App.Vector.add(circle1.Curve.Center,
                        App.Vector(perpCenDir).multiply(circle1.Curve.Radius))

    centers = []
    # Calculate inner homothetic center
    # Get point on second circle
    p2_inner = App.Vector.add(circle1.Curve.Center,
                              App.Vector(perpCenDir).multiply(-circle1.Curve.Radius))
    hCenterInner = DraftVecUtils.intersect(circle1.Curve.Center,
                                           circle2.Curve.Center,
                                           p1, p2_inner,
                                           True, True)
    if hCenterInner:
        centers.append(hCenterInner)

    # Calculate outer homothetic center; it only exists if the circles
    # have different radii
    if circle1.Curve.Radius != circle2.Curve.Radius:
        # Get point on second circle
        p2_outer = App.Vector.add(circle1.Curve.Center,
                                  App.Vector(perpCenDir).multiply(circle1.Curve.Radius))
        hCenterOuter = DraftVecUtils.intersect(circle1.Curve.Center,
                                               circle2.Curve.Center,
                                               p1, p2_outer,
                                               True, True)
        if hCenterOuter:
            centers.append(hCenterOuter)

    if centers:
        return centers
    else:
        return None
Ejemplo n.º 28
0
def edge_to_path(lastpt, edge, Z, hf=2.0):
    if isinstance(edge.Curve, Part.Circle):
        # FreeCAD.Console.PrintMessage("arc\n")
        arcstartpt = edge.valueAt(edge.FirstParameter)
        midpt = edge.valueAt(
            (edge.FirstParameter + edge.LastParameter) * 0.5)
        arcendpt = edge.valueAt(edge.LastParameter)
        # arcchkpt = edge.valueAt(edge.LastParameter * .99)

        if DraftVecUtils.equals(lastpt, arcstartpt):
            startpt = arcstartpt
            endpt = arcendpt
        else:
            startpt = arcendpt
            endpt = arcstartpt
        center = edge.Curve.Center
        relcenter = center.sub(lastpt)
        # FreeCAD.Console.PrintMessage("arc  startpt= " + str(startpt)+ "\n")
        # FreeCAD.Console.PrintMessage("arc  midpt= " + str(midpt)+ "\n")
        # FreeCAD.Console.PrintMessage("arc  endpt= " + str(endpt)+ "\n")
        arc_cw = check_clockwise(
            [(startpt.x, startpt.y), (midpt.x, midpt.y), (endpt.x, endpt.y)])
        # FreeCAD.Console.PrintMessage("arc_cw="+ str(arc_cw)+"\n")
        if arc_cw:
            output = "G2"
        else:
            output = "G3"
        output += " X" + str(fmt(endpt.x)) + " Y" + \
            str(fmt(endpt.y)) + " Z" + str(fmt(Z)) + " F" + str(hf)
        output += " I" + str(fmt(relcenter.x)) + " J" + \
            str(fmt(relcenter.y)) + " K" + str(fmt(relcenter.z))
        output += "\n"
        lastpt = endpt
        # FreeCAD.Console.PrintMessage("last pt arc= " + str(lastpt)+ "\n")
    else:
        point = edge.Vertexes[-1].Point
        if DraftVecUtils.equals(point, lastpt):  # edges can come flipped
            point = edge.Vertexes[0].Point
        output = "G1 X" + str(fmt(point.x)) + " Y" + str(fmt(point.y)) + \
            " Z" + str(fmt(Z)) + " F" + str(hf) + "\n"
        lastpt = point
        # FreeCAD.Console.PrintMessage("line\n")
        # FreeCAD.Console.PrintMessage("last pt line= " + str(lastpt)+ "\n")
    return lastpt, output
Ejemplo n.º 29
0
 def alignToFace(self, shape, offset=0):
     # Set face to the unique selected face, if found
     if shape.ShapeType == 'Face':
         self.alignToPointAndAxis(shape.Faces[0].CenterOfMass, shape.Faces[0].normalAt(0,0), offset)
         import DraftGeomUtils
         q = DraftGeomUtils.getQuad(shape)
         if q:
             self.u = q[1]
             self.v = q[2]
             if not DraftVecUtils.equals(self.u.cross(self.v),self.axis):
                 self.u = q[2]
                 self.v = q[1]
             if DraftVecUtils.equals(self.u,Vector(0,0,1)):
                 # the X axis is vertical: rotate 90 degrees
                 self.u,self.v = self.v.negative(),self.u
                 
         self.weak = False
         return True
     else:
         return False
Ejemplo n.º 30
0
 def onChanged(self,obj,prop):
     if prop == "Placement":
         # make fixtures move along with host
         if hasattr(obj,"Fixtures"):
             vo = obj.Shape.Placement.Base
             vn = obj.Placement.Base
             import DraftVecUtils
             if not DraftVecUtils.equals(vo,vn):
                 delta = vn.sub(vo)
                 for o in obj.Fixtures:
                     o.Placement.move(delta)
Ejemplo n.º 31
0
    def onChanged(self, obj, prop):
        if prop == "Placement":
            # make fixtures move along with host
            if hasattr(obj, "Fixtures"):
                vo = obj.Shape.Placement.Base
                vn = obj.Placement.Base
                import DraftVecUtils

                if not DraftVecUtils.equals(vo, vn):
                    delta = vn.sub(vo)
                    for o in obj.Fixtures:
                        o.Placement.move(delta)
 def alignToPointAndAxis(self, point, axis, offset, upvec=None):
     self.doc = FreeCAD.ActiveDocument
     self.axis = axis;
     self.axis.normalize()
     if (DraftVecUtils.equals(axis, Vector(1,0,0))):
         self.u = Vector(0,1,0)
         self.v = Vector(0,0,1)
     elif (DraftVecUtils.equals(axis, Vector(-1,0,0))):
         self.u = Vector(0,-1,0)
         self.v = Vector(0,0,1)
     elif upvec:
         self.v = upvec
         self.v.normalize()
         self.u = self.v.cross(self.axis)
     else:
         self.v = axis.cross(Vector(1,0,0))
         self.v.normalize()
         self.u = DraftVecUtils.rotate(self.v, -math.pi/2, self.axis)
     offsetVector = Vector(axis); offsetVector.multiply(offset)
     self.position = point.add(offsetVector)
     self.weak = False
Ejemplo n.º 33
0
 def alignToPointAndAxis(self, point, axis, offset=0, upvec=None):
     self.doc = FreeCAD.ActiveDocument
     self.axis = axis;
     self.axis.normalize()
     if (DraftVecUtils.equals(axis, Vector(1,0,0))):
         self.u = Vector(0,1,0)
         self.v = Vector(0,0,1)
     elif (DraftVecUtils.equals(axis, Vector(-1,0,0))):
         self.u = Vector(0,-1,0)
         self.v = Vector(0,0,1)
     elif upvec:
         self.v = upvec
         self.v.normalize()
         self.u = self.v.cross(self.axis)
     else:
         self.v = axis.cross(Vector(1,0,0))
         self.v.normalize()
         self.u = DraftVecUtils.rotate(self.v, -math.pi/2, self.axis)
     offsetVector = Vector(axis); offsetVector.multiply(offset)
     self.position = point.add(offsetVector)
     self.weak = False
Ejemplo n.º 34
0
 def alignToFace(self, shape, offset=0):
     # Set face to the unique selected face, if found
     if shape.ShapeType == 'Face':
         self.alignToPointAndAxis(shape.Faces[0].CenterOfMass, shape.Faces[0].normalAt(0,0), offset)
         import DraftGeomUtils
         q = DraftGeomUtils.getQuad(shape)
         if q:
             self.u = q[1]
             self.v = q[2]
             if not DraftVecUtils.equals(self.u.cross(self.v),self.axis):
                 self.u = q[2]
                 self.v = q[1]
             if DraftVecUtils.equals(self.u,Vector(0,0,1)):
                 # the X axis is vertical: rotate 90 degrees
                 self.u,self.v = self.v.negative(),self.u
             elif DraftVecUtils.equals(self.u,Vector(0,0,-1)):
                 self.u,self.v = self.v,self.u.negative()
                 
         self.weak = False
         return True
     else:
         return False
Ejemplo n.º 35
0
 def onChanged(self,obj,prop):
     self.hideSubobjects(obj,prop)
     # propagate movements to children windows
     if prop == "Placement":
         if obj.Shape:
             if not obj.Shape.isNull():
                 vo = obj.Shape.Placement.Base
                 vn = obj.Placement.Base
                 if not DraftVecUtils.equals(vo,vn):
                     delta = vn.sub(vo)
                     for o in obj.OutList:
                         if (Draft.getType(o) == "Window") or Draft.isClone(o,"Window"):
                             o.Placement.move(delta)
     ArchComponent.Component.onChanged(self,obj,prop)
Ejemplo n.º 36
0
 def execute(self, obj):
     # move children with this floor
     if hasattr(obj, "Placement"):
         if not hasattr(self, "OldPlacement"):
             self.OldPlacement = obj.Placement.copy()
         else:
             pl = obj.Placement.copy()
             if not DraftVecUtils.equals(pl.Base, self.OldPlacement.Base):
                 print "placement moved"
                 delta = pl.Base.sub(self.OldPlacement.Base)
                 for o in obj.Group:
                     if hasattr(o, "Placement"):
                         o.Placement.move(delta)
                 self.OldPlacement = pl
Ejemplo n.º 37
0
def findRadicalAxis(circle1, circle2):
    """Calculate the radical axis of two circles.

    On the radical axis (also called power line) of two circles any
    tangents drawn from a point on the axis to both circles have the same length.

    http://en.wikipedia.org/wiki/Radical_axis
    http://mathworld.wolfram.com/RadicalLine.html

    @sa findRadicalCenter
    """
    if (geomType(circle1) == "Circle") and (geomType(circle2) == "Circle"):
        if DraftVecUtils.equals(circle1.Curve.Center, circle2.Curve.Center):
            return None
        r1 = circle1.Curve.Radius
        r2 = circle1.Curve.Radius
        cen1 = circle1.Curve.Center
        # dist .. the distance from cen1 to cen2.
        dist = DraftVecUtils.dist(cen1, circle2.Curve.Center)
        cenDir = cen1.sub(circle2.Curve.Center)
        cenDir.normalize()

        # Get the perpedicular vector.
        perpCenDir = cenDir.cross(Vector(0, 0, 1))
        perpCenDir.normalize()

        # J ... The radical center.
        # K ... The point where the cadical axis crosses the line of cen1->cen2.
        # k1 ... Distance from cen1 to K.
        # k2 ... Distance from cen2 to K.
        # dist = k1 + k2

        k1 = (dist + (r1 ^ 2 - r2 ^ 2) / dist) / 2.0
        #k2 = dist - k1

        K = Vector.add(cen1, cenDir.multiply(k1))

        # K_ .. A point somewhere between K and J (actually with a distance of 1 unit from K).
        K_ = Vector, add(K, perpCenDir)

        radicalAxis = Part.LineSegment(K, Vector.add(origin, dir))

        if radicalAxis:
            return radicalAxis
        else:
            return None
    else:
        FreeCAD.Console.PrintMessage(
            "debug: findRadicalAxis bad parameters!\n")
        return None
Ejemplo n.º 38
0
 def onChanged(self,obj,prop):
     self.hideSubobjects(obj,prop)
     # propagate movements to children windows
     if prop == "Placement":
         if obj.Shape:
             if not obj.Shape.isNull():
                 vo = obj.Shape.Placement.Base
                 vn = obj.Placement.Base
                 if not DraftVecUtils.equals(vo,vn):
                     delta = vn.sub(vo)
                     for o in obj.OutList:
                         if (Draft.getType(o) == "Window") or Draft.isClone(o,"Window"):
                             o.Placement.move(delta)
     ArchComponent.Component.onChanged(self,obj,prop)
Ejemplo n.º 39
0
 def onChanged(self,obj,prop):
     self.hideSubobjects(obj,prop)
     if prop in ["Base","Height","Width","Align","Additions","Subtractions"]:
         self.createGeometry(obj)
     # propagate movements to children windows
     if prop == "Placement":
         if obj.Shape:
             if not obj.Shape.isNull():
                 vo = obj.Shape.Placement.Base
                 vn = obj.Placement.Base
                 if not DraftVecUtils.equals(vo,vn):
                     delta = vn.sub(vo)
                     for o in obj.OutList:
                         if (Draft.getType(o) == "Window") or Draft.isClone(o,"Window"):
                             o.Placement.move(delta)
Ejemplo n.º 40
0
 def alignToFace(self, shape, offset=0):
     # Set face to the unique selected face, if found
     if shape.ShapeType == 'Face':
         self.alignToPointAndAxis(shape.Faces[0].CenterOfMass, shape.Faces[0].normalAt(0,0), offset)
         import DraftGeomUtils
         q = DraftGeomUtils.getQuad(shape)
         if q:
             self.u = q[1]
             self.v = q[2]
             if not DraftVecUtils.equals(self.u.cross(self.v),self.axis):
                 self.u = q[2]
                 self.v = q[1]
         return True
     else:
         return False
Ejemplo n.º 41
0
 def execute(self, obj):
     # move children with this floor
     if hasattr(obj, "Placement"):
         if not hasattr(self, "OldPlacement"):
             self.OldPlacement = obj.Placement.copy()
         else:
             pl = obj.Placement.copy()
             if not DraftVecUtils.equals(pl.Base, self.OldPlacement.Base):
                 print "placement moved"
                 delta = pl.Base.sub(self.OldPlacement.Base)
                 for o in obj.Group:
                     if hasattr(o, "Placement"):
                         o.Placement.move(delta)
                 self.OldPlacement = pl
     # adjust childrens heights
     for o in obj.Group:
         if Draft.getType(o) in ["Wall", "Structure"]:
             if not o.Height:
                 o.Proxy.execute(o)
Ejemplo n.º 42
0
def makeAreaCurve(edges,direction,startpt=None,endpt=None):
    curveobj = area.Curve()

    cleanededges = PathUtils.cleanedges(edges, 0.01)

    #sort the edges
    vlist,edgestart,common = PathSelection.Sort2Edges([cleanededges[0],cleanededges[1]])
   
    if cleanededges[0].valueAt(cleanededges[0].FirstParameter)<>edgestart:
        firstedge=PathUtils.reverseEdge(cleanededges[0])
    else:
        firstedge=cleanededges[0]
    
    edgelist=[]
    edgelist.append(firstedge)

    #get start and end points of each edge aligned
    for e in cleanededges[1:]:
        if DraftVecUtils.equals(common,e.valueAt(e.FirstParameter)):
            edgelist.append(e)
            common= e.valueAt(e.LastParameter)
        else:
            newedge = PathUtils.reverseEdge(e)
            common= newedge.valueAt(newedge.LastParameter)
            edgelist.append(newedge)
  
    curveobj.append(area.Point(edgestart.x,edgestart.y))


#     seglist =[]
#     if direction=='CW':
#         edgelist.reverse()
#         for e in edgelist:
#             seglist.append(PathUtils.reverseEdge(e)) #swap end points on every segment
#     else:
#         for e in edgelist:
#             seglist.append(e) 
                            
    for s in edgelist:
        curveobj.append(makeAreaVertex(s))

    if startpt:
        # future nearest point code yet to be worked out -fixme
#         v1 = Vector(startpt.X,startpt.Y,startpt.Z)
#         perppoint1 = DraftGeomUtils.findPerpendicular(v1,firstedge)
#         perppoint1 = DraftGeomUtils.findDistance(v1,firstedge)
#         if  perppoint1:
#             curveobj.ChangeStart(area.Point(perppoint1[0].x,perppoint1[0].y))
#         else:
#             curveobj.ChangeStart(area.Point(startpt.X,startpt.Y))
        curveobj.ChangeStart(area.Point(startpt.X,startpt.Y))         
    if endpt:
        # future nearest point code yet to be worked out -fixme
#         v2 = Vector(endpt.X,endpt.Y,endpt.Z)
#         perppoint2 = DraftGeomUtils.findPerpendicular(v2,lastedge)
#         if perppoint2:
#             curveobj.ChangeEnd(area.Point(perppoint2[0].x,perppoint2[0].y))
#         else:
#             curveobj.ChangeEnd(area.Point(endpt.X,endpt.Y))
        curveobj.ChangeEnd(area.Point(endpt.X,endpt.Y))
           
    if direction == 'CW':
        curveobj.Reverse()

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

    if shapes:
        
        if FreeCAD.GuiUp and (not subtraction) and hasattr(obj.ViewObject,"ShapeColor"):
            rgb = obj.ViewObject.ShapeColor
            col = ifcfile.createIfcColourRgb(None,rgb[0],rgb[1],rgb[2])
            ssr = ifcfile.createIfcSurfaceStyleRendering(col,None,None,None,None,None,None,None,"FLAT")
            iss = ifcfile.createIfcSurfaceStyle(None,"BOTH",[ssr])
            psa = ifcfile.createIfcPresentationStyleAssignment([iss])
            for shape in shapes:
                isi = ifcfile.createIfcStyledItem(shape,[psa],None)
                
                
        xvc = ifcfile.createIfcDirection((1.0,0.0,0.0))
        zvc = ifcfile.createIfcDirection((0.0,0.0,1.0))
        ovc = ifcfile.createIfcCartesianPoint((0.0,0.0,0.0))
        gpl = ifcfile.createIfcAxis2Placement3D(ovc,zvc,xvc)
        placement = ifcfile.createIfcLocalPlacement(None,gpl)
        representation = ifcfile.createIfcShapeRepresentation(context,'Body',solidType,shapes)
        productdef = ifcfile.createIfcProductDefinitionShape(None,None,[representation])
        
    return productdef,placement,shapetype