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)]
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
def Activated(self): import DraftGeomUtils try: s = Gui.Selection.getSelectionEx() if hasattr(s, "Point"): return e1 = None e2 = None if len(s) > 2: # Two objects must be selected errMessage = "Select only two vertices " faced.errorDialog(errMessage) return elif len(s) == 1: errMessage = "Not implemented " faced.errorDialog(errMessage) return elif len(s) == 2: s1 = s[0] s2 = s[1] if ('Vertex' in str(s1.SubElementNames)): # Vertexes are selected p1 = s1.SubObjects[0].Vertexes[0].Point p2 = s2.SubObjects[0].Vertexes[0].Point elif ('Edge' in str(s1.SubElementNames)): # Edges are selected # We have to find the nearest two vector. # Joining here means the two edges will # attach to each other while they are # separate. vert1 = [] for e in s1.Object.Shape.OrderedEdges: for v in e.Vertexes: vert1.append(v.Point) vert2 = [] for e in s2.Object.Shape.OrderedEdges: for v in e.Vertexes: vert2.append(v.Point) # Now we need to find one point from each edge # that are nearest to each other index1 = DraftGeomUtils.findClosest(vert1[0], vert2) index2 = DraftGeomUtils.findClosest( vert1[len(vert1) - 1], vert2) dist1 = math.sqrt( pow((vert1[0].x - vert2[index1].x), 2) + pow((vert1[0].y - vert2[index1].y), 2) + pow((vert1[0].z - vert2[index1].z), 2)) dist2 = math.sqrt( pow((vert1[len(vert1) - 1].x - vert2[index2].x), 2) + pow((vert1[len(vert1) - 1].y - vert2[index2].y), 2) + pow((vert1[len(vert1) - 1].y - vert2[index2].z), 2)) if dist1 == dist2 or dist1 < dist2: p1 = vert1[0] p2 = vert2[index1] elif dist2 < dist1: p1 = vert1[len(vert1) - 1] p2 = vert2[index2] if hasattr(s1.Object.Shape, "OrderedEdges"): Edges1 = s1.Object.Shape.OrderedEdges else: Edges1 = s1.Object.Shape.Edges if hasattr(s2.Object.Shape, "OrderedEdges"): Edges2 = s2.Object.Shape.OrderedEdges else: Edges2 = s2.Object.Shape.Edges if len(Edges1) > 1: for ed in Edges1: for v in ed.Vertexes: if v.Point == p1: e1 = ed Edges1.remove(e1) break else: e1 = Edges1[0] Edges1 = [] # We have the edges and the points if e1 is not None: if (e1.Vertexes[0].Point != p1): p1 = e1.Vertexes[0].Point else: p1 = e1.Vertexes[1].Point p1 = App.Vector(p1.x, p1.y, p1.z) p2 = App.Vector(p2.x, p2.y, p2.z) App.ActiveDocument.openTransaction( translate("Design456", "Join2Lines")) l1 = _draft.makeLine(p1, p2) App.ActiveDocument.recompute() newEdg = l1.Shape.Edges[0] if type(Edges1) == list and type(Edges2) == list: totalE = Edges1 + Edges2 + [newEdg] elif type(Edges1) == list and type(Edges2) != list: totalE = Edges1 + [Edges2] + [newEdg] elif type(Edges1) != list and type(Edges2) == list: # Only one edge in the first line, so not included totalE = Edges2 + [newEdg] else: # None of them is multiple edges. so only new edge should be use totalE = [Edges2] + [newEdg] newList = [] for e in totalE: newList.append(e.copy()) sortEdg = _part.sortEdges(newList) W = [_part.Wire(e) for e in sortEdg] for wire in W: newobj = App.ActiveDocument.addObject("Part::Feature", "Wire") newobj.Shape = wire App.ActiveDocument.removeObject(l1.Name) App.ActiveDocument.removeObject(s1.Object.Name) App.ActiveDocument.removeObject(s2.Object.Name) App.ActiveDocument.recompute() App.ActiveDocument.commitTransaction() # undo reg.de here except Exception as err: App.Console.PrintError("'Part Surface' Failed. " "{err}\n".format(err=str(err))) exc_type, exc_obj, exc_tb = sys.exc_info() fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] print(exc_type, fname, exc_tb.tb_lineno)