예제 #1
0
    def MoveCallback(self,point,snapinfo):

        self.currentpoint = point
        if len(self.points) == 1:
            # we have the base point already
            self.Length.setText(FreeCAD.Units.Quantity(str(self.points[-1].sub(point).Length)+"mm").UserString)
            self.Length.selectAll()
            self.Length.setFocus()
        elif len(self.points) == 2:
            # now we already have our base line, we update the 1st rectangle
            p = point
            v1 = point.sub(self.points[1])
            v4 = v1.cross(self.points[1].sub(self.points[0]))
            if v4 and v4.Length:
                n = (self.points[1].sub(self.points[0])).cross(v4)
                if n and n.Length:
                    n = DraftVecUtils.project(v1,n)
                    p = self.points[1].add(n)
            self.cubetracker[0].p3(p)
            self.Width.setText(FreeCAD.Units.Quantity(str(self.cubetracker[0].getSize()[1])+"mm").UserString)
            self.Width.selectAll()
            self.Width.setFocus()
        elif len(self.points) == 3:
            # we must first find our height point by projecting on the normal
            w = DraftVecUtils.project(point.sub(self.cubetracker[0].p3()),self.normal)
            # then we update all rectangles
            self.cubetracker[1].p3((self.cubetracker[0].p2()).add(w))
            self.cubetracker[2].p3((self.cubetracker[0].p4()).add(w))
            self.cubetracker[3].p1((self.cubetracker[0].p1()).add(w))
            self.cubetracker[3].p3((self.cubetracker[0].p3()).add(w))
            self.Height.setText(FreeCAD.Units.Quantity(str(w.Length)+"mm").UserString)
            self.Height.selectAll()
            self.Height.setFocus()
예제 #2
0
def makeFlatFace(mobile=[], fixed=[], vert=False):

    import Part
    import DraftVecUtils
    import DraftGeomUtils
    if not fixed:
        pol = Part.makePolygon(mobile + [mobile[0]])
        pol = DraftGeomUtils.flattenWire(pol)
        return Part.Face(pol)
    elif len(fixed) == 3:
        tempf = Part.Face(Part.makePolygon(fixed + [fixed[0]]))
        v4 = mobile[0].add(
            DraftVecUtils.project(tempf.CenterOfMass.sub(mobile[0]),
                                  tempf.normalAt(0, 0)))
        pol = Part.makePolygon([fixed[0], fixed[1], v4, fixed[2], fixed[0]])
        pol = DraftGeomUtils.flattenWire(pol)
        return Part.Face(pol)
    elif len(fixed) == 2:
        tp = DraftGeomUtils.findMidpoint(
            Part.LineSegment(mobile[0], mobile[1]).toShape())
        tempf = Part.Face(Part.makePolygon(fixed + [tp, fixed[0]]))
        v4 = mobile[0].add(
            DraftVecUtils.project(tempf.CenterOfMass.sub(mobile[0]),
                                  tempf.normalAt(0, 0)))
        v5 = mobile[1].add(
            DraftVecUtils.project(tempf.CenterOfMass.sub(mobile[1]),
                                  tempf.normalAt(0, 0)))
        if vert:
            pol = Part.makePolygon([fixed[0], v4, v5, fixed[1], fixed[0]])
        else:
            pol = Part.makePolygon(fixed + [v4, v5, fixed[0]])
        pol = DraftGeomUtils.flattenWire(pol)
        return Part.Face(pol)
예제 #3
0
    def PointCallback(self,point,snapinfo):

        import FreeCADGui
        import Image

        if not point:
            # cancelled
            self.tracker.off()
            return
        elif not self.basepoint:
            # this is our first clicked point, nothing to do just yet
            self.basepoint = point
            self.tracker.setorigin(point)
            self.tracker.on()
            FreeCADGui.Snapper.getPoint(last=point,callback=self.PointCallback,movecallback=self.MoveCallback)
        else:
            # this is our second point
            self.tracker.off()
            midpoint = self.basepoint.add(self.opposite.sub(self.basepoint).multiply(0.5))
            rotation = FreeCAD.DraftWorkingPlane.getRotation().Rotation
            diagonal = self.opposite.sub(self.basepoint)
            length = DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.u).Length
            height = DraftVecUtils.project(diagonal,FreeCAD.DraftWorkingPlane.v).Length
            FreeCAD.ActiveDocument.openTransaction("Create image plane")
            image = FreeCAD.activeDocument().addObject('Image::ImagePlane','ImagePlane')
            image.Label = os.path.splitext(os.path.basename(self.filename))[0]
            image.ImageFile = self.filename
            image.Placement = FreeCAD.Placement(midpoint,rotation)
            image.XSize = length
            image.YSize = height
            FreeCAD.ActiveDocument.commitTransaction()
            FreeCAD.ActiveDocument.recompute()
예제 #4
0
def isPlanar(shape):
    """Return True if the given shape or list of points is planar."""
    n = getNormal(shape)
    if not n:
        return False

    if isinstance(shape, list):
        if len(shape) <= 3:
            return True
        else:
            for v in shape[3:]:
                pv = v.sub(shape[0])
                rv = DraftVecUtils.project(pv, n)
                if not DraftVecUtils.isNull(rv):
                    return False
    else:
        if len(shape.Vertexes) <= 3:
            return True

        for p in shape.Vertexes[1:]:
            pv = p.Point.sub(shape.Vertexes[0].Point)
            rv = DraftVecUtils.project(pv, n)
            if not DraftVecUtils.isNull(rv):
                return False

    return True
예제 #5
0
파일: dxf.py 프로젝트: rucodelia/FreeCAD
def _get_proj(vec, plane=None):
    if not plane:
        return vec

    nx = DraftVecUtils.project(vec, plane.u)
    ny = DraftVecUtils.project(vec, plane.v)
    return App.Vector(nx.Length, ny.Length, 0)
예제 #6
0
 def getSize(self):
     """returns (length,width) of the rectangle"""
     p1 = Vector(self.coords.point.getValues()[0].getValue())
     p2 = Vector(self.coords.point.getValues()[2].getValue())
     diag = p2.sub(p1)
     return ((DraftVecUtils.project(diag, self.u)).Length,
             (DraftVecUtils.project(diag, self.v)).Length)
예제 #7
0
def updateRectangle(obj, nodeIndex, v):
    if nodeIndex == 0:
        obj.Placement.Base = obj.Placement.multVec(v)
    elif nodeIndex == 1:
        obj.Length = DraftVecUtils.project(v, App.Vector(1, 0, 0)).Length
    elif nodeIndex == 2:
        obj.Height = DraftVecUtils.project(v, App.Vector(0, 1, 0)).Length
예제 #8
0
def get_proj(vec, plane=None):
    """Get a projection of the vector in the plane's u and v directions.

    TODO: check if the same function for SVG and DXF projection can be used
    so that this function is not just duplicated code.
    This function may also be present elsewhere, like `WorkingPlane`
    or `DraftGeomUtils`, so we should avoid code duplication.

    Parameters
    ----------
    vec: Base::Vector3
        An arbitrary vector that will be projected on the U and V directions.

    plane: WorkingPlane.Plane
        An object of type `WorkingPlane`.
    """
    if not plane:
        return vec

    nx = DraftVecUtils.project(vec, plane.u)
    lx = nx.Length

    if abs(nx.getAngle(plane.u)) > 0.1:
        lx = -lx

    ny = DraftVecUtils.project(vec, plane.v)
    ly = ny.Length

    if abs(ny.getAngle(plane.v)) > 0.1:
        ly = -ly

    # if techdraw: buggy - we now simply do it at the end
    #    ly = -ly
    return App.Vector(lx, ly, 0)
예제 #9
0
 def createObject(self):
     """Create the actual object in the current document."""
     plane = App.DraftWorkingPlane
     p1 = self.node[0]
     p3 = self.node[-1]
     diagonal = p3.sub(p1)
     halfdiag = App.Vector(diagonal).multiply(0.5)
     center = p1.add(halfdiag)
     p2 = p1.add(DraftVecUtils.project(diagonal, plane.v))
     p4 = p1.add(DraftVecUtils.project(diagonal, plane.u))
     r1 = (p4.sub(p1).Length) / 2
     r2 = (p2.sub(p1).Length) / 2
     try:
         # The command to run is built as a series of text strings
         # to be committed through the `draftutils.todo.ToDo` class.
         rot, sup, pts, fil = self.getStrings()
         if r2 > r1:
             r1, r2 = r2, r1
             m = App.Matrix()
             m.rotateZ(math.pi / 2)
             rot1 = App.Rotation()
             rot1.Q = eval(rot)
             rot2 = App.Placement(m)
             rot2 = rot2.Rotation
             rot = str((rot1.multiply(rot2)).Q)
         if utils.getParam("UsePartPrimitives", False):
             # Insert a Part::Primitive object
             Gui.addModule("Part")
             _cmd = 'FreeCAD.ActiveDocument.'
             _cmd += 'addObject("Part::Ellipse", "Ellipse")'
             _cmd_list = [
                 'ellipse = ' + _cmd, 'ellipse.MajorRadius = ' + str(r1),
                 'ellipse.MinorRadius = ' + str(r2),
                 'pl = FreeCAD.Placement()', 'pl.Rotation.Q= ' + rot,
                 'pl.Base = ' + DraftVecUtils.toString(center),
                 'ellipse.Placement = pl', 'Draft.autogroup(ellipse)',
                 'FreeCAD.ActiveDocument.recompute()'
             ]
             self.commit(translate("draft", "Create Ellipse"), _cmd_list)
         else:
             # Insert a Draft ellipse
             Gui.addModule("Draft")
             _cmd = 'Draft.makeEllipse'
             _cmd += '('
             _cmd += str(r1) + ', ' + str(r2) + ', '
             _cmd += 'placement=pl, '
             _cmd += 'face=' + fil + ', '
             _cmd += 'support=' + sup
             _cmd += ')'
             _cmd_list = [
                 'pl = FreeCAD.Placement()', 'pl.Rotation.Q = ' + rot,
                 'pl.Base = ' + DraftVecUtils.toString(center),
                 'ellipse = ' + _cmd, 'Draft.autogroup(ellipse)',
                 'FreeCAD.ActiveDocument.recompute()'
             ]
             self.commit(translate("draft", "Create Ellipse"), _cmd_list)
     except Exception:
         _err("Draft: Error: Unable to create object.")
     self.finish(cont=True)
예제 #10
0
 def update(self,point):
     "sets the opposite (diagonal) point of the rectangle"
     diagonal = point.sub(self.origin)
     inpoint1 = self.origin.add(DraftVecUtils.project(diagonal,self.v))
     inpoint2 = self.origin.add(DraftVecUtils.project(diagonal,self.u))
     self.coords.point.set1Value(1,inpoint1.x,inpoint1.y,inpoint1.z)
     self.coords.point.set1Value(2,point.x,point.y,point.z)
     self.coords.point.set1Value(3,inpoint2.x,inpoint2.y,inpoint2.z)
 def update(self,point):
     "sets the opposite (diagonal) point of the rectangle"
     diagonal = point.sub(self.origin)
     inpoint1 = self.origin.add(DraftVecUtils.project(diagonal,self.v))
     inpoint2 = self.origin.add(DraftVecUtils.project(diagonal,self.u))
     self.coords.point.set1Value(1,inpoint1.x,inpoint1.y,inpoint1.z)
     self.coords.point.set1Value(2,point.x,point.y,point.z)
     self.coords.point.set1Value(3,inpoint2.x,inpoint2.y,inpoint2.z)
예제 #12
0
 def createObject(self):
     """Create the final object in the current document."""
     plane = App.DraftWorkingPlane
     p1 = self.node[0]
     p3 = self.node[-1]
     diagonal = p3.sub(p1)
     p2 = p1.add(DraftVecUtils.project(diagonal, plane.v))
     p4 = p1.add(DraftVecUtils.project(diagonal, plane.u))
     length = p4.sub(p1).Length
     if abs(DraftVecUtils.angle(p4.sub(p1), plane.u, plane.axis)) > 1:
         length = -length
     height = p2.sub(p1).Length
     if abs(DraftVecUtils.angle(p2.sub(p1), plane.v, plane.axis)) > 1:
         height = -height
     try:
         # The command to run is built as a series of text strings
         # to be committed through the `draftutils.todo.ToDo` class.
         rot, sup, pts, fil = self.getStrings()
         base = p1
         if length < 0:
             length = -length
             base = base.add((p1.sub(p4)).negative())
         if height < 0:
             height = -height
             base = base.add((p1.sub(p2)).negative())
         Gui.addModule("Draft")
         if utils.getParam("UsePartPrimitives", False):
             # Insert a Part::Primitive object
             _cmd = 'FreeCAD.ActiveDocument.'
             _cmd += 'addObject("Part::Plane", "Plane")'
             _cmd_list = [
                 'plane = ' + _cmd, 'plane.Length = ' + str(length),
                 'plane.Width = ' + str(height), 'pl = FreeCAD.Placement()',
                 'pl.Rotation.Q=' + rot,
                 'pl.Base = ' + DraftVecUtils.toString(base),
                 'plane.Placement = pl', 'Draft.autogroup(plane)',
                 'FreeCAD.ActiveDocument.recompute()'
             ]
             self.commit(translate("draft", "Create Plane"), _cmd_list)
         else:
             _cmd = 'Draft.makeRectangle'
             _cmd += '('
             _cmd += 'length=' + str(length) + ', '
             _cmd += 'height=' + str(height) + ', '
             _cmd += 'placement=pl, '
             _cmd += 'face=' + fil + ', '
             _cmd += 'support=' + sup
             _cmd += ')'
             _cmd_list = [
                 'pl = FreeCAD.Placement()', 'pl.Rotation.Q = ' + rot,
                 'pl.Base = ' + DraftVecUtils.toString(base),
                 'rec = ' + _cmd, 'Draft.autogroup(rec)',
                 'FreeCAD.ActiveDocument.recompute()'
             ]
             self.commit(translate("draft", "Create Rectangle"), _cmd_list)
     except Exception:
         _err("Draft: error delaying commit")
     self.finish(cont=True)
예제 #13
0
 def update(self, point):
     """sets the opposite (diagonal) point of the rectangle"""
     if DEBUG_T:
         App.Console.PrintMessage("rectangle tracker : update \n")
     diagonal = point.sub(self.origin)
     inpoint1 = self.origin.add(DraftVecUtils.project(diagonal, self.v))
     inpoint2 = self.origin.add(DraftVecUtils.project(diagonal, self.u))
     self.coords.point.set1Value(1, inpoint1.x, inpoint1.y, inpoint1.z)
     self.coords.point.set1Value(2, point.x, point.y, point.z)
     self.coords.point.set1Value(3, inpoint2.x, inpoint2.y, inpoint2.z)
예제 #14
0
 def update_object_from_edit_points(self,
                                    obj,
                                    node_idx,
                                    v,
                                    alt_edit_mode=0):
     if node_idx == 0:
         obj.Placement.Base = obj.Placement.multVec(v)
     elif node_idx == 1:
         obj.Length = DraftVecUtils.project(v, App.Vector(1, 0, 0)).Length
     elif node_idx == 2:
         obj.Height = DraftVecUtils.project(v, App.Vector(0, 1, 0)).Length
예제 #15
0
파일: getSVG.py 프로젝트: KimK/FreeCAD
def getProj(vec, plane):
    if not plane: return vec
    nx = DraftVecUtils.project(vec,plane.u)
    lx = nx.Length
    if abs(nx.getAngle(plane.u)) > 0.1: lx = -lx
    ny = DraftVecUtils.project(vec,plane.v)
    ly = ny.Length
    if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly
    #if techdraw: buggy - we now simply do it at the end
    #    ly = -ly
    return Vector(lx,ly,0)
예제 #16
0
def getProj(vec, plane):
    if not plane: return vec
    nx = DraftVecUtils.project(vec, plane.u)
    lx = nx.Length
    if abs(nx.getAngle(plane.u)) > 0.1: lx = -lx
    ny = DraftVecUtils.project(vec, plane.v)
    ly = ny.Length
    if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly
    #if techdraw: buggy - we now simply do it at the end
    #    ly = -ly
    return Vector(lx, ly, 0)
예제 #17
0
def updatePartBox(obj, nodeIndex, v):
    if nodeIndex == 0:
        obj.Placement.Base = obj.Placement.Base + v
    elif nodeIndex == 1:
        _vector = DraftVecUtils.project(v, App.Vector(1, 0, 0))
        obj.Length = _vector.Length
    elif nodeIndex == 2:
        _vector = DraftVecUtils.project(v, App.Vector(0, 1, 0))
        obj.Width = _vector.Length
    elif nodeIndex == 3:
        _vector = DraftVecUtils.project(v, App.Vector(0, 0, 1))
        obj.Height = _vector.Length
예제 #18
0
 def isInside(self,point):
     "returns True if the given point is inside the rectangle"
     vp = point.sub(self.p1())
     uv = self.p2().sub(self.p1())
     vv = self.p4().sub(self.p1())
     uvp = DraftVecUtils.project(vp,uv)
     vvp = DraftVecUtils.project(vp,vv)
     if uvp.getAngle(uv) < 1:
         if vvp.getAngle(vv) < 1:
             if uvp.Length <= uv.Length:
                 if vvp.Length <= vv.Length:
                     return True
     return False
예제 #19
0
def getProjectionToSVGPlane(vec, plane):
    """getProjectionToSVGPlane(Vector, Plane):
    Returns projection of vector on plane.
    """
    nx = DraftVecUtils.project(vec, plane.u)
    lx = nx.Length
    if abs(nx.getAngle(plane.u)) > 0.1:
        lx = -lx
    ny = DraftVecUtils.project(vec, plane.v)
    ly = ny.Length
    if abs(ny.getAngle(plane.v)) > 0.1:
        ly = -ly
    return FreeCAD.Vector(lx, ly, 0)
예제 #20
0
 def isInside(self,point):
     "returns True if the given point is inside the rectangle"
     vp = point.sub(self.p1())
     uv = self.p2().sub(self.p1())
     vv = self.p4().sub(self.p1())
     uvp = DraftVecUtils.project(vp,uv)
     vvp = DraftVecUtils.project(vp,vv)
     if uvp.getAngle(uv) < 1:
         if vvp.getAngle(vv) < 1:
             if uvp.Length <= uv.Length:
                 if vvp.Length <= vv.Length:
                     return True
     return False
예제 #21
0
 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
예제 #22
0
def _get_proj(vec, plane=None):
    """Get a projection of the vector in the plane's u and v directions.

    TODO: check if the same function for SVG and DXF projection can be used
    so that this function is not just duplicated code.
    This function may also be present elsewhere, like `WorkingPlane`
    or `DraftGeomUtils`, so we should avoid code duplication.
    """
    if not plane:
        return vec

    nx = DraftVecUtils.project(vec, plane.u)
    ny = DraftVecUtils.project(vec, plane.v)
    return App.Vector(nx.Length, ny.Length, 0)
예제 #23
0
 def setString(self,text=None):
     "sets the dim string to the given value or auto value"
     self.dimnode.param1.setValue(.5)
     p1 = Vector(self.dimnode.pnts.getValues()[0].getValue())
     p2 = Vector(self.dimnode.pnts.getValues()[-1].getValue())
     m = self.dimnode.datumtype.getValue()
     if m == 2:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(1,0,0))).Length
     elif m == 3:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(0,1,0))).Length
     else:
         self.Distance = (p2.sub(p1)).Length
     text = FreeCAD.Units.Quantity(self.Distance,FreeCAD.Units.Length).UserString
     self.dimnode.string.setValue(text)
예제 #24
0
def getCutVolume(cutplane, shapes):
    """getCutVolume(cutplane,shapes): returns a cut face and a cut volume
    from the given shapes and the given cutting plane"""
    import Part

    placement = FreeCAD.Placement(cutplane.Placement)
    # building boundbox
    bb = shapes[0].BoundBox
    for sh in shapes[1:]:
        bb.add(sh.BoundBox)
    bb.enlarge(1)
    um = vm = wm = 0
    ax = placement.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    u = placement.Rotation.multVec(FreeCAD.Vector(1, 0, 0))
    v = placement.Rotation.multVec(FreeCAD.Vector(0, 1, 0))
    if not bb.isCutPlane(placement.Base, ax):
        FreeCAD.Console.PrintMessage(str(translate("Arch", "No objects are cut by the plane")))
        return None, None, None
    else:
        corners = [
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMax),
        ]
        for c in corners:
            dv = c.sub(placement.Base)
            um1 = DraftVecUtils.project(dv, u).Length
            um = max(um, um1)
            vm1 = DraftVecUtils.project(dv, v).Length
            vm = max(vm, vm1)
            wm1 = DraftVecUtils.project(dv, ax).Length
            wm = max(wm, wm1)
        p1 = FreeCAD.Vector(-um, vm, 0)
        p2 = FreeCAD.Vector(um, vm, 0)
        p3 = FreeCAD.Vector(um, -vm, 0)
        p4 = FreeCAD.Vector(-um, -vm, 0)
        cutface = Part.makePolygon([p1, p2, p3, p4, p1])
        cutface = Part.Face(cutface)
        cutface.Placement = placement
        cutnormal = DraftVecUtils.scaleTo(ax, wm)
        cutvolume = cutface.extrude(cutnormal)
        cutnormal = DraftVecUtils.neg(cutnormal)
        invcutvolume = cutface.extrude(cutnormal)
        return cutface, cutvolume, invcutvolume
예제 #25
0
def getCutVolume(cutplane, shapes):
    """getCutVolume(cutplane,shapes): returns a cut face and a cut volume
    from the given shapes and the given cutting plane"""
    import Part
    placement = FreeCAD.Placement(cutplane.Placement)
    # building boundbox
    bb = shapes[0].BoundBox
    for sh in shapes[1:]:
        bb.add(sh.BoundBox)
    bb.enlarge(1)
    um = vm = wm = 0
    ax = placement.Rotation.multVec(FreeCAD.Vector(0, 0, 1))
    u = placement.Rotation.multVec(FreeCAD.Vector(1, 0, 0))
    v = placement.Rotation.multVec(FreeCAD.Vector(0, 1, 0))
    if not bb.isCutPlane(placement.Base, ax):
        FreeCAD.Console.PrintMessage(
            str(translate("Arch", "No objects are cut by the plane")))
        return None, None, None
    else:
        corners = [
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMax)
        ]
        for c in corners:
            dv = c.sub(placement.Base)
            um1 = DraftVecUtils.project(dv, u).Length
            um = max(um, um1)
            vm1 = DraftVecUtils.project(dv, v).Length
            vm = max(vm, vm1)
            wm1 = DraftVecUtils.project(dv, ax).Length
            wm = max(wm, wm1)
        p1 = FreeCAD.Vector(-um, vm, 0)
        p2 = FreeCAD.Vector(um, vm, 0)
        p3 = FreeCAD.Vector(um, -vm, 0)
        p4 = FreeCAD.Vector(-um, -vm, 0)
        cutface = Part.makePolygon([p1, p2, p3, p4, p1])
        cutface = Part.Face(cutface)
        cutface.Placement = placement
        cutnormal = DraftVecUtils.scaleTo(ax, wm)
        cutvolume = cutface.extrude(cutnormal)
        cutnormal = DraftVecUtils.neg(cutnormal)
        invcutvolume = cutface.extrude(cutnormal)
        return cutface, cutvolume, invcutvolume
예제 #26
0
 def getLocalRot(self,point):
     "Same as getLocalCoords, but discards the WP position"
     xv = DraftVecUtils.project(point,self.u)
     x = xv.Length
     if xv.getAngle(self.u) > 1:
             x = -x
     yv = DraftVecUtils.project(point,self.v)
     y = yv.Length
     if yv.getAngle(self.v) > 1:
             y = -y
     zv = DraftVecUtils.project(point,self.axis)
     z = zv.Length
     if zv.getAngle(self.axis) > 1:
             z = -z
     return Vector(x,y,z)
예제 #27
0
 def getLocalRot(self, point):
     "Same as getLocalCoords, but discards the WP position"
     xv = DraftVecUtils.project(point, self.u)
     x = xv.Length
     if xv.getAngle(self.u) > 1:
         x = -x
     yv = DraftVecUtils.project(point, self.v)
     y = yv.Length
     if yv.getAngle(self.v) > 1:
         y = -y
     zv = DraftVecUtils.project(point, self.axis)
     z = zv.Length
     if zv.getAngle(self.axis) > 1:
         z = -z
     return Vector(x, y, z)
예제 #28
0
 def update_object_from_edit_points(self,
                                    obj,
                                    node_idx,
                                    v,
                                    alt_edit_mode=0):
     if node_idx == 0:
         obj.Placement.Base = obj.Placement.Base + v
     elif node_idx == 1:
         _vector = DraftVecUtils.project(v, App.Vector(1, 0, 0))
         obj.Length = _vector.Length
     elif node_idx == 2:
         _vector = DraftVecUtils.project(v, App.Vector(0, 1, 0))
         obj.Width = _vector.Length
     elif node_idx == 3:
         _vector = DraftVecUtils.project(v, App.Vector(0, 0, 1))
         obj.Height = _vector.Length
예제 #29
0
 def setup_clipping_plane(self, vobj):
     """Set-up the clipping plane of the 3dView.
     This method is called when the property CutView or the object Placement changes.
     """
     sg = Gui.ActiveDocument.ActiveView.getSceneGraph()
     if self.clip:
         sg.removeChild(self.clip)
         self.clip = None
     '''for o in Draft.getGroupContents(vobj.Object.Objects,walls=True):
         if hasattr(o.ViewObject,"Lighting"):
             o.ViewObject.Lighting = "One side"''' # prefer keeping interior lighty
     self.clip = coin.SoClipPlane()
     self.clip.on.setValue(True)
     norm = vobj.Object.Proxy.getNormal(vobj.Object)
     mp = vobj.Object.Shape.CenterOfMass
     mp = DraftVecUtils.project(mp, norm)
     dist = mp.Length  #- 0.1 # to not clip exactly on the section object
     norm = norm.negative()
     marg = 1
     if hasattr(vobj, "CutMargin"):
         marg = vobj.CutMargin.Value
     if mp.getAngle(norm) > 1:
         dist += marg
         dist = -dist
     else:
         dist -= marg
     plane = coin.SbPlane(coin.SbVec3f(norm.x, norm.y, norm.z), dist)
     self.clip.plane.setValue(plane)
     sg.insertChild(self.clip, 0)
예제 #30
0
 def updateWire(self,v):
     pts = self.obj.Points
     editPnt = v#self.invpl.multVec(v)
     # DNC: allows to close the curve by placing ends close to each other
     tol = 0.001
     if ( ( self.editing == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or ( self.editing == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
         self.obj.Closed = True
     # DNC: fix error message if edited point coincides with one of the existing points
     if ( editPnt in pts ) == True: # checks if point enter is equal to other, this could cause a OCC problem
         FreeCAD.Console.PrintMessage(translate("draft", "Is not possible to have two coincident points in this object, please try again.")+"\n")
         if Draft.getType(self.obj) in ["BezCurve"]: self.resetTrackers()
         else: self.trackers[self.editing].set(self.pl.multVec(self.obj.Points[self.editing]))
         return
     if Draft.getType(self.obj) in ["BezCurve"]:
         pts = self.recomputePointsBezier(pts,self.editing,v,self.obj.Degree,moveTrackers=False)
     # check that the new point lies on the plane of the wire
     import DraftGeomUtils, DraftVecUtils
     if self.obj.Closed:
         n = DraftGeomUtils.getNormal(self.obj.Shape)
         dv = editPnt.sub(pts[self.editing])
         rn = DraftVecUtils.project(dv,n)
         if dv.Length:
             editPnt = editPnt.add(rn.negative())
     pts[self.editing] = editPnt
     self.obj.Points = pts
     self.trackers[self.editing].set(self.pl.multVec(v))
예제 #31
0
 def getLocalCoords(self, point):
     "returns the coordinates of a given point on the working plane"
     pt = point.sub(self.position)
     xv = DraftVecUtils.project(pt, self.u)
     x = xv.Length
     if xv.getAngle(self.u) > 1:
         x = -x
     yv = DraftVecUtils.project(pt, self.v)
     y = yv.Length
     if yv.getAngle(self.v) > 1:
         y = -y
     zv = DraftVecUtils.project(pt, self.axis)
     z = zv.Length
     if zv.getAngle(self.axis) > 1:
         z = -z
     return Vector(x, y, z)
예제 #32
0
 def getLocalCoords(self,point):
     "returns the coordinates of a given point on the working plane"
     pt = point.sub(self.position)
     xv = DraftVecUtils.project(pt,self.u)
     x = xv.Length
     if xv.getAngle(self.u) > 1:
             x = -x
     yv = DraftVecUtils.project(pt,self.v)
     y = yv.Length
     if yv.getAngle(self.v) > 1:
             y = -y
     zv = DraftVecUtils.project(pt,self.axis)
     z = zv.Length
     if zv.getAngle(self.axis) > 1:
             z = -z
     return Vector(x,y,z)
예제 #33
0
    def align_axis_to_edge(self, wall, sub_link):
        """Align the wall Placement in LCS xy plane to a given edge.
        If the linked subobject changes, the wall is not notified, so 
        I was thinking to modify the Axis system object to do that.
        TODO: Take into account global placement.
        """

        if sub_link is None:
            return
        linked_object = sub_link[0]
        linked_subobject_names = sub_link[1]
        for name in linked_subobject_names:
            subobject = linked_object.getSubObject(name)
            if hasattr(subobject, "ShapeType") and subobject.ShapeType == 'Edge':
                break
        
        import DraftVecUtils
        v1 = subobject.Vertexes[0].Point
        v2 = subobject.Vertexes[1].Point
        p = wall.Placement.Base.sub(v1)
        point_on_edge = DraftVecUtils.project(p, v2.sub(v1)) + v1

        angle = Draft.DraftVecUtils.angle(App.Vector(1,0,0), v2.sub(v1))
        print(angle)

        wall.Placement.Base.x = point_on_edge.x
        wall.Placement.Base.y = point_on_edge.y

        wall.Placement.Rotation.Angle = angle
예제 #34
0
def sortedge(edge):

    vdir = FreeCAD.Vector(1,0,0)
    proj = DraftVecUtils.project(edge.CenterOfMass,vdir)
    if proj.getAngle(vdir) < 1:
        return proj.Length
    else:
        return -proj.Length
예제 #35
0
 def setString(self,text=None):
     "sets the dim string to the given value or auto value"
     self.dimnode.param1.setValue(.5)
     p1 = Vector(self.dimnode.pnts.getValues()[0].getValue())
     p2 = Vector(self.dimnode.pnts.getValues()[-1].getValue())
     m = self.dimnode.datumtype.getValue()
     if m == 2:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(1,0,0))).Length
     elif m == 3:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(0,1,0))).Length
     else:
         self.Distance = (p2.sub(p1)).Length 
     if not text:
         text = Draft.getParam("dimPrecision",2)
         text = "%."+str(text)+"f"
         text = (text % self.Distance)
     self.dimnode.string.setValue(text)
예제 #36
0
    def getProjectedLength(self, v, ref):
        """gets a signed length from projecting a vector on another"""

        proj = DraftVecUtils.project(v, ref)
        if proj.getAngle(ref) < 1:
            return proj.Length
        else:
            return -proj.Length
 def setString(self,text=None):
     "sets the dim string to the given value or auto value"
     self.dimnode.param1.setValue(.5)
     p1 = Vector(self.dimnode.pnts.getValues()[0].getValue())
     p2 = Vector(self.dimnode.pnts.getValues()[-1].getValue())
     m = self.dimnode.datumtype.getValue()
     if m == 2:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(1,0,0))).Length
     elif m == 3:
         self.Distance = (DraftVecUtils.project(p2.sub(p1),Vector(0,1,0))).Length
     else:
         self.Distance = (p2.sub(p1)).Length 
     if not text:
         text = Draft.getParam("dimPrecision",2)
         text = "%."+str(text)+"f"
         text = (text % self.Distance)
     self.dimnode.string.setValue(text)
예제 #38
0
    def order(self,face,right=False):

        """order(face,[right]): returns a list of vertices
        ordered clockwise. The first vertex will be the
        lefmost one, unless right is True, in which case the
        first vertex will be the rightmost one"""

        verts = [v.Point for v in face.OuterWire.OrderedVertexes]

        # flatten the polygon on the XY plane

        wp = WorkingPlane.plane()
        wp.alignToPointAndAxis(face.CenterOfMass,face.normalAt(0,0))
        pverts = []
        for v in verts:
            vx = DraftVecUtils.project(v,wp.u)
            lx = vx.Length
            if vx.getAngle(wp.u) > 1:
                lx = -lx
            vy = DraftVecUtils.project(v,wp.v)
            ly = vy.Length
            if vy.getAngle(wp.v) > 1:
                ly = -ly
            pverts.append(FreeCAD.Vector(lx,ly,0))
        pverts.append(pverts[0])

        # https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order

        s = 0
        for i in range(len(pverts)-1):
            s += (pverts[i+1].x-pverts[i].x)*(pverts[i+1].y+pverts[i].y)
        if s < 0:
            verts.reverse()
        elif s == 0:
            print("error computing winding direction")
            return

        return verts
예제 #39
0
def projectToVector(shape, vector):
    """projectToVector(shape,vector): projects the given shape on the given
    vector"""
    projpoints = []
    minl = 10000000000
    maxl = -10000000000
    for v in shape.Vertexes:
        p = DraftVecUtils.project(v.Point, vector)
        projpoints.append(p)
        l = p.Length
        if p.getAngle(vector) > 1:
            l = -l
        if l > maxl:
            maxl = l
        if l < minl:
            minl = l
    return DraftVecUtils.scaleTo(vector, maxl - minl)
예제 #40
0
 def onChanged(self,vobj,prop):
     if prop == "LineColor":
         l = vobj.LineColor
         self.mat1.diffuseColor.setValue([l[0],l[1],l[2]])
         self.mat2.diffuseColor.setValue([l[0],l[1],l[2]])
     elif prop == "Transparency":
         if hasattr(vobj,"Transparency"):
             self.mat2.transparency.setValue(vobj.Transparency/100.0)
     elif prop in ["DisplayLength","DisplayHeight","ArrowSize"]:
         if hasattr(vobj,"DisplayLength"):
             ld = vobj.DisplayLength.Value/2
             hd = vobj.DisplayHeight.Value/2
         elif hasattr(vobj,"DisplaySize"):
             # old objects
             ld = vobj.DisplaySize.Value/2
             hd = vobj.DisplaySize.Value/2
         else:
             ld = 1
             hd = 1
         verts = []
         fverts = []
         for v in [[-ld,-hd],[ld,-hd],[ld,hd],[-ld,hd]]:
             if hasattr(vobj,"ArrowSize"):
                 l1 = vobj.ArrowSize.Value if vobj.ArrowSize.Value > 0 else 0.1
             else:
                 l1 = 0.1
             l2 = l1/3
             pl = FreeCAD.Placement(vobj.Object.Placement)
             p1 = pl.multVec(Vector(v[0],v[1],0))
             p2 = pl.multVec(Vector(v[0],v[1],-l1))
             p3 = pl.multVec(Vector(v[0]-l2,v[1],-l1+l2))
             p4 = pl.multVec(Vector(v[0]+l2,v[1],-l1+l2))
             p5 = pl.multVec(Vector(v[0],v[1]-l2,-l1+l2))
             p6 = pl.multVec(Vector(v[0],v[1]+l2,-l1+l2))
             verts.extend([[p1.x,p1.y,p1.z],[p2.x,p2.y,p2.z]])
             fverts.append([p1.x,p1.y,p1.z])
             verts.extend([[p2.x,p2.y,p2.z],[p3.x,p3.y,p3.z],[p4.x,p4.y,p4.z],[p2.x,p2.y,p2.z]])
             verts.extend([[p2.x,p2.y,p2.z],[p5.x,p5.y,p5.z],[p6.x,p6.y,p6.z],[p2.x,p2.y,p2.z]])
         verts.extend(fverts+[fverts[0]])
         self.lcoords.point.setValues(verts)
         self.fcoords.point.setValues(fverts)
     elif prop == "LineWidth":
         self.drawstyle.lineWidth = vobj.LineWidth
     elif prop == "CutView":
         if hasattr(vobj,"CutView") and FreeCADGui.ActiveDocument.ActiveView:
             sg = FreeCADGui.ActiveDocument.ActiveView.getSceneGraph()
             if vobj.CutView:
                 if self.clip:
                     sg.removeChild(self.clip)
                     self.clip = None
                 for o in Draft.getGroupContents(vobj.Object.Objects,walls=True):
                     if hasattr(o.ViewObject,"Lighting"):
                         o.ViewObject.Lighting = "One side"
                 self.clip = coin.SoClipPlane()
                 self.clip.on.setValue(True)
                 norm = vobj.Object.Proxy.getNormal(vobj.Object)
                 mp = vobj.Object.Shape.CenterOfMass
                 mp = DraftVecUtils.project(mp,norm)
                 dist = mp.Length + 0.1 # to not clip exactly on the section object
                 norm = norm.negative()
                 plane = coin.SbPlane(coin.SbVec3f(norm.x,norm.y,norm.z),-dist)
                 self.clip.plane.setValue(plane)
                 sg.insertChild(self.clip,0)
             else:
                 if self.clip:
                     sg.removeChild(self.clip)
                     self.clip = None
     return
예제 #41
0
def getCutVolume(cutplane, shapes):
    """getCutVolume(cutplane,shapes): returns a cut face and a cut volume
    from the given shapes and the given cutting plane"""
    if not shapes:
        return None, None, None
    import Part

    if not isinstance(shapes, list):
        shapes = [shapes]
    # building boundbox
    bb = shapes[0].BoundBox
    for sh in shapes[1:]:
        bb.add(sh.BoundBox)
    bb.enlarge(1)
    # building cutplane space
    placement = None
    um = vm = wm = 0
    try:
        if hasattr(cutplane, "Shape"):
            p = cutplane.Shape.copy().Faces[0]
        else:
            p = cutplane.copy().Faces[0]
    except:
        FreeCAD.Console.PrintMessage(translate("Arch", "Invalid cutplane"))
        return None, None, None
    ce = p.CenterOfMass
    ax = p.normalAt(0, 0)
    u = p.Vertexes[1].Point.sub(p.Vertexes[0].Point).normalize()
    v = u.cross(ax)
    if not bb.isCutPlane(ce, ax):
        FreeCAD.Console.PrintMessage(translate("Arch", "No objects are cut by the plane"))
        return None, None, None
    else:
        corners = [
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMin),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMin),
            FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMin, bb.YMax, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMin, bb.ZMax),
            FreeCAD.Vector(bb.XMax, bb.YMax, bb.ZMax),
        ]
        for c in corners:
            dv = c.sub(ce)
            um1 = DraftVecUtils.project(dv, u).Length
            um = max(um, um1)
            vm1 = DraftVecUtils.project(dv, v).Length
            vm = max(vm, vm1)
            wm1 = DraftVecUtils.project(dv, ax).Length
            wm = max(wm, wm1)
        vu = DraftVecUtils.scaleTo(u, um)
        vui = vu.negative()
        vv = DraftVecUtils.scaleTo(v, vm)
        vvi = vv.negative()
        p1 = ce.add(vu.add(vvi))
        p2 = ce.add(vu.add(vv))
        p3 = ce.add(vui.add(vv))
        p4 = ce.add(vui.add(vvi))
        cutface = Part.makePolygon([p1, p2, p3, p4, p1])
        cutface = Part.Face(cutface)
        cutnormal = DraftVecUtils.scaleTo(ax, wm)
        cutvolume = cutface.extrude(cutnormal)
        cutnormal = cutnormal.negative()
        invcutvolume = cutface.extrude(cutnormal)
        return cutface, cutvolume, invcutvolume
예제 #42
0
    def constrain(self,point,basepoint=None,axis=None):
        '''constrain(point,basepoint=None,axis=None: Returns a
        constrained point. Axis can be "x","y" or "z" or a custom vector. If None,
        the closest working plane axis will be picked.
        Basepoint is the base point used to figure out from where the point
        must be constrained. If no basepoint is given, the current point is
        used as basepoint.'''

        # without the Draft module fully loaded, no axes system!"
        if not hasattr(FreeCAD,"DraftWorkingPlane"):
            return point

        point = Vector(point)

        # setup trackers if needed
        if not self.constrainLine:
            self.constrainLine = DraftTrackers.lineTracker(dotted=True)

        # setting basepoint
        if not basepoint:
            if not self.basepoint:
                self.basepoint = point
        else:
            self.basepoint = basepoint
        delta = point.sub(self.basepoint)

        # setting constraint axis
        if self.mask:
            self.affinity = self.mask
        if not self.affinity:
            self.affinity = FreeCAD.DraftWorkingPlane.getClosestAxis(delta)
        if isinstance(axis,FreeCAD.Vector):
            self.constraintAxis = axis
        elif axis == "x":
            self.constraintAxis = FreeCAD.DraftWorkingPlane.u
        elif axis == "y":
            self.constraintAxis = FreeCAD.DraftWorkingPlane.v
        elif axis == "z":
            self.constraintAxis = FreeCAD.DraftWorkingPlane.axis
        else:
            if self.affinity == "x":
                self.constraintAxis = FreeCAD.DraftWorkingPlane.u
            elif self.affinity == "y":
                self.constraintAxis = FreeCAD.DraftWorkingPlane.v
            else:
                self.constraintAxis = FreeCAD.DraftWorkingPlane.axis
                
        # calculating constrained point
        cdelta = DraftVecUtils.project(delta,self.constraintAxis)
        npoint = self.basepoint.add(cdelta)

        # setting constrain line
        if self.constrainLine:
            if point != npoint:
                self.constrainLine.p1(point)
                self.constrainLine.p2(npoint)
                self.constrainLine.on()
            else:
                self.constrainLine.off()
		
        return npoint       
예제 #43
0
 def getPerpendicular(self,edge,pt):
     "returns a point on an edge, perpendicular to the given point"
     dv = pt.sub(edge.Vertexes[0].Point)
     nv = DraftVecUtils.project(dv,DraftGeomUtils.vec(edge))
     np = (edge.Vertexes[0].Point).add(nv)
     return np
 def getSize(self):
     "returns (length,width) of the rectangle"
     p1 = Vector(self.coords.point.getValues()[0].getValue())
     p2 = Vector(self.coords.point.getValues()[2].getValue())
     diag = p2.sub(p1)
     return ((DraftVecUtils.project(diag,self.u)).Length,(DraftVecUtils.project(diag,self.v)).Length)
예제 #45
0
    def compare(self,face1,face2):
        "zsorts two faces. Returns 1 if face1 is closer, 2 if face2 is closer, 0 otherwise"

        #print face1,face2

        if not face1:
            if DEBUG: print "Warning, undefined face!" 
            return 31
        elif not face2:
            if DEBUG: print "Warning, undefined face!" 
            return 32

        # theory from
        # http://www.siggraph.org/education/materials/HyperGraph/scanline/visibility/painter.htm
        # and practical application http://vrm.ao2.it/ (blender vector renderer)

        b1 = face1[0].BoundBox
        b2 = face2[0].BoundBox

        # test 1: if faces don't overlap, no comparison possible
        if DEBUG: print "doing test 1"
        if b1.XMax < b2.XMin:
            return 0
        if b1.XMin > b2.XMax:
            return 0
        if b1.YMax < b2.YMin:
            return 0
        if b1.YMin > b2.YMax:
            return 0
        if DEBUG: print "failed, faces bboxes are not distinct"

        # test 2: if Z bounds dont overlap, it's easy to know the closest
        if DEBUG: print "doing test 2"
        if b1.ZMax < b2.ZMin:
            return 2
        if b2.ZMax < b1.ZMin:
            return 1
        if DEBUG: print "failed, faces Z are not distinct"

        # test 3: all verts of face1 are in front or behind the plane of face2
        if DEBUG: print "doing test 3"
        norm = face2[0].normalAt(0,0)
        behind = 0
        front = 0
        for v in face1[0].Vertexes:
            dv = v.Point.sub(face2[0].Vertexes[0].Point)
            dv = DraftVecUtils.project(dv,norm)
            if DraftVecUtils.isNull(dv):
                behind += 1
                front += 1
            else:
                if dv.getAngle(norm) > 1:
                    behind += 1
                else:
                    front += 1
        if DEBUG: print "front: ",front," behind: ",behind
        if behind == len(face1[0].Vertexes):
            return 2
        elif front == len(face1[0].Vertexes):
            return 1
        if DEBUG: print "failed, cannot say if face 1 is in front or behind"

        # test 4: all verts of face2 are in front or behind the plane of face1
        if DEBUG: print "doing test 4"
        norm = face1[0].normalAt(0,0)
        behind = 0
        front = 0
        for v in face2[0].Vertexes:
            dv = v.Point.sub(face1[0].Vertexes[0].Point)
            dv = DraftVecUtils.project(dv,norm)
            if DraftVecUtils.isNull(dv):
                behind += 1
                front += 1
            else:
                if dv.getAngle(norm) > 1:
                    behind += 1
                else:
                    front += 1
        if DEBUG: print "front: ",front," behind: ",behind
        if behind == len(face2[0].Vertexes):
            return 1
        elif front == len(face2[0].Vertexes):
            return 2
        if DEBUG: print "failed, cannot say if face 2 is in front or behind"

        # test 5: see if faces projections don't overlap, vertexwise
        if DEBUG: print "doing test 5"
        if not self.zOverlaps(face1,face2):
            return 0
        elif not self.zOverlaps(face2,face1):
            return 0
        if DEBUG: print "failed, faces are overlapping" 

        if DEBUG: print "Houston, all tests passed, and still no results" 
        return 0
예제 #46
0
    def cut(self,cutplane):
        "Cuts through the shapes with a given cut plane and builds section faces"
        if DEBUG: print "\n\n======> Starting cut\n\n"
        if self.iscut:
            return
        if not self.shapes:
            if DEBUG: print "No objects to make sections"
        else:
            fill = (1.0,1.0,1.0,1.0)
            placement = FreeCAD.Placement(cutplane.Placement)

            # building boundbox
            bb = self.shapes[0][0].BoundBox 
            for sh in self.shapes[1:]:
                bb.add(sh[0].BoundBox)
            bb.enlarge(1)
            um = vm = wm = 0
            if not bb.isCutPlane(placement.Base,self.wp.axis):
                if DEBUG: print "No objects are cut by the plane"
            else:
                corners = [FreeCAD.Vector(bb.XMin,bb.YMin,bb.ZMin),
                           FreeCAD.Vector(bb.XMin,bb.YMax,bb.ZMin),
                           FreeCAD.Vector(bb.XMax,bb.YMin,bb.ZMin),
                           FreeCAD.Vector(bb.XMax,bb.YMax,bb.ZMin),
                           FreeCAD.Vector(bb.XMin,bb.YMin,bb.ZMax),
                           FreeCAD.Vector(bb.XMin,bb.YMax,bb.ZMax),
                           FreeCAD.Vector(bb.XMax,bb.YMin,bb.ZMax),
                           FreeCAD.Vector(bb.XMax,bb.YMax,bb.ZMax)]
                for c in corners:
                    dv = c.sub(placement.Base)
                    um1 = DraftVecUtils.project(dv,self.wp.u).Length
                    um = max(um,um1)
                    vm1 = DraftVecUtils.project(dv,self.wp.v).Length
                    vm = max(vm,vm1)
                    wm1 = DraftVecUtils.project(dv,self.wp.axis).Length
                    wm = max(wm,wm1)
                p1 = FreeCAD.Vector(-um,vm,0)
                p2 = FreeCAD.Vector(um,vm,0)
                p3 = FreeCAD.Vector(um,-vm,0)
                p4 = FreeCAD.Vector(-um,-vm,0)
                cutface = Part.makePolygon([p1,p2,p3,p4,p1])
                cutface = Part.Face(cutface)
                cutface.Placement = placement
                cutnormal = DraftVecUtils.scaleTo(self.wp.axis,wm)
                cutvolume = cutface.extrude(cutnormal)
                shapes = []
                faces = []
                sections = []
                for sh in self.shapes:
                    for sol in sh[0].Solids:
                        c = sol.cut(cutvolume)
                        shapes.append([c]+sh[1:])
                        for f in c.Faces:
                            faces.append([f]+sh[1:])
                            print "iscoplanar:",f.Vertexes[0].Point,f.normalAt(0,0),cutface.Vertexes[0].Point,cutface.normalAt(0,0)
                            if DraftGeomUtils.isCoplanar([f,cutface]):
                                print "COPLANAR"
                                sections.append([f,fill])
                self.shapes = shapes
                self.faces = faces
                self.sections = sections
                if DEBUG: print "Built ",len(self.sections)," sections, ", len(self.faces), " faces retained"
                self.iscut = True
                self.oriented = False
                self.trimmed = False
                self.sorted = False
                self.joined = False
        if DEBUG: print "\n\n======> Finished cut\n\n"