diff --git a/src/Mod/Arch/ArchBuildingPart.py b/src/Mod/Arch/ArchBuildingPart.py index fe0e595885..9d5b7a5db8 100644 --- a/src/Mod/Arch/ArchBuildingPart.py +++ b/src/Mod/Arch/ArchBuildingPart.py @@ -486,6 +486,8 @@ class ViewProviderBuildingPart: vobj.addProperty("App::PropertyBool","RestoreView","BuildingPart",QT_TRANSLATE_NOOP("App::Property","If set, the view stored in this object will be restored on double-click")) if not "DiffuseColor" in pl: vobj.addProperty("App::PropertyColorList","DiffuseColor","BuildingPart",QT_TRANSLATE_NOOP("App::Property","The individual face colors")) + if not "AutoWorkingPlane" in pl: + vobj.addProperty("App::PropertyBool","AutoWorkingPlane","BuildingPart",QT_TRANSLATE_NOOP("App::Property","If set to True, the working plane will be kept on Auto mode")) def onDocumentRestored(self,vobj): @@ -690,6 +692,9 @@ class ViewProviderBuildingPart: FreeCAD.DraftWorkingPlane.save() FreeCAD.DraftWorkingPlane.setFromPlacement(self.Object.Placement,rebase=True) FreeCAD.DraftWorkingPlane.weak = False + if hasattr(self.Object.ViewObject,"AutoWorkingPlane"): + if self.Object.ViewObject.AutoWorkingPlane: + FreeCAD.DraftWorkingPlane.weak = True if hasattr(FreeCADGui,"Snapper"): FreeCADGui.Snapper.setGrid() if hasattr(FreeCADGui,"draftToolBar"): diff --git a/src/Mod/Draft/Draft.py b/src/Mod/Draft/Draft.py index ec256b23e0..187beaae3f 100644 --- a/src/Mod/Draft/Draft.py +++ b/src/Mod/Draft/Draft.py @@ -186,6 +186,8 @@ def getType(obj): return "Sketch" if (obj.TypeId == "Part::Line"): return "Part::Line" + if (obj.TypeId == "Part::Offset2D"): + return "Offset2D" if obj.isDerivedFrom("Part::Feature"): return "Part" if (obj.TypeId == "App::Annotation"): diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 92542476d7..4be505d88e 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -338,6 +338,9 @@ class SelectPlane(DraftTool): elif Draft.getType(sel.Object) in ["WorkingPlaneProxy","BuildingPart"]: plane.setFromPlacement(sel.Object.Placement,rebase=True) plane.weak = False + if hasattr(sel.Object.ViewObject,"AutoWorkingPlane"): + if sel.Object.ViewObject.AutoWorkingPlane: + plane.weak = True if hasattr(sel.Object.ViewObject,"RestoreView"): if sel.Object.ViewObject.RestoreView: if hasattr(sel.Object.ViewObject,"ViewData"): @@ -2894,8 +2897,24 @@ class Stretch(Modifier): def proceed(self): if self.call: - self.view.removeEventCallback("SoEvent",self.call) - self.sel = FreeCADGui.Selection.getSelection() + self.view.removeEventCallback("SoEvent",self.call) + supported = ["Rectangle","Wire","BSpline","BezCurve","Sketch"] + self.sel = [] + for obj in FreeCADGui.Selection.getSelection(): + if Draft.getType(obj) in supported: + self.sel.append(obj) + elif hasattr(obj,"Base"): + if obj.Base: + if Draft.getType(obj.Base) in supported: + self.sel.append(obj.Base) + elif Draft.getType(obj.Base) == "Offset2D": + if obj.Base.Source: + if Draft.getType(obj.Base.Source) in supported: + self.sel.append(obj.Base.Source) + elif Draft.getType(obj) == "Offset2D": + if obj.Source: + if Draft.getType(obj.Source) in supported: + self.sel.append(obj.Source) if self.ui and self.sel: self.step = 1 self.refpoint = None @@ -2972,6 +2991,18 @@ class Stretch(Modifier): nodes.append(p) if iso: self.ops.append([o,np]) + elif tp in ["Sketch"]: + np = [] + iso = False + for p in o.Shape.Vertexes: + p = o.Placement.multVec(p.Point) + isi = self.rectracker.isInside(p) + np.append(isi) + if isi: + iso = True + nodes.append(p) + if iso: + self.ops.append([o,np]) else: if self.rectracker.isInside(o.Placement.Base): self.ops.append([o]) @@ -3001,9 +3032,9 @@ class Stretch(Modifier): self.addPoint(point) def finish(self,closed=False): - if self.rectracker: + if hasattr(self,"rectracker") and self.rectracker: self.rectracker.finalize() - if self.nodetracker: + if hasattr(self,"nodetracker") and self.nodetracker: for n in self.nodetracker: n.finalize() Modifier.finish(self) @@ -3026,6 +3057,19 @@ class Stretch(Modifier): pts.append(ops[0].Points[i].add(localdisp)) pts = str(pts).replace("Vector","FreeCAD.Vector") commitops.append("FreeCAD.ActiveDocument."+ops[0].Name+".Points="+pts) + elif tp in ["Sketch"]: + for i in range(ops[0].GeometryCount): + j = 0 + while True: + try: + p = ops[0].getPoint(i,j) + except ValueError: + break + else: + p = ops[0].Placement.multVec(p) + if p in ops[1]: + commitops.append("FreeCAD.ActiveDocument."+ops[0].Name+".movePoint("+str(i)+","+str(j)+",FreeCAD."+str(localdisp)+",True)") + j += 1 elif tp in ["Rectangle"]: p1 = Vector(0,0,0) p2 = Vector(ops[0].Length.Value,0,0) @@ -3041,7 +3085,7 @@ class Stretch(Modifier): optype = 4 else: optype = 0 - print("length:",ops[0].Length,"height:",ops[0].Height," - ",ops[1]," - ",self.displacement) + #print("length:",ops[0].Length,"height:",ops[0].Height," - ",ops[1]," - ",self.displacement) done = False if optype > 0: v1 = ops[0].Placement.multVec(p2).sub(ops[0].Placement.multVec(p1)) @@ -3127,6 +3171,9 @@ class Stretch(Modifier): commitops.append("w = Draft.makeWire("+pts+",closed=True)") commitops.append("Draft.formatObject(w,FreeCAD.ActiveDocument."+ops[0].Name+")") commitops.append("FreeCAD.ActiveDocument."+ops[0].Name+".ViewObject.hide()") + for par in ops[0].InList: + if hasattr(par,"Base") and par.Base == ops[0]: + commitops.append("FreeCAD.ActiveDocument."+par.Name+".Base = w") else: commitops.append("FreeCAD.ActiveDocument."+ops[0].Name+".Placement.Base=FreeCAD."+str(ops[0].Placement.Base.add(self.displacement))) if commitops: @@ -4198,6 +4245,14 @@ class Edit(Modifier): pts[changep] = self.obj.Proxy.modifysymmetricpole(\ pts[knot],editPnt) self.trackers[changep].set(pts[changep]) + # check that the new point lies on the plane of the wire + import DraftGeomUtils + if self.obj.Closed: + n = DraftGeomUtils.getNormal(self.obj.Shape) + dv = editPnt.sub(pts[self.editing]) + rn = DraftVecUtils.project(dv,n) + if dv.Length: + editPnt = editPnt.add(rn.negative()) pts[self.editing] = editPnt self.obj.Points = pts self.trackers[self.editing].set(v) diff --git a/src/Mod/Draft/WorkingPlane.py b/src/Mod/Draft/WorkingPlane.py index ea708ca1d3..500f05a4d3 100644 --- a/src/Mod/Draft/WorkingPlane.py +++ b/src/Mod/Draft/WorkingPlane.py @@ -290,7 +290,9 @@ class plane: rot = FreeCADGui.ActiveDocument.ActiveView.getCameraNode().getField("orientation").getValue() upvec = Vector(rot.multVec(coin.SbVec3f(0,1,0)).getValue()) vdir = FreeCADGui.ActiveDocument.ActiveView.getViewDirection() - self.alignToPointAndAxis(Vector(0,0,0), vdir.negative(), 0, upvec) + if (vdir.getAngle(self.axis) > 0.001) and (vdir.getAngle(self.axis) < 3.14159): + # don't change the WP if it is already perpendicular to the current view + self.alignToPointAndAxis(Vector(0,0,0), vdir.negative(), 0, upvec) except: pass self.weak = True diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py index c2b7fee0c0..de8f20275a 100644 --- a/src/Mod/Draft/importDXF.py +++ b/src/Mod/Draft/importDXF.py @@ -580,7 +580,7 @@ def drawFace(face): warn(face) return None -def drawMesh(mesh): +def drawMesh(mesh,forceShape=False): "returns a Mesh from a dxf mesh" md = [] if mesh.flags == 16: @@ -604,18 +604,26 @@ def drawMesh(mesh): pts.append(p) elif p.flags == 128: fcs.append(p) + #print("Creating polyface with",len(pts),"points and",len(fcs),"facets") for f in fcs: - p1 = pts[rawValue(f,71)-1] - p2 = pts[rawValue(f,72)-1] - p3 = pts[rawValue(f,73)-1] + p1 = pts[abs(rawValue(f,71))-1] + p2 = pts[abs(rawValue(f,72))-1] + p3 = pts[abs(rawValue(f,73))-1] md.append([p1,p2,p3]) if rawValue(f,74) != None: - p4 = pts[rawValue(f,74)-1] + p4 = pts[abs(rawValue(f,74))-1] md.append([p1,p3,p4]) try: - return Mesh.Mesh(md) + m = Mesh.Mesh(md) + if forceShape: + s = Part.Shape() + s.makeShapeFromMesh(m.Topology,1) + s = s.removeSplitter() + m = s except FreeCAD.Base.FreeCADError: warn(mesh) + else: + return m return None def drawSolid(solid): @@ -832,7 +840,10 @@ def drawBlock(blockref,num=None,createObject=False): s = drawLine(line,forceShape=True) if s: shapes.append(s) for polyline in blockref.entities.get_type('polyline'): - s = drawPolyline(polyline,forceShape=True) + if hasattr(polyline,"flags") and polyline.flags in [16,64]: + s = drawMesh(polyline,forceShape=True) + else: + s = drawPolyline(polyline,forceShape=True) if s: shapes.append(s) for polyline in blockref.entities.get_type('lwpolyline'): s = drawPolyline(polyline,forceShape=True) @@ -908,9 +919,16 @@ def drawInsert(insert,num=None,clone=False): rot = math.radians(insert.rotation) scale = insert.scale tsf = FreeCAD.Matrix() - tsf.scale(scale[0],scale[1],0) # for some reason z must be 0 to work + #tsf.scale(scale[0],scale[1],0) # for some reason z must be 0 to work tsf.rotateZ(rot) - shape = shape.transformGeometry(tsf) + try: + shape = shape.transformGeometry(tsf) + except Part.OCCError: + tsf.scale(scale[0],scale[1],0) + try: + shape = shape.transformGeometry(tsf) + except Part.OCCError: + print("importDXF: unable to apply insert transform:",tsf) shape.translate(pos) return shape return None