Exemple #1
0
 def update(self,point):
     "sets the opposite (diagonal) point of the rectangle"
     diagonal = point.sub(self.origin)
     inpoint1 = self.origin.add(fcvec.project(diagonal,self.v))
     inpoint2 = self.origin.add(fcvec.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 getProj(self, vec, plane):
     "returns a vector in working plane space from the given vector"
     if not plane:
         return vec
     nx = fcvec.project(vec, plane.u)
     lx = nx.Length
     if abs(nx.getAngle(plane.u)) > 0.1: lx = -lx
     ny = fcvec.project(vec, plane.v)
     ly = ny.Length
     if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly
     return Vector(lx, ly, 0)
Exemple #3
0
 def getLocalCoords(self, point):
     "returns the coordinates of a given point on the working plane"
     xv = fcvec.project(point, self.u)
     x = xv.Length
     if xv.getAngle(self.u) > 1:
         x = -x
     yv = fcvec.project(point, self.v)
     y = yv.Length
     if yv.getAngle(self.v) > 1:
         y = -y
     zv = fcvec.project(point, self.axis)
     z = zv.Length
     if zv.getAngle(self.axis) > 1:
         z = -z
     return Vector(x, y, z)
Exemple #4
0
 def getLocalCoords(self,point):
         "returns the coordinates of a given point on the working plane"
         xv = fcvec.project(point,self.u)
         x = xv.Length
         if xv.getAngle(self.u) > 1:
                 x = -x
         yv = fcvec.project(point,self.v)
         y = yv.Length
         if yv.getAngle(self.v) > 1:
                 y = -y
         zv = fcvec.project(point,self.axis)
         z = zv.Length
         if zv.getAngle(self.axis) > 1:
                 z = -z
         return Vector(x,y,z)
Exemple #5
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 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 = fcvec.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       
Exemple #6
0
 def getClosestNode(self,point):
     "returns the closest node from the given point"
     # get the 2D coords.
     point = FreeCAD.DraftWorkingPlane.projectPoint(point)
     u = fcvec.project(point,FreeCAD.DraftWorkingPlane.u)
     lu = u.Length
     if u.getAngle(FreeCAD.DraftWorkingPlane.u) > 1.5:
         lu  = -lu
     v = fcvec.project(point,FreeCAD.DraftWorkingPlane.v)
     lv = v.Length
     if v.getAngle(FreeCAD.DraftWorkingPlane.v) > 1.5:
         lv = -lv
     # print "u = ",u," v = ",v
     # find nearest grid node
     pu = (round(lu/self.space,0))*self.space
     pv = (round(lv/self.space,0))*self.space
     rot = FreeCAD.Rotation()
     rot.Q = self.trans.rotation.getValue().getValue()
     return rot.multVec(Vector(pu,pv,0))
 def intersection(p1, p2, p3, p4):
     "returns the intersection of line (p1,p2) with plane (p3,p4)"
     # http://paulbourke.net/geometry/planeline/
     dn = p4.dot(p2.sub(p1))
     if dn != 0:
         u = (p4.dot(p3.sub(p1))) / dn
         p = p1.add((p2.sub(p1)).scale(u, u, u))
         return p
     else:
         # line is parallel to normal
         vp = fcvec.project(p3.sub(p1), p2.sub(p1))
         l = vp.Length
         if vp.getAngle(p2.sub(p1)) > 1:
             l = -l
         return fcvec.scaleTo(p2.sub(p1), l)
Exemple #8
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 = fcvec.project(dv,fcgeo.vec(edge))
     np = (edge.Vertexes[0].Point).add(nv)
     return np
Exemple #9
0
    def sortFaces(self, face1, face2):
        "zsorts two faces. Returns 1 if face1 is closer, 2 if face2 is closer, 0 otherwise"

        # 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.BoundBox
        b2 = face2.BoundBox

        if DEBUG:
            print "comparing face1: normal ", face1.normalAt(
                0, 0), " with face2: normal ", face2.normalAt(0, 0)

        # 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 "passed, faces are overlapping"

        # 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 "passed, faces Z are crossed"

        # test 3: all verts of face1 are behind the plane of face2
        if DEBUG: print "doing test 3"
        norm = face2.normalAt(0, 0)
        behind = 0
        for v in face1.Vertexes:
            dv = v.Point.sub(face2.Vertexes[0].Point)
            dv = fcvec.project(dv, norm)
            if dv.Length:
                if dv.getAngle(norm) > 0.1:
                    behind += 1
        if behind == len(face1.Vertexes):
            return 2
        if DEBUG: print "passed, face 1 is not behind"

        # test 4: all verts of face2 are in front of the plane of face1
        if DEBUG: print "doing test 4"
        norm = face1.normalAt(0, 0)
        front = 0
        for v in face2.Vertexes:
            dv = v.Point.sub(face1.Vertexes[0].Point)
            dv = fcvec.project(dv, norm)
            if dv.Length:
                if dv.getAngle(norm) < 0.1:
                    front += 1
        if front == len(face2.Vertexes):
            return 2
        if DEBUG: print "passed, face 2 is not in front"

        # 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 "passed, faces are overlapping"

        if DEBUG: print "Houston, all tests passed, and still no results"
        return 0
Exemple #10
0
    def compare(self,face1,face2):
        "zsorts two faces. Returns 1 if face1 is closer, 2 if face2 is closer, 0 otherwise"

        # 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 = fcvec.project(dv,norm)
            if fcvec.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 = fcvec.project(dv,norm)
            if fcvec.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
Exemple #11
0
    def cut(self,cutplane):
        "Cuts through the shapes with a given cut plane and builds section faces"
        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 = fcvec.project(dv,self.wp.u).Length
                    um = max(um,um1)
                    vm1 = fcvec.project(dv,self.wp.v).Length
                    vm = max(vm,vm1)
                    wm1 = fcvec.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 = fcvec.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:])
                        sec = sol.section(cutface)
                        if sec.Edges:
                            wires = fcgeo.findWires(sec.Edges)
                            for w in wires:
                                sec = Part.Face(w)
                                sections.append([sec,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
Exemple #12
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 ((fcvec.project(diag,self.u)).Length,(fcvec.project(diag,self.v)).Length)