示例#1
0
    def backSmaller(self, i):
        import DraftGeomUtils

        profilCurrent = self.findProfil(i)
        profilBack1 = self.findProfil(i - 1)
        dec = profilBack1["height"] / math.tan(math.radians(profilCurrent["angle"]))
        edgeRidgeOnPane = DraftGeomUtils.offset(
            profilCurrent["edge"], self.getPerpendicular(profilCurrent["vec"], profilCurrent["rot"], dec)
        )
        ptInter1 = DraftGeomUtils.findIntersection(
            edgeRidgeOnPane, profilBack1["ridge"], infinite1=True, infinite2=True
        )
        edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]), profilCurrent["edge"].Vertexes[0].Point)
        ptInter2 = edgeHip.Vertexes[0].Point
        vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [profilCurrent["ridge"].Edges[0]], force=0)
        ptInterRidges = ptInter2.add(vecInterRidges[0])
        self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
        self.ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
        ptInterHipEave = DraftGeomUtils.findIntersection(
            edgeHip, profilCurrent["eave"], infinite1=True, infinite2=False
        )
        if ptInterHipEave:
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
        else:
            ptInterHipEave = DraftGeomUtils.findIntersection(
                edgeHip, profilBack1["eaveD"], infinite1=True, infinite2=True
            )
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
            self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[0].Point[0]))
示例#2
0
    def nextHigher(self, i):
        import DraftGeomUtils

        profilCurrent = self.findProfil(i)
        profilNext1 = self.findProfil(i + 1)
        dec = profilCurrent["height"] / math.tan(math.radians(profilNext1["angle"]))
        edgeRidgeOnPane = DraftGeomUtils.offset(
            profilNext1["edge"], self.getPerpendicular(profilNext1["vec"], profilNext1["rot"], dec)
        )
        ptInter = DraftGeomUtils.findIntersection(
            profilCurrent["ridge"], edgeRidgeOnPane, infinite1=True, infinite2=True
        )
        edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter[0]), profilCurrent["edge"].Vertexes[-1].Point)
        ptInterHipEave = DraftGeomUtils.findIntersection(
            edgeHip, profilCurrent["eave"], infinite1=True, infinite2=False
        )
        if ptInterHipEave:
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
        else:
            ptInterHipEave = DraftGeomUtils.findIntersection(
                edgeHip, profilNext1["eaveD"], infinite1=True, infinite2=True
            )
            self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point[0]))
            self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
        self.ptsPaneProject.append(FreeCAD.Vector(ptInter[0]))
        ptInterRidges = DraftGeomUtils.findIntersection(
            profilCurrent["ridge"], profilNext1["ridge"], infinite1=True, infinite2=True
        )
        self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
示例#3
0
    def calcEave(self, i):

        import DraftGeomUtils
        pt0Eave1 = DraftGeomUtils.findIntersection(self.findProfil(i-1)["eaveD"],self.findProfil(i)["eaveD"],infinite1=True,infinite2=True,)
        pt1Eave1 = DraftGeomUtils.findIntersection(self.findProfil(i)["eaveD"],self.findProfil(i+1)["eaveD"],infinite1=True,infinite2=True,)
        eave = DraftGeomUtils.edg(FreeCAD.Vector(pt0Eave1[0]),FreeCAD.Vector(pt1Eave1[0]))
        self.profilsDico[i]["eave"] = eave
示例#4
0
文件: ArchRoof.py 项目: 5263/FreeCAD
 def nextSmaller(self, i):
     print("Next : ht2 < ht1")
     profilCurrent = self.findProfil(i)
     profilNext1 = self.findProfil(i+1)
     dec = profilNext1["height"]/math.tan(math.radians(profilCurrent["angle"]))
     edgeRidgeOnPane = DraftGeomUtils.offset(profilCurrent["edge"],self.getPerpendicular(profilCurrent["vec"],profilCurrent["rot"],dec))
     ptInter = DraftGeomUtils.findIntersection(profilNext1["ridge"],edgeRidgeOnPane,infinite1=True,infinite2=True,)
     edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter[0]),profilCurrent["edge"].Vertexes[-1].Point)
     ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilCurrent["eave"],infinite1=True,infinite2=False,)
     if ptInterHipEave:
         print "a ",FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     else:
         ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilNext1["eaveD"],infinite1=True,infinite2=True,)
         print "b ",FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point[0])
         print "c ",FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point[0]))
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     print "d ",FreeCAD.Vector(ptInter[0])
     self.ptsPaneProject.append(FreeCAD.Vector(ptInter[0]))
     ptInter = edgeHip.Vertexes[0].Point
     vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter, [profilCurrent["ridge"].Edges[0],], force=0)
     ptInterRidges = ptInter.add(vecInterRidges[0])
     print "e ",FreeCAD.Vector(ptInterRidges)
     self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
示例#5
0
 def backSameHeight(self, i):
     import DraftGeomUtils
     profilCurrent = self.findProfil(i)
     profilBack1 = self.findProfil(i-1)
     ptInterRidges = DraftGeomUtils.findIntersection(profilCurrent["ridge"],profilBack1["ridge"],infinite1=True,infinite2=True,)
     self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
     edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),profilCurrent["edge"].Vertexes[0].Point)
     ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilCurrent["eave"],infinite1=True,infinite2=False,)
     if ptInterHipEave:
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     else:
         ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilBack1["eaveD"],infinite1=True,infinite2=True,)
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
         self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[0].Point))
示例#6
0
 def findPivotIntersection(self, pivot, pivotEdge, edge, refPt, d, color):
     debugPrint(
         "Intersection (%.2f, %.2f)^%.2f  - [(%.2f, %.2f), (%.2f, %.2f)]"
         % (
             pivotEdge.Curve.Center.x,
             pivotEdge.Curve.Center.y,
             pivotEdge.Curve.Radius,
             edge.Vertexes[0].Point.x,
             edge.Vertexes[0].Point.y,
             edge.Vertexes[1].Point.x,
             edge.Vertexes[1].Point.y,
         )
     )
     ppt = None
     pptDistance = 0
     for pt in DraftGeomUtils.findIntersection(edge, pivotEdge, dts=False):
         # debugMarker(pt, "pti.%d-%s.in" % (self.boneId, d), color, 0.2)
         distance = (pt - refPt).Length
         debugPrint("        -->  (%.2f, %.2f): %.2f" % (pt.x, pt.y, distance))
         if not ppt or pptDistance < distance:
             ppt = pt
             pptDistance = distance
     if not ppt:
         tangent = DraftGeomUtils.findDistance(pivot, edge)
         if tangent:
             debugPrint("Taking tangent as intersect %s" % tangent)
             ppt = pivot + tangent
         else:
             debugPrint("Taking chord start as intersect %s" % inChordStart)
             ppt = inChord.Start
         # debugMarker(ppt, "ptt.%d-%s.in" % (self.boneId, d), color, 0.2)
         debugPrint("        -->  (%.2f, %.2f)" % (ppt.x, ppt.y))
     return ppt
示例#7
0
def intersectionCLines(thing1=None, thing2=None):
  '''
  intersectionCLines(thing1=None, thing2=None)
  Returns the intersection (vector) of the center lines of thing1 and thing2.
  Things can be any combination of intersecting beams, pipes or edges.
  If less than 2 arguments are given, thing1 and thing2 are the first 2 beams
  or pipes found in the selection set.
  '''
  if not (thing1 and thing2):
    try:
      thing1,thing2=beams()[:2]
    except:
      FreeCAD.Console.PrintError('Insufficient arguments for intersectionCLines\n')
      return None
  edges=[]
  for thing in [thing1,thing2]:
    if beams([thing]):
      edges.append(vec2edge(thing.Placement.Base,beamAx(thing)))
    elif hasattr(thing,'ShapeType') and thing.ShapeType=='Edge':
      edges.append(thing)
  intersections=dgu.findIntersection(*edges, infinite1=True, infinite2=True)
  if len(intersections):
    return rounded(intersections[0])
  else:
    FreeCAD.Console.PrintError('No intersection found\n')
    return None
示例#8
0
 def connectNodes(self,other=None):
     if not other:
         self.observer = StructSelectionObserver(self.connectNodes)
         FreeCADGui.Selection.addObserver(self.observer)
         FreeCAD.Console.PrintMessage(translate("Arch","Pick another Structure object: "))
     else:
         FreeCADGui.Selection.removeObserver(self.observer)
         self.observer = None
         if Draft.getType(other) != "Structure":
             FreeCAD.Console.PrintError(translate("Arch","The picked object is not a Structure\n"))
         else:
             if not other.Nodes:
                 FreeCAD.Console.PrintError(translate("Arch","The picked object has no structural nodes\n"))
             else:
                 if (len(self.Object.Nodes) != 2) or (len(other.Nodes) != 2):
                     FreeCAD.Console.PrintError(translate("Arch","One of these objects has more than 2 nodes\n"))
                 else:
                     import DraftGeomUtils
                     nodes1 = [self.Object.Placement.multVec(v) for v in self.Object.Nodes]
                     nodes2 = [other.Placement.multVec(v) for v in other.Nodes]
                     intersect = DraftGeomUtils.findIntersection(nodes1[0],nodes1[1],nodes2[0],nodes2[1],True,True)
                     if not intersect:
                         FreeCAD.Console.PrintError(translate("Arch","Unable to find a suitable intersection point\n"))
                     else:
                         intersect = intersect[0]
                         FreeCAD.Console.PrintMessage(translate("Arch","Intersection found.\n"))
                         if DraftGeomUtils.findClosest(intersect,nodes1) == 0:
                             self.Object.Nodes = [self.Object.Placement.inverse().multVec(intersect),self.Object.Nodes[1]]
                         else:
                             self.Object.Nodes = [self.Object.Nodes[0],self.Object.Placement.inverse().multVec(intersect)]
                         if DraftGeomUtils.findClosest(intersect,nodes2) == 0:
                             other.Nodes = [other.Placement.inverse().multVec(intersect),other.Nodes[1]]
                         else:
                             other.Nodes = [other.Nodes[0],other.Placement.inverse().multVec(intersect)]
示例#9
0
 def getAxisPoints(self,obj):
     "returns the gridpoints of linked axes"
     import DraftGeomUtils
     pts = []
     if len(obj.Axes) == 1:
         if hasattr(obj,"Align"):
             if obj.Align == True :
                 p0 = obj.Axes[0].Shape.Edges[0].Vertexes[1].Point
                 for e in obj.Axes[0].Shape.Edges:
                     p = e.Vertexes[1].Point
                     p = p.sub(p0)
                     pts.append(p)
             else:
                 for e in obj.Axes[0].Shape.Edges:
                     pts.append(e.Vertexes[0].Point)
         else:
             for e in obj.Axes[0].Shape.Edges:
                     pts.append(e.Vertexes[0].Point)
     elif len(obj.Axes) >= 2:
         set1 = obj.Axes[0].Shape.Edges
         set2 = obj.Axes[1].Shape.Edges
         for e1 in set1:
             for e2 in set2:
                 pts.extend(DraftGeomUtils.findIntersection(e1,e2))
     return pts
示例#10
0
文件: ArchRoof.py 项目: 5263/FreeCAD
 def nextSameHeight(self, i):
     print("Next : ht1 = ht2")
     profilCurrent = self.findProfil(i)
     profilNext1 = self.findProfil(i+1)
     ptInterRidges = DraftGeomUtils.findIntersection(profilCurrent["ridge"],profilNext1["ridge"],infinite1=True,infinite2=True,)
     edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),profilCurrent["edge"].Vertexes[-1].Point)
     ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilCurrent["eave"],infinite1=True,infinite2=False,)
     if ptInterHipEave:
         print "a ",FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     else:
         ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilNext1["eaveD"],infinite1=True,infinite2=True,)
         print "b ",FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point)
         print "c ",FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[-1].Point))
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     print "d ",FreeCAD.Vector(ptInterRidges[0])
     self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
示例#11
0
 def snapToElines(self,e1,e2):
     "returns a snap location at the infinite intersection of the given edges"
     snaps = []
     if self.isEnabled("intersection") and self.isEnabled("extension"):
         if e1 and e2:
             # get the intersection points
             pts = DraftGeomUtils.findIntersection(e1,e2,True,True)
             if pts:
                 for p in pts:
                     snaps.append([p,'intersection',p])
     return snaps
示例#12
0
文件: ArchRoof.py 项目: 5263/FreeCAD
 def backHigher(self, i):
     print("Back : ht1 < ht0")
     profilCurrent = self.findProfil(i)
     profilBack1 = self.findProfil(i-1)
     dec = profilCurrent["height"]/math.tan(math.radians(profilBack1["angle"]))
     edgeRidgeOnPane = DraftGeomUtils.offset(profilBack1["edge"],self.getPerpendicular(profilBack1["vec"],profilBack1["rot"],dec))
     ptInterRidges = DraftGeomUtils.findIntersection(edgeRidgeOnPane,profilCurrent["ridge"],infinite1=True,infinite2=True,)
     print "a ",FreeCAD.Vector(ptInterRidges[0])
     self.ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
     edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),profilCurrent["edge"].Vertexes[0].Point)
     ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilCurrent["eave"],infinite1=True,infinite2=False,)
     if ptInterHipEave:
         print "b ",FreeCAD.Vector(ptInterHipEave[0])
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
     else:
         ptInterHipEave = DraftGeomUtils.findIntersection(edgeHip,profilBack1["eaveD"],infinite1=True,infinite2=True,)
         print "c ",FreeCAD.Vector(ptInterHipEave[0])
         print "d ",FreeCAD.Vector(profilCurrent["eave"].Vertexes[0].Point[0])
         self.ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave[0]))
         self.ptsPaneProject.append(FreeCAD.Vector(profilCurrent["eave"].Vertexes[0].Point[0]))
示例#13
0
 def snapToExtOrtho(self,last,constrain,eline):
     "returns an ortho X extension snap location"
     if self.isEnabled("extension") and self.isEnabled("ortho"):
         if constrain and last and self.constraintAxis and self.extLine:
             tmpEdge1 = Part.Line(last,last.add(self.constraintAxis)).toShape()
             tmpEdge2 = Part.Line(self.extLine.p1(),self.extLine.p2()).toShape()
             # get the intersection points
             pt = DraftGeomUtils.findIntersection(tmpEdge1,tmpEdge2,True,True)
             if pt:
                 return [pt[0],'ortho',pt[0]]
         if eline:
             try:
                 tmpEdge2 = Part.Line(self.extLine.p1(),self.extLine.p2()).toShape()
                 # get the intersection points
                 pt = DraftGeomUtils.findIntersection(eline,tmpEdge2,True,True)
                 if pt:
                     return [pt[0],'ortho',pt[0]]
             except:
                 return None
     return None
示例#14
0
文件: trmi.py 项目: eason2/trim
def findInterPoint(edge1,edge2): # give two edges and then return the inter_point
    pt1a = edge1.Vertex1.Point
    pt1b = edge1.Vertex2.Point
    pt2a = edge2.Vertex1.Point
    pt2b = edge2.Vertex2.Point
    nor1 = pt1a.sub(pt1b).normalize()
    nor2 = pt2a.sub(pt2b).normalize()
    line1 = Part.makeLine(pt1a+nor1*1000,pt1a+nor1*-1000)
    line2 = Part.makeLine(pt2a+nor2*1000,pt2a+nor2*-1000)
    p=DraftGeomUtils.findIntersection(line1,line2)
    if p: return(p[0])
    return(prf('cen not find the inter point!'))
示例#15
0
文件: ArchRoof.py 项目: 5263/FreeCAD
 def nextPignon(self, i):
     print("Next : pignon")
     profilCurrent = self.findProfil(i)
     profilNext1 = self.findProfil(i+1)
     profilNext2 = self.findProfil(i+2)
     point = DraftGeomUtils.findIntersection(profilCurrent["eave"],profilNext1["eave"],infinite1=True,infinite2=True,)
     print "a ",FreeCAD.Vector(point[0])
     self.ptsPaneProject.append(FreeCAD.Vector(point[0]))
     pt1 = DraftGeomUtils.findIntersection(profilCurrent["edge"],profilNext1["eave"],infinite1=True,infinite2=True,)
     pt2 = DraftGeomUtils.findIntersection(profilNext2["edge"],profilNext1["eave"],infinite1=True,infinite2=True,)
     eaveWithoutOverhang = DraftGeomUtils.edg(pt1[0],pt2[0])
     if profilCurrent["run"]+profilNext2["run"] != eaveWithoutOverhang.Length :
         points = [FreeCAD.Vector(0.0,0.0,0.0),]
         points.append(FreeCAD.Vector(profilCurrent["run"],profilCurrent["height"],0.0))
         rampantCurrent = DraftGeomUtils.edg(points[0],points[1])
         points = [FreeCAD.Vector(eaveWithoutOverhang.Length,0.0,0.0),]
         points.append(FreeCAD.Vector(eaveWithoutOverhang.Length-profilNext2["run"],profilNext2["height"],0.0))
         rampantNext2 = DraftGeomUtils.edg(points[0],points[1])
         point = DraftGeomUtils.findIntersection(rampantCurrent,rampantNext2,infinite1=True,infinite2=True,)
         ridgeCurrent = DraftGeomUtils.offset(profilCurrent["edge"],self.getPerpendicular(profilCurrent["vec"],profilCurrent["rot"],point[0].x))
         point = DraftGeomUtils.findIntersection(ridgeCurrent,profilNext1["eave"],infinite1=True,infinite2=True,)
     else:
         point = DraftGeomUtils.findIntersection(profilCurrent["ridge"],profilNext1["eaveD"],infinite1=True,infinite2=True,)
     print "b ",FreeCAD.Vector(point[0])
     self.ptsPaneProject.append(FreeCAD.Vector(point[0]))
示例#16
0
    def backPignon(self, i):
        import DraftGeomUtils

        profilCurrent = self.findProfil(i)
        profilBack1 = self.findProfil(i - 1)
        profilBack2 = self.findProfil(i - 2)
        pt1 = DraftGeomUtils.findIntersection(
            profilCurrent["edge"], profilBack1["eave"], infinite1=True, infinite2=True
        )
        pt2 = DraftGeomUtils.findIntersection(profilBack2["edge"], profilBack1["eave"], infinite1=True, infinite2=True)
        eaveWithoutOverhang = DraftGeomUtils.edg(pt1[0], pt2[0])
        if profilCurrent["run"] + profilBack2["run"] != eaveWithoutOverhang.Length:
            points = [FreeCAD.Vector(0.0, 0.0, 0.0)]
            points.append(FreeCAD.Vector(profilCurrent["run"], profilCurrent["height"], 0.0))
            rampantCurrent = DraftGeomUtils.edg(points[0], points[1])
            points = [FreeCAD.Vector(eaveWithoutOverhang.Length, 0.0, 0.0)]
            points.append(FreeCAD.Vector(eaveWithoutOverhang.Length - profilBack2["run"], profilBack2["height"], 0.0))
            rampantBack2 = DraftGeomUtils.edg(points[0], points[1])
            point = DraftGeomUtils.findIntersection(rampantCurrent, rampantBack2, infinite1=True, infinite2=True)
            ridgeCurrent = DraftGeomUtils.offset(
                profilCurrent["edge"], self.getPerpendicular(profilCurrent["vec"], profilCurrent["rot"], point[0].x)
            )
            point = DraftGeomUtils.findIntersection(ridgeCurrent, profilBack1["eave"], infinite1=True, infinite2=True)
        else:
            point = DraftGeomUtils.findIntersection(
                profilCurrent["ridge"], profilBack1["eave"], infinite1=True, infinite2=True
            )
        self.ptsPaneProject.append(FreeCAD.Vector(point[0]))
        point = DraftGeomUtils.findIntersection(
            profilCurrent["eave"], profilBack1["eave"], infinite1=True, infinite2=True
        )
        self.ptsPaneProject.append(FreeCAD.Vector(point[0]))
示例#17
0
 def getAxisPoints(self,obj):
     "returns the gridpoints of linked axes"
     import DraftGeomUtils
     pts = []
     if len(obj.Axes) == 1:
         for e in obj.Axes[0].Shape.Edges:
             pts.append(e.Vertexes[0].Point)
     elif len(obj.Axes) >= 2:
         set1 = obj.Axes[0].Shape.Edges
         set2 = obj.Axes[1].Shape.Edges
         for e1 in set1:
             for e2 in set2: 
                 pts.extend(DraftGeomUtils.findIntersection(e1,e2))
     return pts
示例#18
0
    def zOverlaps(self,face1,face2):
        "Checks if face1 overlaps face2 in Z direction"
        face1 = self.flattenFace(face1)
        face2 = self.flattenFace(face2)
        
        # first we check if one of the verts is inside the other face
        for v in face1[0].Vertexes:
            if self.isInside(v,face2):
                return True

        # even so, faces can still overlap if their edges cross each other
        for e1 in face1[0].Edges:
            for e2 in face2[0].Edges:
                if DraftGeomUtils.findIntersection(e1,e2):
                    return True
        return False
示例#19
0
 def snapToOrtho(self,shape,last,constrain):
     "returns a list of ortho snap locations"
     snaps = []
     if self.isEnabled("ortho"):
         if constrain:
             if isinstance(shape,Part.Edge):
                 if last:
                     if DraftGeomUtils(shape) == "Line":
                         if self.constraintAxis:
                             tmpEdge = Part.Line(last,last.add(self.constraintAxis)).toShape()
                             # get the intersection points
                             pt = DraftGeomUtils.findIntersection(tmpEdge,shape,True,True)
                             if pt:
                                 for p in pt:
                                     snaps.append([p,'ortho',p])
     return snaps
示例#20
0
 def snapToIntersection(self,shape):
     "returns a list of intersection snap locations"
     snaps = []
     if self.isEnabled("intersection"):
         # get the stored objects to calculate intersections
         if self.lastObj[0]:
             obj = FreeCAD.ActiveDocument.getObject(self.lastObj[0])
             if obj:
                 if obj.isDerivedFrom("Part::Feature"):
                     if (not self.maxEdges) or (len(obj.Shape.Edges) <= self.maxEdges):
                         for e in obj.Shape.Edges:
                             # get the intersection points
                             pt = DraftGeomUtils.findIntersection(e,shape)
                             if pt:
                                 for p in pt:
                                     snaps.append([p,'intersection',p])
     return snaps
示例#21
0
    def removePathCrossing(self, commands, bone1, bone2):
        commands.append(bone2.lastCommand)
        bones = bone2.commands
        if True and hasattr(bone1, "outCommands") and hasattr(bone2, "inCommands"):
            inEdges = edgesForCommands(bone1.outCommands, bone1.tip)
            outEdges = edgesForCommands(bone2.inCommands,  bone2.inChord.Start)
            for i in range(len(inEdges)):
                e1 = inEdges[i]
                for j in range(len(outEdges)-1, -1, -1):
                    e2 = outEdges[j]
                    cutoff = DraftGeomUtils.findIntersection(e1, e2)
                    for pt in cutoff:
                        # debugCircle(e1.Curve.Center, e1.Curve.Radius, "bone.%d-1" % (self.boneId), (1.,0.,0.))
                        # debugCircle(e2.Curve.Center, e2.Curve.Radius, "bone.%d-2" % (self.boneId), (0.,1.,0.))
                        if PathGeom.pointsCoincide(pt, e1.valueAt(e1.LastParameter)) or PathGeom.pointsCoincide(pt, e2.valueAt(e2.FirstParameter)):
                            continue
                        # debugMarker(pt, "it", (0.0, 1.0, 1.0))
                        # 1. remove all redundant commands
                        commands = commands[:-(len(inEdges) - i)]
                        # 2., correct where c1 ends
                        c1 = bone1.outCommands[i]
                        c1Params = c1.Parameters
                        c1Params.update({'X': pt.x, 'Y': pt.y, 'Z': pt.z})
                        c1 = Path.Command(c1.Name, c1Params)
                        commands.append(c1)
                        # 3. change where c2 starts, this depends on the command itself
                        c2 = bone2.inCommands[j]
                        if c2.Name in movearc:
                            center = e2.Curve.Center
                            offset = center - pt
                            c2Params = c2.Parameters
                            c2Params.update({'I': offset.x, 'J': offset.y, 'K': offset.z})
                            c2 = Path.Command(c2.Name, c2Params)
                            bones = [c2]
                            bones.extend(bone2.commands[j+1:])
                        else:
                            bones = bone2.commands[j:]
                        # there can only be the one ...
                        return commands, bones

        return commands, bones
示例#22
0
 def backPignon(self, i):
     import DraftGeomUtils
     profilCurrent = self.findProfil(i)
     profilBack1 = self.findProfil(i - 1)
     profilBack2 = self.findProfil(i - 2)
     pt1 = DraftGeomUtils.findIntersection(
         profilCurrent["edge"],
         profilBack1["eave"],
         infinite1=True,
         infinite2=True,
     )
     pt2 = DraftGeomUtils.findIntersection(
         profilBack2["edge"],
         profilBack1["eave"],
         infinite1=True,
         infinite2=True,
     )
     eaveWithoutOverhang = DraftGeomUtils.edg(pt1[0], pt2[0])
     if profilCurrent["run"] + profilBack2[
             "run"] != eaveWithoutOverhang.Length:
         points = [
             FreeCAD.Vector(0.0, 0.0, 0.0),
         ]
         points.append(
             FreeCAD.Vector(profilCurrent["run"], profilCurrent["height"],
                            0.0))
         rampantCurrent = DraftGeomUtils.edg(points[0], points[1])
         points = [
             FreeCAD.Vector(eaveWithoutOverhang.Length, 0.0, 0.0),
         ]
         points.append(
             FreeCAD.Vector(eaveWithoutOverhang.Length - profilBack2["run"],
                            profilBack2["height"], 0.0))
         rampantBack2 = DraftGeomUtils.edg(points[0], points[1])
         point = DraftGeomUtils.findIntersection(
             rampantCurrent,
             rampantBack2,
             infinite1=True,
             infinite2=True,
         )
         ridgeCurrent = DraftGeomUtils.offset(
             profilCurrent["edge"],
             self.getPerpendicular(profilCurrent["vec"],
                                   profilCurrent["rot"], point[0].x))
         point = DraftGeomUtils.findIntersection(
             ridgeCurrent,
             profilBack1["eave"],
             infinite1=True,
             infinite2=True,
         )
     else:
         point = DraftGeomUtils.findIntersection(
             profilCurrent["ridge"],
             profilBack1["eave"],
             infinite1=True,
             infinite2=True,
         )
     self.ptsPaneProject.append(FreeCAD.Vector(point[0]))
     point = DraftGeomUtils.findIntersection(
         profilCurrent["eave"],
         profilBack1["eave"],
         infinite1=True,
         infinite2=True,
     )
     self.ptsPaneProject.append(FreeCAD.Vector(point[0]))
示例#23
0
    def smoothChordCommands(self, bone, inChord, outChord, edge, wire, corner, smooth, color=None):
        if smooth == 0:
            PathLog.info(" No smoothing requested")
            return [bone.lastCommand, outChord.g1Command(bone.F)]

        d = 'in'
        refPoint = inChord.Start
        if smooth == Smooth.Out:
            d = 'out'
            refPoint = outChord.End

        if DraftGeomUtils.areColinear(inChord.asEdge(), outChord.asEdge()):
            PathLog.info(" straight edge %s" % d)
            return [outChord.g1Command(bone.F)]

        pivot = None
        pivotDistance = 0

        PathLog.info("smooth:  (%.2f, %.2f)-(%.2f, %.2f)" % (edge.Vertexes[0].Point.x, edge.Vertexes[0].Point.y, edge.Vertexes[1].Point.x, edge.Vertexes[1].Point.y))
        for e in wire.Edges:
            self.dbg.append(e)
            if type(e.Curve) == Part.LineSegment or type(e.Curve) == Part.Line:
                PathLog.debug("         (%.2f, %.2f)-(%.2f, %.2f)" % (e.Vertexes[0].Point.x, e.Vertexes[0].Point.y, e.Vertexes[1].Point.x, e.Vertexes[1].Point.y))
            else:
                PathLog.debug("         (%.2f, %.2f)^%.2f" % (e.Curve.Center.x, e.Curve.Center.y, e.Curve.Radius))
            for pt in DraftGeomUtils.findIntersection(edge, e, True, findAll=True):
                if not PathGeom.pointsCoincide(pt, corner) and self.pointIsOnEdge(pt, e):
                    # debugMarker(pt, "candidate-%d-%s" % (self.boneId, d), color, 0.05)
                    PathLog.debug("         -> candidate")
                    distance = (pt - refPoint).Length
                    if not pivot or pivotDistance > distance:
                        pivot = pt
                        pivotDistance = distance
                else:
                    PathLog.debug("         -> corner intersect")

        if pivot:
            # debugCircle(pivot, self.toolRadius, "pivot.%d-%s" % (self.boneId, d), color)

            pivotEdge = Part.Edge(Part.Circle(pivot, FreeCAD.Vector(0, 0, 1), self.toolRadius))
            t1 = self.findPivotIntersection(pivot, pivotEdge, inChord.asEdge(), inChord.End, d, color)
            t2 = self.findPivotIntersection(pivot, pivotEdge, outChord.asEdge(), inChord.End, d, color)

            commands = []
            if not PathGeom.pointsCoincide(t1, inChord.Start):
                PathLog.debug("  add lead in")
                commands.append(Chord(inChord.Start, t1).g1Command(bone.F))
            if bone.obj.Side == Side.Left:
                PathLog.debug("  add g3 command")
                commands.append(Chord(t1, t2).g3Command(pivot, bone.F))
            else:
                PathLog.debug("  add g2 command center=(%.2f, %.2f) -> from (%2f, %.2f) to (%.2f, %.2f" % (pivot.x, pivot.y, t1.x, t1.y, t2.x, t2.y))
                commands.append(Chord(t1, t2).g2Command(pivot, bone.F))
            if not PathGeom.pointsCoincide(t2, outChord.End):
                PathLog.debug("  add lead out")
                commands.append(Chord(t2, outChord.End).g1Command(bone.F))

            # debugMarker(pivot, "pivot.%d-%s"     % (self.boneId, d), color, 0.2)
            # debugMarker(t1,    "pivot.%d-%s.in"  % (self.boneId, d), color, 0.1)
            # debugMarker(t2,    "pivot.%d-%s.out" % (self.boneId, d), color, 0.1)

            return commands

        PathLog.info(" no pivot found - straight command")
        return [inChord.g1Command(bone.F), outChord.g1Command(bone.F)]
示例#24
0
    def execute(self,obj):
        import Part, math, DraftGeomUtils
        pl = obj.Placement
        self.baseface = None

        base = None
        if obj.Base and obj.Angles:
            w = None
            if obj.Base.isDerivedFrom("Part::Feature"):
                if (obj.Base.Shape.Faces and obj.Face):
                    w = obj.Base.Shape.Faces[obj.Face-1].Wires[0]
                elif obj.Base.Shape.Wires:
                    w = obj.Base.Shape.Wires[0]
            if w:
                if w.isClosed():
                    self.profilsDico = []
                    self.shps = []
                    self.subVolshps = []
                    heights = []
                    edges = DraftGeomUtils.sortEdges(w.Edges)
                    l = len(edges)
                    print("le contour contient "+str(l)+" aretes")
                    for i in range(l):
                        self.makeRoofProfilsDic(i, obj.Angles[i], obj.Runs[i], obj.IdRel[i], obj.Overhang[i], obj.Thickness[i])
                    for i in range(l):
                        self.calcMissingData(i)
                    for p in self.profilsDico:
                        heights.append(p["height"])
                    obj.Heights = heights
                    for i in range(l):
                        edgesForward = edges[:]
                        edgesForward.append(edges[0])
                        ptsPaneProject=[]
                        profil0 =self.profilsDico[i-1]
                        profil1 =self.profilsDico[i]
                        if i == l-1:
                            profil2 =self.profilsDico[0]
                        else:
                            profil2 =self.profilsDico[i+1]
                        vec0 = edges[i-1].Vertexes[-1].Point.sub(edges[i-1].Vertexes[0].Point)
                        vec1 = edges[i].Vertexes[-1].Point.sub(edges[i].Vertexes[0].Point)
                        vec2 = edgesForward[i+1].Vertexes[-1].Point.sub(edgesForward[i+1].Vertexes[0].Point)
                        rotEdge0 = math.degrees(DraftVecUtils.angle(vec0))
                        rotEdge1 = math.degrees(DraftVecUtils.angle(vec1))
                        rotEdge2 = math.degrees(DraftVecUtils.angle(vec2))
                        edgeEave0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["overhang"]).negative())
                        edgeEave1 = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,profil1["overhang"]).negative())
                        edgeEave2 = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,profil2["overhang"]).negative())
                        pt0Eave1 = DraftGeomUtils.findIntersection(edgeEave0,edgeEave1,infinite1=True,infinite2=True,)
                        pt1Eave1 = DraftGeomUtils.findIntersection(edgeEave1,edgeEave2,infinite1=True,infinite2=True,)
                        edgeEave1 = DraftGeomUtils.edg(FreeCAD.Vector(pt0Eave1[0]),FreeCAD.Vector(pt1Eave1[0]))
                        edgeRidge0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["run"]))
                        edgeRidge1 = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,profil1["run"]))
                        edgeRidge2 = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,profil2["run"]))
                        midpoint = DraftGeomUtils.findMidpoint(edges[i])
                        pt0Edge1 = edges[i].Vertexes[0].Point
                        pt1Edge1 = edges[i].Vertexes[-1].Point
                        print("Analyse profil " + str(i))
                        if profil1["angle"] != 90.:
                            if profil2["angle"] == 90. :
                                print("situation a droite : pignon")
                                ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                point = DraftGeomUtils.findIntersection(edgeRidge1,edgeEave2,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                            elif profil1["height"] == profil2["height"] :
                                print("situation a droite : ht1 = ht2")
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                            elif profil1["height"] > profil2["height"]:
                                print("situation a droite : ht1 > ht2")
                                dec = profil2["height"]/math.tan(math.radians(profil1["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge2,edgeRidge2OnPane,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [edgeRidge1.Edges[0],], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
                            elif profil1["height"] < profil2["height"]:
                                print("situation a droite : ht1 < ht2")
                                dec = profil1["height"]/math.tan(math.radians(profil2["angle"]))
                                edgeRidge2OnPane = DraftGeomUtils.offset(edgesForward[i+1],self.getPerpendicular(vec2,rotEdge2,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2OnPane,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt1Edge1)
                                ptInterHipEave1 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave1:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave1[0]))
                                else:
                                    ptInterHipEave2 = DraftGeomUtils.findIntersection(edgeHip,edgeEave2,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(pt1Eave1[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave2[0]))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge2,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            if profil0["angle"] == 90. :
                                print("situation a gauche : pignon")
                                point = DraftGeomUtils.findIntersection(edgeRidge1,edgeEave0,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(point[0]))
                                ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil0["height"] == profil1["height"]:
                                print("situation a gauche : ht1 = ht0")
                                edgeRidge0 = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,profil0["run"]))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge1,edgeRidge0,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] > profil0["height"]:
                                print("situation a gauche : ht1 > ht0")
                                dec = profil0["height"]/math.tan(math.radians(profil1["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(edges[i],self.getPerpendicular(vec1,rotEdge1,dec))
                                ptInter1 = DraftGeomUtils.findIntersection(edgeRidge0OnPane,edgeRidge0,infinite1=True,infinite2=True,)
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInter1[0]),pt0Edge1)
                                ptInter2 = edgeHip.Vertexes[0].Point
                                vecInterRidges = DraftGeomUtils.findPerpendicular(ptInter2, [edgeRidge1.Edges[0],], force=0)
                                ptInterRidges = ptInter2.add(vecInterRidges[0])
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges))
                                ptsPaneProject.append(FreeCAD.Vector(ptInter1[0]))
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            elif profil1["height"] < profil0["height"]:
                                print("situation a gauche : ht1 < ht0")
                                dec = profil1["height"]/math.tan(math.radians(profil0["angle"]))
                                edgeRidge0OnPane = DraftGeomUtils.offset(edges[i-1],self.getPerpendicular(vec0,rotEdge0,dec))
                                ptInterRidges = DraftGeomUtils.findIntersection(edgeRidge0OnPane,edgeRidge1,infinite1=True,infinite2=True,)
                                ptsPaneProject.append(FreeCAD.Vector(ptInterRidges[0]))
                                edgeHip = DraftGeomUtils.edg(FreeCAD.Vector(ptInterRidges[0]),pt0Edge1)
                                ptInterHipEave3 = DraftGeomUtils.findIntersection(edgeHip,edgeEave1,infinite1=True,infinite2=False,)
                                if ptInterHipEave3:
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave3[0]))
                                else:
                                    ptInterHipEave4 = DraftGeomUtils.findIntersection(edgeHip,edgeEave0,infinite1=True,infinite2=True,)
                                    ptsPaneProject.append(FreeCAD.Vector(ptInterHipEave4[0]))
                                    ptsPaneProject.append(FreeCAD.Vector(pt0Eave1[0]))
                            else:
                                print("Cas de figure non pris en charge")
                            ptsPaneProject = DraftVecUtils.removeDoubles(ptsPaneProject)
                            print("ptsPaneProject",ptsPaneProject)
                            print("Fin Analyse profil " + str(i))
                            self.profilsDico[i]["points"] = ptsPaneProject
                            lp = len(ptsPaneProject)
                            ptsPaneProject.append(ptsPaneProject[0])
                            edgesWire = []
                            for i in range(lp):
                                edge = Part.makeLine(ptsPaneProject[i],ptsPaneProject[i+1])
                                edgesWire.append(edge)
                            wire = Part.Wire(edgesWire)
                            d = wire.BoundBox.DiagonalLength
                            thicknessV = profil1["thickness"]/(math.cos(math.radians(profil1["angle"])))
                            overhangV = profil1["overhang"]*math.tan(math.radians(profil1["angle"]))
                            if wire.isClosed():
                                f = Part.Face(wire)
                                f = f.extrude(FreeCAD.Vector(0,0,profil1["height"]+2*thicknessV+2*overhangV))
                                f.translate(FreeCAD.Vector(0.0,0.0,-2*overhangV))
                            ptsPaneProfil=[FreeCAD.Vector(-profil1["overhang"],-overhangV,0.0),FreeCAD.Vector(profil1["run"],profil1["height"],0.0),FreeCAD.Vector(profil1["run"],profil1["height"]+thicknessV,0.0),FreeCAD.Vector(-profil1["overhang"],-overhangV+thicknessV,0.0)]
                            self.createProfilShape (ptsPaneProfil, midpoint, rotEdge1, vec1, profil1["run"], d, self.shps, f)
                            ## subVolume shape
                            ptsSubVolumeProfil=[FreeCAD.Vector(-profil1["overhang"],-overhangV,0.0),FreeCAD.Vector(profil1["run"],profil1["height"],0.0),FreeCAD.Vector(profil1["run"],profil1["height"]+10000,0.0),FreeCAD.Vector(0.0,profil1["height"]+10000,0.0)]
                            self.createProfilShape (ptsSubVolumeProfil, midpoint, rotEdge1, vec1, profil1["run"], d, self.subVolshps, f)
                        else:
                            #TODO PIGNON
                            pass

                    ## SubVolume
                    self.sub = self.subVolshps.pop()
                    for s in self.subVolshps:
                        self.sub = self.sub.fuse(s)
                    self.sub = self.sub.removeSplitter()
                    if not self.sub.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            self.sub.Placement = pl
                    ## BaseVolume
                    base = Part.makeCompound(self.shps)
                    if not base.isNull():
                        if not DraftGeomUtils.isNull(pl):
                            base.Placement = pl
        base = self.processSubShapes(obj,base)
        if base:
            if not base.isNull():
                obj.Shape = base
示例#25
0
    def redraw(self, point, snapped=None, shift=False, alt=False, real=None):
        """Redraw the ghost normally."""
        # initializing
        reverse = False
        for g in self.ghost:
            g.off()
        if real:
            newedges = []

        import DraftGeomUtils
        import Part

        # finding the active point
        vlist = []
        for e in self.edges:
            vlist.append(e.Vertexes[0].Point)
        vlist.append(self.edges[-1].Vertexes[-1].Point)
        if shift:
            npoint = self.activePoint
        else:
            npoint = DraftGeomUtils.findClosest(point, vlist)
        if npoint > len(self.edges) / 2:
            reverse = True
        if alt:
            reverse = not reverse
        self.activePoint = npoint

        # sorting out directions
        if reverse and (npoint > 0):
            npoint = npoint - 1
        if (npoint > len(self.edges) - 1):
            edge = self.edges[-1]
            ghost = self.ghost[-1]
        else:
            edge = self.edges[npoint]
            ghost = self.ghost[npoint]
        if reverse:
            v1 = edge.Vertexes[-1].Point
            v2 = edge.Vertexes[0].Point
        else:
            v1 = edge.Vertexes[0].Point
            v2 = edge.Vertexes[-1].Point

        # snapping
        if snapped:
            snapped = self.doc.getObject(snapped['Object'])
            if hasattr(snapped, "Shape"):
                pts = []
                for e in snapped.Shape.Edges:
                    int = DraftGeomUtils.findIntersection(edge, e, True, True)
                    if int:
                        pts.extend(int)
                if pts:
                    point = pts[DraftGeomUtils.findClosest(point, pts)]

        # modifying active edge
        if DraftGeomUtils.geomType(edge) == "Line":
            ve = DraftGeomUtils.vec(edge)
            chord = v1.sub(point)
            n = ve.cross(chord)
            if n.Length == 0:
                self.newpoint = point
            else:
                perp = ve.cross(n)
                proj = DraftVecUtils.project(chord, perp)
                self.newpoint = App.Vector.add(point, proj)
            dist = v1.sub(self.newpoint).Length
            ghost.p1(self.newpoint)
            ghost.p2(v2)
            self.ui.labelRadius.setText(translate("draft", "Distance"))
            self.ui.radiusValue.setToolTip(
                translate("draft", "The offset distance"))
            if real:
                if self.force:
                    ray = self.newpoint.sub(v1)
                    ray.multiply(self.force / ray.Length)
                    self.newpoint = App.Vector.add(v1, ray)
                newedges.append(Part.LineSegment(self.newpoint, v2).toShape())
        else:
            center = edge.Curve.Center
            rad = edge.Curve.Radius
            ang1 = DraftVecUtils.angle(v2.sub(center))
            ang2 = DraftVecUtils.angle(point.sub(center))
            _rot_rad = DraftVecUtils.rotate(App.Vector(rad, 0, 0), -ang2)
            self.newpoint = App.Vector.add(center, _rot_rad)
            self.ui.labelRadius.setText(translate("draft", "Angle"))
            self.ui.radiusValue.setToolTip(
                translate("draft", "The offset angle"))
            dist = math.degrees(-ang2)
            # if ang1 > ang2:
            #     ang1, ang2 = ang2, ang1
            # print("last calculated:",
            #       math.degrees(-ang1),
            #       math.degrees(-ang2))
            ghost.setEndAngle(-ang2)
            ghost.setStartAngle(-ang1)
            ghost.setCenter(center)
            ghost.setRadius(rad)
            if real:
                if self.force:
                    angle = math.radians(self.force)
                    newray = DraftVecUtils.rotate(App.Vector(rad, 0, 0),
                                                  -angle)
                    self.newpoint = App.Vector.add(center, newray)
                chord = self.newpoint.sub(v2)
                perp = chord.cross(App.Vector(0, 0, 1))
                scaledperp = DraftVecUtils.scaleTo(perp, rad)
                midpoint = App.Vector.add(center, scaledperp)
                _sh = Part.Arc(self.newpoint, midpoint, v2).toShape()
                newedges.append(_sh)
        ghost.on()

        # resetting the visible edges
        if not reverse:
            li = list(range(npoint + 1, len(self.edges)))
        else:
            li = list(range(npoint - 1, -1, -1))
        for i in li:
            edge = self.edges[i]
            ghost = self.ghost[i]
            if DraftGeomUtils.geomType(edge) == "Line":
                ghost.p1(edge.Vertexes[0].Point)
                ghost.p2(edge.Vertexes[-1].Point)
            else:
                ang1 = DraftVecUtils.angle(edge.Vertexes[0].Point.sub(center))
                ang2 = DraftVecUtils.angle(edge.Vertexes[-1].Point.sub(center))
                # if ang1 > ang2:
                #     ang1, ang2 = ang2, ang1
                ghost.setEndAngle(-ang2)
                ghost.setStartAngle(-ang1)
                ghost.setCenter(edge.Curve.Center)
                ghost.setRadius(edge.Curve.Radius)
            if real:
                newedges.append(edge)
            ghost.on()

        # finishing
        if real:
            return newedges
        else:
            return dist
示例#26
0
文件: trmi.py 项目: eason2/trim
def trim():# main
    global mysel
    obj = mysel[0]
    pos = mysel[1]
    sub = mysel[2]
    myobj = obj
    obj = downgrade_start_obj(obj)# downgrade
    for i in obj: # delete what you click
        if DraftGeomUtils.isSameLine(i.Shape.Edge1,sub):
            myobj = i
            #FreeCAD.ActiveDocument.removeObject(i)
            break


    FreeCAD.ActiveDocument.recompute()
    allobjs=FreeCAD.ActiveDocument.Objects
    allobjs.remove(myobj)
    connet_edge_list = []
    connet_obj_list = []
    for i in allobjs:
        if str(type(i)) <> "<type 'App.DocumentObjectGroup'>" and FreeCADGui.ActiveDocument.getObject(i.Name).Visibility==True:
            for edge in i.Shape.Edges: # edges in obj
                if DraftGeomUtils.findIntersection(edge,sub): # if there is a interpoint in edge and sub_edge(click)...
                    connet_edge_list.append(edge)
                    connet_obj_list.append(i)
                    prf('Edge Inter ( click edge )',i.Name)


    prf('connet edge num',len(connet_edge_list))
    if len(connet_edge_list) == 0:
        prf('find no intersectionpoint,delete the obj!')
        FreeCAD.ActiveDocument.removeObject(myobj.Name)


    elif len(connet_edge_list) == 1:
        objs = downgrade_obj([myobj,mkobj(connet_edge_list[0])])
        myedge = getinteredge(objs,pos)
        FreeCAD.ActiveDocument.removeObject(myedge.Name)


    elif len(connet_edge_list) > 1:
        myedge = mkobj(getinteredge(connet_edge_list,pos,True))
        obj1 = downgrade_obj([myobj,myedge])
        myedge = getinteredge(obj1,pos)
        if len(obj1) == 1:
            FreeCAD.ActiveDocument.removeObject(obj1[0].Name)
            return()


        if obj1[0].Name == myedge.Name:
            another_edge = obj1[1]


        else: 
            another_edge = obj1[0]


        click_edge = myedge
        my_new_connet_edge = []
        for i in connet_edge_list:
            if DraftGeomUtils.findIntersection(i,click_edge.Shape.Edge1):
                if not DraftGeomUtils.findIntersection(i,another_edge.Shape.Edge1):
                    my_new_connet_edge.append(i)


        if my_new_connet_edge:
            myedge1 = mkobj(getinteredge(my_new_connet_edge,pos,True))
            myobj = downgrade_obj([myedge,myedge1])
            myedge = getinteredge(myobj,pos) # del obj
            FreeCAD.ActiveDocument.removeObject(myedge.Name)


        else:
            FreeCAD.ActiveDocument.removeObject(click_edge.Name)


    FreeCAD.ActiveDocument.recompute()
示例#27
0
    def run(self):

        """run(): Runs a nesting operation. Returns a list of lists of
           shapes, each primary list being one filled container, or None
           if the operation failed."""

        # reset abort mechanism and variables

        self.running = True
        self.progress = 0
        starttime = datetime.now()

        # general conformity tests

        print("Executing conformity tests ... ",end="")
        if not self.container:
            print("Empty container. Aborting")
            return
        if not self.shapes:
            print("Empty shapes. Aborting")
            return
        if not isinstance(self.container,Part.Face):
            print("Container is not a face. Aborting")
            return
        normal = self.container.normalAt(0,0)
        for s in self.shapes:
            if not self.update():
                return
            if len(s.Faces) != 1:
                print("One of the shapes does not contain exactly one face. Aborting")
                return
            # check if all faces correctly oriented (same normal)
            if s.Faces[0].normalAt(0,0).getAngle(normal) > TOLERANCE:
                # let pass faces with inverted normal
                if s.Faces[0].normalAt(0,0).getAngle(normal)-math.pi > TOLERANCE:
                    print("One of the face doesn't have the same orientation as the container. Aborting")
                    return

        # TODO
        # allow to use a non-rectangular container
        # manage margins/paddings
        # allow to prevent or force specific rotations for a piece

        # LONG-TERM TODO
        # add genetic algo to swap pieces, and check if the result is better

        # track progresses
        step = 100.0/(len(self.shapes)*len(ROTATIONS))

        # store hashCode together with the face so we can change the order
        # and still identify the original face, so we can calculate a transform afterwards
        self.indexedfaces = [[shape.hashCode(),shape] for shape in self.shapes]

        # build a clean copy so we don't touch the original
        faces = list(self.indexedfaces)

        # replace shapes by their face
        faces = [[f[0],f[1].Faces[0]] for f in faces]

        # order by area
        faces = sorted(faces,key=lambda face: face[1].Area)

        # discretize non-linear edges and remove holes
        nfaces = []
        for face in faces:
            if not self.update():
                return
            nedges = []
            allLines = True
            for edge in face[1].OuterWire.OrderedEdges:
                if isinstance(edge.Curve,(Part.LineSegment,Part.Line)):
                    nedges.append(edge)
                else:
                    allLines = False
                    last = edge.Vertexes[0].Point
                    for i in range(DISCRETIZE):
                        s = float(i+1)/DISCRETIZE
                        par = edge.FirstParameter + (edge.LastParameter-edge.FirstParameter)*s
                        new = edge.valueAt(par)
                        nedges.append(Part.LineSegment(last,new).toShape())
                        last = new
            f = Part.Face(Part.Wire(nedges))
            if not f.isValid():
                if allLines:
                    print("Invalid face found in set. Aborting")
                else:
                    print("Face distretizing failed. Aborting")
                return
            nfaces.append([face[0],f])
        faces = nfaces

        # container for sheets with a first, empty sheet
        sheets = [[]]

        print("Everything OK (",datetime.now()-starttime,")")

        # main loop

        facenumber = 1
        facesnumber = len(faces)

        #print("Vertices per face:",[len(face[1].Vertexes) for face in faces])

        while faces:

            print("Placing piece",facenumber,"/",facesnumber,"Area:",FreeCAD.Units.Quantity(faces[-1][1].Area,FreeCAD.Units.Area).getUserPreferred()[0],": ",end="")

            face = faces.pop()
            boc = self.container.BoundBox

            # this stores the available solutions for each rotation of a piece
            # contains [sheetnumber,face,xlength] lists,
            # face being [hascode,transformed face] and xlength
            # the X size of all boundboxes of placed pieces
            available = []

            # this stores the possible positions on a blank
            # sheet, in case we need to create a new one
            initials = []

            # this checks if the piece don't fit in the container
            unfit = True

            for rotation in ROTATIONS:

                if not self.update():
                    return

                self.progress += step

                print(rotation,", ",end="")
                hashcode = face[0]
                rotface = face[1].copy()
                if rotation:
                    rotface.rotate(rotface.CenterOfMass,normal,rotation)
                bof = rotface.BoundBox
                rotverts = self.order(rotface)
                #for i,v in enumerate(rotverts):
                #    Draft.makeText([str(i)],point=v)
                basepoint = rotverts[0] # leftmost point of the rotated face
                basecorner = boc.getPoint(0) # lower left corner of the container

                # See if the piece fits in the container dimensions
                if (bof.XLength < boc.XLength) and (bof.YLength < boc.YLength):
                    unfit = False

                # Get the fit polygon of the container
                # that is, the polygon inside which basepoint can
                # circulate, and the face still be fully inside the container

                v1 = basecorner.add(basepoint.sub(bof.getPoint(0)))
                v2 = v1.add(FreeCAD.Vector(0,boc.YLength-bof.YLength,0))
                v3 = v2.add(FreeCAD.Vector(boc.XLength-bof.XLength,0,0))
                v4 = v3.add(FreeCAD.Vector(0,-(boc.YLength-bof.YLength),0))
                binpol = Part.Face(Part.makePolygon([v1,v2,v3,v4,v1]))
                initials.append([binpol,[hashcode,rotface],basepoint])

                # check for available space on each existing sheet

                for sheetnumber,sheet in enumerate(sheets):
                    # Get the no-fit polygon for each already placed face in
                    # current sheet. That is, a polygon in which basepoint
                    # cannot be, if we want our face to not overlap with the
                    # placed face.
                    # To do this, we "circulate" the face around the placed face

                    if not self.update():
                        return

                    nofitpol = []
                    for placed in sheet:
                        pts = []
                        pi = 0
                        for placedvert in self.order(placed[1],right=True):
                            fpts = []
                            for i,rotvert in enumerate(rotverts):
                                if not self.update():
                                    return

                                facecopy = rotface.copy()
                                facecopy.translate(placedvert.sub(rotvert))

                                # test if all the points of the face are outside the
                                # placed face (except the base point, which is coincident)

                                outside = True
                                faceverts = self.order(facecopy)
                                for vert in faceverts:
                                    if (vert.sub(placedvert)).Length > TOLERANCE:
                                        if placed[1].isInside(vert,TOLERANCE,True):
                                            outside = False
                                            break

                                # also need to test for edge intersection, because even
                                # if all vertices are outside, the pieces could still
                                # overlap

                                if outside:
                                    for e1 in facecopy.OuterWire.Edges:
                                        for e2 in placed[1].OuterWire.Edges:
                                            if not self.update():
                                                return

                                            if True:
                                                # Draft code (SLOW)
                                                p = DraftGeomUtils.findIntersection(e1,e2)
                                                if p:
                                                    p = p[0]
                                                    p1 = e1.Vertexes[0].Point
                                                    p2 = e1.Vertexes[1].Point
                                                    p3 = e2.Vertexes[0].Point
                                                    p4 = e2.Vertexes[1].Point
                                                    if (p.sub(p1).Length > TOLERANCE) and (p.sub(p2).Length > TOLERANCE) \
                                                    and (p.sub(p3).Length > TOLERANCE) and (p.sub(p4).Length > TOLERANCE):
                                                        outside = False
                                                        break
                                            else:
                                                # alt code: using distToShape (EVEN SLOWER!)
                                                p = e1.distToShape(e2)
                                                if p:
                                                    if p[0] < TOLERANCE:
                                                        # allow vertex-to-vertex intersection
                                                        if (p[2][0][0] != "Vertex") or (p[2][0][3] != "Vertex"):
                                                            outside = False
                                                            break


                                if outside:
                                    fpts.append([faceverts[0],i])
                                    #Draft.makeText([str(i)],point=faceverts[0])

                            # reorder available solutions around a same point if needed
                            # ensure they are in the correct order

                            idxs = [p[1] for p in fpts]
                            if (0 in idxs) and (len(faceverts)-1 in idxs):
                                slicepoint = len(fpts)
                                last = len(faceverts)
                                for p in reversed(fpts):
                                    if p[1] == last-1:
                                        slicepoint -= 1
                                        last -= 1
                                    else:
                                        break
                                fpts = fpts[slicepoint:]+fpts[:slicepoint]
                                #print(fpts)
                            pts.extend(fpts)

                        # create the polygon

                        if len(pts) < 3:
                            print("Error calculating a no-fit polygon. Aborting")
                            return
                        pts = [p[0] for p in pts]
                        pol = Part.Face(Part.makePolygon(pts+[pts[0]]))

                        if not pol.isValid():

                            # fix overlapping edges

                            overlap = True
                            while overlap:
                                overlap = False
                                for i in range(len(pol.OuterWire.Edges)-1):
                                    if not self.update():
                                        return

                                    v1 = DraftGeomUtils.vec(pol.OuterWire.OrderedEdges[i])
                                    v2 = DraftGeomUtils.vec(pol.OuterWire.OrderedEdges[i+1])
                                    if abs(v1.getAngle(v2)-math.pi) <= TOLERANCE:
                                        overlap = True
                                        ne = Part.LineSegment(pol.OuterWire.OrderedEdges[i].Vertexes[0].Point,
                                                              pol.OuterWire.OrderedEdges[i+1].Vertexes[-1].Point).toShape()
                                        pol = Part.Face(Part.Wire(pol.OuterWire.OrderedEdges[:i]+[ne]+pol.OuterWire.OrderedEdges[i+2:]))
                                        break

                        if not pol.isValid():

                            # trying basic OCC fix

                            pol.fix(0,0,0)
                            if pol.isValid():
                                if pol.ShapeType == "Face":
                                    pol = Part.Face(pol.OuterWire) # discard possible inner holes
                                elif pol.Faces:
                                    # several faces after the fix, keep the biggest one
                                    a = 0
                                    ff = None
                                    for f in pol.Faces:
                                        if f.Area > a:
                                            a = f.Area
                                            ff = f
                                    if ff:
                                        pol = ff
                                else:
                                    print("Unable to fix invalid no-fit polygon. Aborting")
                                    Part.show(pol)
                                    return

                        if not pol.isValid():

                            # none of the fixes worked. Epic fail.

                            print("Invalid no-fit polygon. Aborting")
                            Part.show(pol.OuterWire)
                            for p in sheet:
                                Part.show(p[1])
                            Part.show(facecopy)
                            #for i,p in enumerate(faceverts):
                            #    Draft.makeText([str(i)],point=p)
                            return
                            
                        if pol.isValid():
                            nofitpol.append(pol)
                            #Part.show(pol)

                    # Union all the no-fit pols into one

                    if len(nofitpol) == 1:
                        nofitpol = nofitpol[0]
                    elif len(nofitpol) > 1:
                        b = nofitpol.pop()
                        for n in nofitpol:
                            if not self.update():
                                return
                            b = b.fuse(n)
                        nofitpol = b

                        # remove internal edges (discard edges shared by 2 faces)

                        lut = {}
                        for f in fitpol.Faces:
                            for e in f.Edges:
                                h = e.hashCode()
                                if h in lut:
                                    lut[h].append(e)
                                else:
                                    lut[h] = [e]
                        edges = [e[0] for e in lut.values() if len(e) == 1]
                        try:
                            pol = Part.Face(Part.Wire(edges))
                        except:
                            # above method can fail sometimes. Try a slower method
                            w = DraftGeomUtils.findWires(edges)
                            if len(w) == 1:
                                if w[0].isClosed():
                                    try:
                                        pol = Part.Face(w[0])
                                    except:
                                        print("Error merging polygons. Aborting")
                                        try:
                                            Part.show(Part.Wire(edges))
                                        except:
                                            for e in edges:
                                                Part.show(e)
                                        return

                    # subtract the no-fit polygon from the container's fit polygon
                    # we then have the zone where the face can be placed

                    if nofitpol:
                        fitpol = binpol.cut(nofitpol)
                    else:
                        fitpol = binpol.copy()

                    # check that we have some space on this sheet

                    if (fitpol.Area > 0) and fitpol.Vertexes:

                        # order the fitpol vertexes by smallest X
                        # and try to place the piece, making sure it doesn't
                        # intersect with already placed pieces
                        fitverts = sorted([v.Point for v in fitpol.Vertexes],key=lambda v: v.x)
                        for p in fitverts:
                            if not self.update():
                                return

                            trface = rotface.copy()
                            trface.translate(p.sub(basepoint))
                            ok = True
                            for placed in sheet:
                                if ok:
                                    for vert in trface.Vertexes:
                                        if placed[1].isInside(vert.Point,TOLERANCE,False):
                                            ok = False
                                            break
                                if ok:
                                    for e1 in trface.OuterWire.Edges:
                                        for e2 in placed[1].OuterWire.Edges:
                                            p = DraftGeomUtils.findIntersection(e1,e2)
                                            if p:
                                                p = p[0]
                                                p1 = e1.Vertexes[0].Point
                                                p2 = e1.Vertexes[1].Point
                                                p3 = e2.Vertexes[0].Point
                                                p4 = e2.Vertexes[1].Point
                                                if (p.sub(p1).Length > TOLERANCE) and (p.sub(p2).Length > TOLERANCE) \
                                                and (p.sub(p3).Length > TOLERANCE) and (p.sub(p4).Length > TOLERANCE):
                                                    ok = False
                                                    break
                                if not ok:
                                    break
                            if ok:
                                rotface = trface
                                break
                        else:
                            print("Couldn't determine location on sheet. Aborting")
                            return

                        # check the X space occupied by this solution

                        bb = rotface.BoundBox
                        for placed in sheet:
                            bb.add(placed[1].BoundBox)
                        available.append([sheetnumber,[hashcode,rotface],bb.XMax,fitpol])

            if unfit:
                print("One face doesn't fit in the container. Aborting")
                return

            if available:

                # order by smallest X size and take the first one
                available = sorted(available,key=lambda sol: sol[2])
                print("Adding piece to sheet",available[0][0]+1)
                sheets[available[0][0]].append(available[0][1])
                #Part.show(available[0][3])

            else:

                # adding to the leftmost vertex of the binpol

                sheet = []
                print("Creating new sheet, adding piece to sheet",len(sheets))
                # order initial positions by smallest X size
                initials = sorted(initials,key=lambda sol: sol[1][1].BoundBox.XLength)
                hashcode = initials[0][1][0]
                face = initials[0][1][1]
                # order binpol vertexes by X coord
                verts = sorted([v.Point for v in initials[0][0].Vertexes],key=lambda v: v.x)
                face.translate(verts[0].sub(initials[0][2]))
                sheet.append([hashcode,face])
                sheets.append(sheet)

            facenumber += 1

        print("Run time:",datetime.now()-starttime)
        self.results.append(sheets)
        return sheets
示例#28
0
    def trimObjects(self, objectslist):
        """Attempt to trim two objects together."""
        import Part
        import DraftGeomUtils

        wires = []
        for obj in objectslist:
            if not utils.getType(obj) in ["Wire", "Circle"]:
                _err(
                    translate(
                        "draft", "Unable to trim these objects, "
                        "only Draft wires and arcs are supported."))
                return
            if len(obj.Shape.Wires) > 1:
                _err(
                    translate(
                        "draft", "Unable to trim these objects, "
                        "too many wires"))
                return
            if len(obj.Shape.Wires) == 1:
                wires.append(obj.Shape.Wires[0])
            else:
                wires.append(Part.Wire(obj.Shape.Edges))
        ints = []
        edge1 = None
        edge2 = None
        for i1, e1 in enumerate(wires[0].Edges):
            for i2, e2 in enumerate(wires[1].Edges):
                i = DraftGeomUtils.findIntersection(e1, e2, dts=False)
                if len(i) == 1:
                    ints.append(i[0])
                    edge1 = i1
                    edge2 = i2
        if not ints:
            _err(translate("draft", "These objects don't intersect."))
            return
        if len(ints) != 1:
            _err(translate("draft", "Too many intersection points."))
            return

        v11 = wires[0].Vertexes[0].Point
        v12 = wires[0].Vertexes[-1].Point
        v21 = wires[1].Vertexes[0].Point
        v22 = wires[1].Vertexes[-1].Point
        if DraftVecUtils.closest(ints[0], [v11, v12]) == 1:
            last1 = True
        else:
            last1 = False
        if DraftVecUtils.closest(ints[0], [v21, v22]) == 1:
            last2 = True
        else:
            last2 = False
        for i, obj in enumerate(objectslist):
            if i == 0:
                ed = edge1
                la = last1
            else:
                ed = edge2
                la = last2
            if utils.getType(obj) == "Wire":
                if la:
                    pts = obj.Points[:ed + 1] + ints
                else:
                    pts = ints + obj.Points[ed + 1:]
                obj.Points = pts
            else:
                vec = ints[0].sub(obj.Placement.Base)
                vec = obj.Placement.inverse().Rotation.multVec(vec)
                _x = App.Vector(1, 0, 0)
                _ang = -DraftVecUtils.angle(vec,
                                            obj.Placement.Rotation.multVec(_x),
                                            obj.Shape.Edges[0].Curve.Axis)
                ang = math.degrees(_ang)
                if la:
                    obj.LastAngle = ang
                else:
                    obj.FirstAngle = ang
        self.doc.recompute()