From 636708c90d2a698b47512345b979f1b20f8629db Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Wed, 6 Feb 2019 21:44:58 +0100 Subject: [PATCH 1/9] Update DraftTools.py Update Edit tool to edit wall base objects. --- src/Mod/Draft/DraftTools.py | 218 +++++++++++++++++++++++++++--------- 1 file changed, 164 insertions(+), 54 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 2efaba405e..c3c0263bbc 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -1314,6 +1314,7 @@ class Arc(Creator): self.arctrack.on() self.ui.radiusUi() self.step = 1 + self.ui.setNextFocus() self.linetrack.on() msg(translate("draft", "Pick radius:")+"\n") else: @@ -1328,6 +1329,7 @@ class Arc(Creator): self.arctrack.on() self.ui.radiusUi() self.step = 1 + self.ui.setNextFocus() self.linetrack.on() msg(translate("draft", "Pick radius:")+"\n") if self.planetrack: @@ -3207,6 +3209,71 @@ class Stretch(Modifier): self.commit(translate("draft","Stretch"),commitops) self.finish() +class Join(Modifier): + '''The Draft_Join FreeCAD command definition.''' + + def GetResources(self): + return {'Pixmap' : 'Draft_Join', + 'Accel' : "J, O", + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Join", "Join"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Join", "Joins two wires together")} + + def Activated(self): + Modifier.Activated(self,"Join") + if not self.ui: + return + if not FreeCADGui.Selection.getSelection(): + self.ui.selectUi() + msg(translate("draft", "Select an object to join")+"\n") + self.call = self.view.addEventCallback("SoEvent",selectObject) + else: + self.proceed() + + def proceed(self): + if self.call: + self.view.removeEventCallback("SoEvent",self.call) + if FreeCADGui.Selection.getSelection(): + print(FreeCADGui.Selection.getSelection()) + FreeCADGui.addModule("Draft") + self.commit(translate("draft","Join"), + ['Draft.joinWires(FreeCADGui.Selection.getSelection())', 'FreeCAD.ActiveDocument.recompute()']) + self.finish() + +class Split(Modifier): + '''The Draft_Split FreeCAD command definition.''' + + def GetResources(self): + return {'Pixmap' : 'Draft_Split', + 'Accel' : "S, P", + 'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Split", "Split"), + 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Split", "Splits a wire into two wires")} + + def Activated(self): + Modifier.Activated(self,"Split") + if not self.ui: + return + msg(translate("draft", "Select an object to split")+"\n") + self.call = self.view.addEventCallback("SoEvent", self.action) + + def action(self, arg): + "scene event handler" + if arg["Type"] == "SoKeyboardEvent": + if arg["Key"] == "ESCAPE": + self.finish() + elif arg["Type"] == "SoLocation2Event": + getPoint(self, arg) + redraw3DView() + elif arg["Type"] == "SoMouseButtonEvent" and arg["State"] == "DOWN" and arg["Button"] == "BUTTON1": + self.point, ctrlPoint, info = getPoint(self, arg) + if "Edge" in info["Component"]: + return self.proceed(info) + + def proceed(self, info): + Draft.split(FreeCAD.ActiveDocument.getObject(info["Object"]), + self.point, int(info["Component"][4:])) + if self.call: + self.view.removeEventCallback("SoEvent", self.call) + self.finish() class Upgrade(Modifier): '''The Draft_Upgrade FreeCAD command definition.''' @@ -3969,7 +4036,7 @@ class Edit(Modifier): if hasattr(self.selection[0].Proxy,"Type"): if not Draft.getType(self.selection[0]) in ["BezCurve","Wire","BSpline","Circle","Rectangle", "Polygon","Dimension","Space","Structure","PanelCut", - "PanelSheet"]: + "PanelSheet","Wall"]: msg(translate("draft", "This object type is not editable")+"\n",'warning') self.finish() return @@ -4004,10 +4071,14 @@ class Edit(Modifier): self.obj = self.obj[0] if not Draft.getType(self.obj) in ["BezCurve","Wire","BSpline","Circle","Rectangle", "Polygon","Dimension","Space","Structure","PanelCut", - "PanelSheet"]: + "PanelSheet","Wall"]: msg(translate("draft", "This object type is not editable")+"\n",'warning') self.finish() return + if Draft.getType(self.obj) == "Wall": + if Draft.getType(self.obj.Base) in ["Wire","Circle","Rectangle", + "Polygon"]: + self.obj=self.obj.Base if (Draft.getType(self.obj) == "BezCurve"): self.ui.editUi("BezCurve") else: @@ -4050,6 +4121,9 @@ class Edit(Modifier): self.editpoints.append(self.obj.Placement.Base) if self.obj.FirstAngle == self.obj.LastAngle: self.editpoints.append(self.obj.Shape.Vertexes[0].Point) + else: + self.editpoints.append(self.obj.Shape.Vertexes[0].Point) + self.editpoints.append(self.obj.Shape.Vertexes[1].Point) elif Draft.getType(self.obj) == "Rectangle": self.editpoints.append(self.obj.Placement.Base) self.editpoints.append(self.obj.Shape.Vertexes[2].Point) @@ -4096,6 +4170,12 @@ class Edit(Modifier): self.editpoints.append(self.pl.multVec(self.obj.TagPosition)) for o in self.obj.Group: self.editpoints.append(self.pl.multVec(o.Placement.Base)) + elif Draft.getType(self.obj) == "Wall": + if Draft.getType(self.obj.Base) == "Sketch": + if self.obj.Base.GeometryCount == 1: + self.editpoints.append(self.obj.Base.getPoint(0,1)) + self.editpoints.append(self.obj.Base.getPoint(0,2)) + #if self.obj.Base.GeometryCount > 1: add dialog box that asks if the user wants to enter sketch edit mode if Draft.getType(self.obj) != "BezCurve": self.trackers = [] if self.editpoints: @@ -4177,39 +4257,44 @@ class Edit(Modifier): p = FreeCADGui.ActiveDocument.ActiveView.getCursorPos() info = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo(p) if info: - if info["Object"] == self.obj.Name: - if self.ui.addButton.isChecked(): - if self.point: - pt = self.point - if "x" in info: - # prefer "real" 3D location over working-plane-driven one if possible - pt = FreeCAD.Vector(info["x"],info["y"],info["z"]) - self.addPoint(pt,info) - elif self.ui.delButton.isChecked(): - if 'EditNode' in info["Component"]: - self.delPoint(int(info["Component"][8:])) - # don't do tan/sym on DWire/BSpline! - elif ((Draft.getType(self.obj) == "BezCurve") and - (self.ui.sharpButton.isChecked())): - if 'EditNode' in info["Component"]: - self.smoothBezPoint(int(info["Component"][8:]), info, 'Sharp') - elif ((Draft.getType(self.obj) == "BezCurve") and - (self.ui.tangentButton.isChecked())): - if 'EditNode' in info["Component"]: - self.smoothBezPoint(int(info["Component"][8:]), info, 'Tangent') - elif ((Draft.getType(self.obj) == "BezCurve") and - (self.ui.symmetricButton.isChecked())): - if 'EditNode' in info["Component"]: - self.smoothBezPoint(int(info["Component"][8:]), info, 'Symmetric') - elif 'EditNode' in info["Component"]: - self.ui.pointUi() - self.ui.isRelative.show() - self.editing = int(info["Component"][8:]) - self.trackers[self.editing].off() - if hasattr(self.obj.ViewObject,"Selectable"): - self.obj.ViewObject.Selectable = False - self.node.append(self.trackers[self.editing].get()) - FreeCADGui.Snapper.setSelectMode(False) + if info["Object"] != self.obj.Name: + return + if self.ui.addButton.isChecked() \ + and Draft.getType(self.obj) == "Wire" \ + and 'Edge' in info["Component"]: + self.addPointOnEdge(FreeCAD.Vector(info["x"],info["y"],info["z"]), int(info["Component"][4:])) + elif self.ui.addButton.isChecked(): + if self.point: + pt = self.point + if "x" in info: + # prefer "real" 3D location over working-plane-driven one if possible + pt = FreeCAD.Vector(info["x"],info["y"],info["z"]) + self.addPoint(pt,info) + elif self.ui.delButton.isChecked(): + if 'EditNode' in info["Component"]: + self.delPoint(int(info["Component"][8:])) + # don't do tan/sym on DWire/BSpline! + elif ((Draft.getType(self.obj) == "BezCurve") and + (self.ui.sharpButton.isChecked())): + if 'EditNode' in info["Component"]: + self.smoothBezPoint(int(info["Component"][8:]), info, 'Sharp') + elif ((Draft.getType(self.obj) == "BezCurve") and + (self.ui.tangentButton.isChecked())): + if 'EditNode' in info["Component"]: + self.smoothBezPoint(int(info["Component"][8:]), info, 'Tangent') + elif ((Draft.getType(self.obj) == "BezCurve") and + (self.ui.symmetricButton.isChecked())): + if 'EditNode' in info["Component"]: + self.smoothBezPoint(int(info["Component"][8:]), info, 'Symmetric') + elif 'EditNode' in info["Component"]: + self.ui.pointUi() + self.ui.isRelative.show() + self.editing = int(info["Component"][8:]) + self.trackers[self.editing].off() + if hasattr(self.obj.ViewObject,"Selectable"): + self.obj.ViewObject.Selectable = False + self.node.append(self.trackers[self.editing].get()) + FreeCADGui.Snapper.setSelectMode(False) else: self.trackers[self.editing].on() #if hasattr(self.obj.ViewObject,"Selectable"): @@ -4282,15 +4367,31 @@ class Edit(Modifier): self.trackers[self.editing].set(v) elif Draft.getType(self.obj) == "Circle": delta = v.sub(self.obj.Placement.Base) + deltaX = v[0]-self.obj.Placement.Base[0] + deltaY = v[1]-self.obj.Placement.Base[1] + dangle = math.degrees(math.atan2(deltaY,deltaX)) if self.editing == 0: p = self.obj.Placement p.move(delta) self.obj.Placement = p self.trackers[0].set(self.obj.Placement.Base) + if not self.obj.FirstAngle == self.obj.LastAngle: + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) elif self.editing == 1: + if self.obj.FirstAngle == self.obj.LastAngle: + self.obj.Radius = delta.Length + self.obj.recompute() + else: + self.obj.Radius = delta.Length + self.obj.FirstAngle=dangle + self.obj.recompute() + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + elif self.editing == 2: self.obj.Radius = delta.Length + self.obj.LastAngle=dangle self.obj.recompute() - self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) elif Draft.getType(self.obj) == "Rectangle": delta = v.sub(self.obj.Placement.Base) if self.editing == 0: @@ -4351,6 +4452,15 @@ class Edit(Modifier): self.obj.TagPosition = self.invpl.multVec(v) else: self.obj.Group[self.editing-1].Placement.Base = self.invpl.multVec(v) + elif Draft.getType(self.obj) == "Wall": + if self.editing == 0: + self.obj.Base.movePoint(0,1,v) + self.obj.Base.recompute() + self.obj.recompute() + if self.editing == 1: + self.obj.Base.movePoint(0,2,v) + self.obj.Base.recompute() + self.obj.recompute() try: FreeCADGui.ActiveDocument.ActiveView.redraw() except AttributeError as err: @@ -4370,8 +4480,22 @@ class Edit(Modifier): self.ui.editUi() self.node = [] + def addPointOnEdge(self, newPoint, edgeIndex): + newPoints = [] + hasAddedPoint = False + for index, point in enumerate(self.obj.Points): + if index == edgeIndex: + hasAddedPoint = True + newPoints.append(self.invpl.multVec(newPoint)) + newPoints.append(point) + if not hasAddedPoint: + newPoints.append(point) + self.obj.Points = newPoints + self.doc.recompute() + self.resetTrackers() + def addPoint(self,point,info=None): - if not (Draft.getType(self.obj) in ["Wire","BSpline","BezCurve"]): return + if not (Draft.getType(self.obj) in ["BSpline","BezCurve"]): return pts = self.obj.Points if Draft.getType(self.obj) == "BezCurve": if not info['Component'].startswith('Edge'): @@ -4402,23 +4526,7 @@ class Edit(Modifier): cont = 1 if (self.obj.Degree >= 2) else 0 self.obj.Continuity = c[0:edgeindex]+[cont]+c[edgeindex:] else: - if ( Draft.getType(self.obj) == "Wire" ): - if (self.obj.Closed == True): - # DNC: work around.... seems there is a - # bug in approximate method for closed wires... - edges = self.obj.Shape.Wires[0].Edges - e1 = edges[-1] # last edge - v1 = e1.Vertexes[0].Point - v2 = e1.Vertexes[1].Point - v2.multiply(0.9999) - edges[-1] = Part.makeLine(v1,v2) - edges.reverse() - wire = Part.Wire(edges) - curve = wire.approximate(0.0001,0.0001,100,25) - else: - # DNC: this version is much more reliable near sharp edges! - curve = self.obj.Shape.Wires[0].approximate(0.0001,0.0001,100,25) - elif ( Draft.getType(self.obj) in ["BSpline"]): + if ( Draft.getType(self.obj) in ["BSpline"]): if (self.obj.Closed == True): curve = self.obj.Shape.Edges[0].Curve else: @@ -5801,6 +5909,8 @@ FreeCADGui.addCommand('Draft_Label',Draft_Label()) FreeCADGui.addCommand('Draft_Move',Move()) FreeCADGui.addCommand('Draft_Rotate',Rotate()) FreeCADGui.addCommand('Draft_Offset',Offset()) +FreeCADGui.addCommand('Draft_Join',Join()) +FreeCADGui.addCommand('Draft_Split',Split()) FreeCADGui.addCommand('Draft_Upgrade',Upgrade()) FreeCADGui.addCommand('Draft_Downgrade',Downgrade()) FreeCADGui.addCommand('Draft_Trimex',Trimex()) From 85604f22f65308baf49965ffb9c719d7af3013d9 Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Fri, 8 Feb 2019 23:06:35 +0100 Subject: [PATCH 2/9] Update DraftTools.py Modified arc editing: - middle editpoint control radius - end editpoint control first and last angle; --- src/Mod/Draft/DraftTools.py | 50 ++++++++++++++++++++++++++++++------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index c3c0263bbc..f59f066772 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -4121,9 +4121,14 @@ class Edit(Modifier): self.editpoints.append(self.obj.Placement.Base) if self.obj.FirstAngle == self.obj.LastAngle: self.editpoints.append(self.obj.Shape.Vertexes[0].Point) - else: - self.editpoints.append(self.obj.Shape.Vertexes[0].Point) - self.editpoints.append(self.obj.Shape.Vertexes[1].Point) + else:#self.obj is an arc + self.editpoints.append(self.obj.Shape.Vertexes[0].Point)#First endpoint + self.editpoints.append(self.obj.Shape.Vertexes[1].Point)#Second endpoint + midAngle=math.radians(self.obj.FirstAngle+(self.obj.LastAngle-self.obj.FirstAngle)/2) + midRadX=self.obj.Radius*math.cos(midAngle) + midRadY=self.obj.Radius*math.sin(midAngle) + deltaMid=FreeCAD.Vector(midRadX,midRadY,0) + self.editpoints.append(self.obj.Placement.Base+deltaMid)#Midpoint elif Draft.getType(self.obj) == "Rectangle": self.editpoints.append(self.obj.Placement.Base) self.editpoints.append(self.obj.Shape.Vertexes[2].Point) @@ -4175,7 +4180,8 @@ class Edit(Modifier): if self.obj.Base.GeometryCount == 1: self.editpoints.append(self.obj.Base.getPoint(0,1)) self.editpoints.append(self.obj.Base.getPoint(0,2)) - #if self.obj.Base.GeometryCount > 1: add dialog box that asks if the user wants to enter sketch edit mode + else: + msg("Wall base sketch is too complex to edit: it's suggested to edit directly the sketch") if Draft.getType(self.obj) != "BezCurve": self.trackers = [] if self.editpoints: @@ -4377,20 +4383,26 @@ class Edit(Modifier): self.trackers[0].set(self.obj.Placement.Base) if not self.obj.FirstAngle == self.obj.LastAngle: self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid())#self.obj is an arc elif self.editing == 1: - if self.obj.FirstAngle == self.obj.LastAngle: + if self.obj.FirstAngle == self.obj.LastAngle:#self.obj is a circle self.obj.Radius = delta.Length self.obj.recompute() - else: - self.obj.Radius = delta.Length + else:#self.obj is an arc self.obj.FirstAngle=dangle self.obj.recompute() self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) elif self.editing == 2: - self.obj.Radius = delta.Length self.obj.LastAngle=dangle self.obj.recompute() - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) + elif self.editing == 3: + self.obj.Radius = delta.Length + self.obj.recompute() + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) elif Draft.getType(self.obj) == "Rectangle": delta = v.sub(self.obj.Placement.Base) @@ -4411,6 +4423,7 @@ class Edit(Modifier): ay = -ay self.obj.Length = ax self.obj.Height = ay + self.obj.recompute() self.trackers[0].set(self.obj.Placement.Base) self.trackers[1].set(self.obj.Shape.Vertexes[2].Point) elif Draft.getType(self.obj) == "Polygon": @@ -4427,6 +4440,7 @@ class Edit(Modifier): halfangle = ((math.pi*2)/self.obj.FacesNumber)/2 rad = math.cos(halfangle)*delta.Length self.obj.Radius = rad + self.obj.recompute() self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) elif Draft.getType(self.obj) == "Dimension": if self.editing == 0: @@ -4466,6 +4480,24 @@ class Edit(Modifier): except AttributeError as err: pass + def getArcMid(self):#Returns object midpoint + if Draft.getType(self.obj) == "Circle": + #self.obj.recompute() + if self.obj.LastAngle>self.obj.FirstAngle: + midAngle=math.radians(self.obj.FirstAngle+(self.obj.LastAngle-self.obj.FirstAngle)/2) + else: + midAngle=math.radians(self.obj.FirstAngle+(self.obj.LastAngle-self.obj.FirstAngle)/2)+math.pi + midRadX=self.obj.Radius*math.cos(midAngle) + midRadY=self.obj.Radius*math.sin(midAngle) + deltaMid=FreeCAD.Vector(midRadX,midRadY,0) + midPoint=(self.obj.Placement.Base+deltaMid) + return(midPoint) + elif Draft.getType(self.obj) == "Wall": + if self.obj.Base.GeometryCount == 1: + msg("wall edit mode: get midpoint") + else: + msg("Failed to get object midpoint during Editing") + def numericInput(self,v,numy=None,numz=None): '''this function gets called by the toolbar when valid x, y, and z have been entered there''' From ef7552955a006f05f9bec06689fe16459dd906f0 Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Fri, 8 Feb 2019 23:13:15 +0100 Subject: [PATCH 3/9] Update DraftTools.py Refined last commit code --- src/Mod/Draft/DraftTools.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index f59f066772..5921ef3cd6 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -4124,11 +4124,7 @@ class Edit(Modifier): else:#self.obj is an arc self.editpoints.append(self.obj.Shape.Vertexes[0].Point)#First endpoint self.editpoints.append(self.obj.Shape.Vertexes[1].Point)#Second endpoint - midAngle=math.radians(self.obj.FirstAngle+(self.obj.LastAngle-self.obj.FirstAngle)/2) - midRadX=self.obj.Radius*math.cos(midAngle) - midRadY=self.obj.Radius*math.sin(midAngle) - deltaMid=FreeCAD.Vector(midRadX,midRadY,0) - self.editpoints.append(self.obj.Placement.Base+deltaMid)#Midpoint + self.editpoints.append(self.getArcMid())#Midpoint elif Draft.getType(self.obj) == "Rectangle": self.editpoints.append(self.obj.Placement.Base) self.editpoints.append(self.obj.Shape.Vertexes[2].Point) From c88fadde54201f177b15ea2a689b9acb70be9d62 Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Fri, 8 Feb 2019 23:27:21 +0100 Subject: [PATCH 4/9] Update DraftTools.py Updated first part of file from FreeCAD/FreeCAD --- src/Mod/Draft/DraftTools.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 5921ef3cd6..c017bc330f 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -77,7 +77,7 @@ MODALT = MODS[Draft.getParam("modalt",2)] def msg(text=None,mode=None): "prints the given message on the FreeCAD status bar" if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("Verbose",True): - if not text: + if not text: FreeCAD.Console.PrintMessage("") else: if mode == 'warning': @@ -779,7 +779,7 @@ class Wire(Line): class BSpline(Line): - "a FreeCAD command for creating a b-spline" + "a FreeCAD command for creating a B-spline" def __init__(self): Line.__init__(self,wiremode=True) @@ -2900,7 +2900,7 @@ class Stretch(Modifier): def proceed(self): if self.call: - self.view.removeEventCallback("SoEvent",self.call) + self.view.removeEventCallback("SoEvent",self.call) supported = ["Rectangle","Wire","BSpline","BezCurve","Sketch"] self.sel = [] for obj in FreeCADGui.Selection.getSelection(): @@ -2910,7 +2910,7 @@ class Stretch(Modifier): if obj.Base: if Draft.getType(obj.Base) in supported: self.sel.append([obj.Base,obj.Placement]) - + elif Draft.getType(obj.Base) in ["Offset2D","Array"]: base = None if hasattr(obj.Base,"Source") and obj.Base.Source: @@ -4005,7 +4005,6 @@ class ToggleDisplayMode(): if "Flat Lines" in obj.ViewObject.listDisplayModes(): obj.ViewObject.DisplayMode = "Flat Lines" - class Edit(Modifier): "The Draft_Edit FreeCAD command definition" From 3b4aaab869aaea750956bccf29b7e583b4079313 Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Sun, 10 Feb 2019 11:55:26 +0100 Subject: [PATCH 5/9] Edit tool Arc 3 points editing Updated the edit tool to edit arc by 3 points. Just a dubt: i did a bit of a workaround using Part.ArcOfCircle to compute the values of the new arc. --- src/Mod/Draft/DraftGui.py | 21 ++++- src/Mod/Draft/DraftTools.py | 149 ++++++++++++++++++++++++------------ 2 files changed, 118 insertions(+), 52 deletions(-) diff --git a/src/Mod/Draft/DraftGui.py b/src/Mod/Draft/DraftGui.py index f3e1caf67d..6cb6d516a6 100644 --- a/src/Mod/Draft/DraftGui.py +++ b/src/Mod/Draft/DraftGui.py @@ -503,6 +503,7 @@ class DraftToolBar: self.sharpButton = self._pushbutton("sharpButton", self.layout, icon="Draft_BezSharpNode", width=22, checkable=True) self.tangentButton = self._pushbutton("tangentButton", self.layout, icon="Draft_BezTanNode", width=22, checkable=True) self.symmetricButton = self._pushbutton("symmetricButton", self.layout, icon="Draft_BezSymNode", width=22, checkable=True) + self.arc3PtButton = self._pushbutton("arc3PtButton", self.layout, icon="Draft_BezSymNode", width=22, checkable=True) # point @@ -647,6 +648,7 @@ class DraftToolBar: QtCore.QObject.connect(self.sharpButton,QtCore.SIGNAL("toggled(bool)"),self.setSharpMode) QtCore.QObject.connect(self.tangentButton,QtCore.SIGNAL("toggled(bool)"),self.setTangentMode) QtCore.QObject.connect(self.symmetricButton,QtCore.SIGNAL("toggled(bool)"),self.setSymmetricMode) + QtCore.QObject.connect(self.arc3PtButton,QtCore.SIGNAL("toggled(bool)"),self.arc3PtMode) QtCore.QObject.connect(self.finishButton,QtCore.SIGNAL("pressed()"),self.finish) QtCore.QObject.connect(self.closeButton,QtCore.SIGNAL("pressed()"),self.closeLine) QtCore.QObject.connect(self.wipeButton,QtCore.SIGNAL("pressed()"),self.wipeLine) @@ -791,6 +793,7 @@ class DraftToolBar: self.sharpButton.setToolTip(translate("draft", "Make Bezier node sharp")) self.tangentButton.setToolTip(translate("draft", "Make Bezier node tangent")) self.symmetricButton.setToolTip(translate("draft", "Make Bezier node symmetric")) + self.arc3PtButton.setToolTip(translate("draft", "Activate 3 point arc editing")) self.undoButton.setText(translate("draft", "&Undo (CTRL+Z)")) self.undoButton.setToolTip(translate("draft", "Undo the last segment")) self.closeButton.setText(translate("draft", "Close")+" ("+inCommandShortcuts["Close"][0]+")") @@ -1057,6 +1060,7 @@ class DraftToolBar: self.sharpButton.hide() self.tangentButton.hide() self.symmetricButton.hide() + self.arc3PtButton.hide() self.undoButton.hide() self.closeButton.hide() self.wipeButton.hide() @@ -1187,6 +1191,7 @@ class DraftToolBar: self.makeDumbTask(extra,callback) def editUi(self, mode=None): + self.lastMode=mode self.taskUi(translate("draft", "Edit")) self.hideXYZ() self.numFaces.hide() @@ -1194,18 +1199,26 @@ class DraftToolBar: self.hasFill.hide() self.addButton.show() self.delButton.show() - if mode == 'BezCurve': + if mode == 'Wire': + self.setEditButtons(True) + self.setBezEditButtons(False) + elif mode == 'Arc': + self.addButton.hide() + self.delButton.hide() + self.arc3PtButton.show() + elif mode == 'BezCurve': self.sharpButton.show() self.tangentButton.show() self.symmetricButton.show() - self.finishButton.show() self.closeButton.show() + self.finishButton.show() # always start Edit with buttons unchecked self.addButton.setChecked(False) self.delButton.setChecked(False) self.sharpButton.setChecked(False) self.tangentButton.setChecked(False) self.symmetricButton.setChecked(False) + self.arc3PtButton.setChecked(False) def extUi(self): self.hasFill.show() @@ -1968,6 +1981,10 @@ class DraftToolBar: self.addButton.setChecked(False) self.delButton.setChecked(False) + def arc3PtMode(self,bool): + if self.arc3PtButton.isChecked(): + self.arc3PtButton.setChecked(True) + def setRadiusValue(self,val,unit=None): #print("DEBUG: setRadiusValue val: ", val, " unit: ", unit) if not isinstance(val, (int, float)): #??some code passes strings or ??? diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index c017bc330f..f0786882f2 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -4068,46 +4068,40 @@ class Edit(Modifier): self.obj = FreeCADGui.Selection.getSelection() if self.obj: self.obj = self.obj[0] + # we could skip next passage putting an "else" at the end of the proceed function if not Draft.getType(self.obj) in ["BezCurve","Wire","BSpline","Circle","Rectangle", "Polygon","Dimension","Space","Structure","PanelCut", "PanelSheet","Wall"]: msg(translate("draft", "This object type is not editable")+"\n",'warning') self.finish() return - if Draft.getType(self.obj) == "Wall": - if Draft.getType(self.obj.Base) in ["Wire","Circle","Rectangle", - "Polygon"]: - self.obj=self.obj.Base - if (Draft.getType(self.obj) == "BezCurve"): - self.ui.editUi("BezCurve") - else: - self.ui.editUi() # store selectable state of the object if hasattr(self.obj.ViewObject,"Selectable"): self.selectstate = self.obj.ViewObject.Selectable self.obj.ViewObject.Selectable = False FreeCADGui.Selection.clearSelection() - if Draft.getType(self.obj) in ["Wire","BSpline"]: - self.ui.setEditButtons(True) - self.ui.setBezEditButtons(False) - elif Draft.getType(self.obj) == "BezCurve": - self.ui.setEditButtons(True) - self.ui.setBezEditButtons(True) - else: - self.ui.setEditButtons(False) - self.ui.setBezEditButtons(False) self.editing = None self.editpoints = [] self.pl = None + self.arc3Pt = False FreeCADGui.Snapper.setSelectMode(True) + # Edit Gui setup is moved inside each kind of object + # overwrite self.obj to match the right editing target + if Draft.getType(self.obj) == "Wall": + if Draft.getType(self.obj.Base) in ["Wire","Circle","Rectangle", + "Polygon"]: + self.obj=self.obj.Base if "Placement" in self.obj.PropertiesList: self.pl = self.obj.Placement self.invpl = self.pl.inverse() + # setup of different object type (set editUi, set editTrackers) if Draft.getType(self.obj) in ["Wire","BSpline"]: + self.ui.editUi("Wire") for p in self.obj.Points: if self.pl: p = self.pl.multVec(p) self.editpoints.append(p) elif Draft.getType(self.obj) == "BezCurve": + self.ui.editUi("BezCurve") self.resetTrackersBezier() self.call = self.view.addEventCallback("SoEvent",self.action) self.running = True @@ -4118,13 +4112,16 @@ class Edit(Modifier): self.planetrack.set(self.editpoints[0]) elif Draft.getType(self.obj) == "Circle": self.editpoints.append(self.obj.Placement.Base) - if self.obj.FirstAngle == self.obj.LastAngle: + if self.obj.FirstAngle == self.obj.LastAngle:#self.obj is a circle + self.ui.editUi("Circle") self.editpoints.append(self.obj.Shape.Vertexes[0].Point) else:#self.obj is an arc + self.ui.editUi("Arc") self.editpoints.append(self.obj.Shape.Vertexes[0].Point)#First endpoint self.editpoints.append(self.obj.Shape.Vertexes[1].Point)#Second endpoint self.editpoints.append(self.getArcMid())#Midpoint elif Draft.getType(self.obj) == "Rectangle": + self.ui.editUi() self.editpoints.append(self.obj.Placement.Base) self.editpoints.append(self.obj.Shape.Vertexes[2].Point) v = self.obj.Shape.Vertexes @@ -4135,20 +4132,24 @@ class Edit(Modifier): if self.obj.Height < 0: self.by = self.by.negative() elif Draft.getType(self.obj) == "Polygon": + self.ui.editUi() self.editpoints.append(self.obj.Placement.Base) self.editpoints.append(self.obj.Shape.Vertexes[0].Point) elif Draft.getType(self.obj) == "Dimension": + self.ui.editUi() p = self.obj.ViewObject.Proxy.textpos.translation.getValue() self.editpoints.append(self.obj.Start) self.editpoints.append(self.obj.End) self.editpoints.append(self.obj.Dimline) self.editpoints.append(Vector(p[0],p[1],p[2])) elif Draft.getType(self.obj) == "Space": + self.ui.editUi() try: self.editpoints.append(self.obj.ViewObject.Proxy.getTextPosition(self.obj.ViewObject)) except: pass elif Draft.getType(self.obj) == "Structure": + self.ui.editUi() if self.obj.Nodes: self.originalDisplayMode = self.obj.ViewObject.DisplayMode self.originalPoints = self.obj.ViewObject.NodeSize @@ -4161,16 +4162,19 @@ class Edit(Modifier): p = self.pl.multVec(p) self.editpoints.append(p) elif Draft.getType(self.obj) == "PanelCut": + self.ui.editUi() if self.obj.TagPosition.Length == 0: pos = self.obj.Shape.BoundBox.Center else: pos = self.pl.multVec(self.obj.TagPosition) self.editpoints.append(pos) elif Draft.getType(self.obj) == "PanelSheet": + self.ui.editUi() self.editpoints.append(self.pl.multVec(self.obj.TagPosition)) for o in self.obj.Group: self.editpoints.append(self.pl.multVec(o.Placement.Base)) elif Draft.getType(self.obj) == "Wall": + self.ui.editUi() if Draft.getType(self.obj.Base) == "Sketch": if self.obj.Base.GeometryCount == 1: self.editpoints.append(self.obj.Base.getPoint(0,1)) @@ -4288,6 +4292,10 @@ class Edit(Modifier): if 'EditNode' in info["Component"]: self.smoothBezPoint(int(info["Component"][8:]), info, 'Symmetric') elif 'EditNode' in info["Component"]: + if self.ui.arc3PtButton.isChecked(): + self.arc3Pt = True#store arc 3 points edit mode + else: + self.arc3Pt = False#decide if it's deselected after every editing point self.ui.pointUi() self.ui.isRelative.show() self.editing = int(info["Component"][8:]) @@ -4368,37 +4376,83 @@ class Edit(Modifier): self.trackers[self.editing].set(v) elif Draft.getType(self.obj) == "Circle": delta = v.sub(self.obj.Placement.Base) - deltaX = v[0]-self.obj.Placement.Base[0] - deltaY = v[1]-self.obj.Placement.Base[1] - dangle = math.degrees(math.atan2(deltaY,deltaX)) - if self.editing == 0: - p = self.obj.Placement - p.move(delta) - self.obj.Placement = p - self.trackers[0].set(self.obj.Placement.Base) - if not self.obj.FirstAngle == self.obj.LastAngle: - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid())#self.obj is an arc - elif self.editing == 1: - if self.obj.FirstAngle == self.obj.LastAngle:#self.obj is a circle + if self.obj.FirstAngle == self.obj.LastAngle:# object is a circle + if self.editing == 0: + p = self.obj.Placement + p.move(delta) + self.obj.Placement = p + self.trackers[0].set(self.obj.Placement.Base) + if self.editing == 1: self.obj.Radius = delta.Length self.obj.recompute() - else:#self.obj is an arc - self.obj.FirstAngle=dangle + self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) + else:#self.obj is an arc + if self.arc3Pt == False:#edit by center radius FirstAngle LastAngle + msg("CENTRO E RAGGIO") + deltaX = v[0]-self.obj.Placement.Base[0] + deltaY = v[1]-self.obj.Placement.Base[1] + dangle = math.degrees(math.atan2(deltaY,deltaX)) + if self.editing == 0: + p = self.obj.Placement + p.move(delta) + self.obj.Placement = p + self.trackers[0].set(self.obj.Placement.Base) + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) + elif self.editing == 1: + self.obj.FirstAngle=dangle + self.obj.recompute() + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) + elif self.editing == 2: + self.obj.LastAngle=dangle + self.obj.recompute() + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) + elif self.editing == 3: + self.obj.Radius = delta.Length + self.obj.recompute() + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) + self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) + elif self.arc3Pt: + msg("3 PUNTI") + if self.editing == 0:#keep everithing as it is for the moment + p1=self.obj.Shape.Vertexes[0].Point + p2=self.getArcMid() + p3=self.obj.Shape.Vertexes[1].Point + arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? + if self.editing == 1: + p1=v + p2=self.getArcMid() + p3=self.obj.Shape.Vertexes[1].Point + arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? + elif self.editing == 3: + p1=self.obj.Shape.Vertexes[0].Point + p2=v + p3=self.obj.Shape.Vertexes[1].Point + arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? + elif self.editing == 2: + p1=self.obj.Shape.Vertexes[0].Point + p2=self.getArcMid() + p3=v + arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? + self.obj.Placement.Base=arc.Center + self.obj.Radius = arc.Radius + deltaX = p1[0]-self.obj.Placement.Base[0] + deltaY = p1[1]-self.obj.Placement.Base[1] + dangleF = math.degrees(math.atan2(deltaY,deltaX)) + deltaX = p3[0]-self.obj.Placement.Base[0] + deltaY = p3[1]-self.obj.Placement.Base[1] + dangleL = math.degrees(math.atan2(deltaY,deltaX)) + self.obj.FirstAngle = dangleF + self.obj.LastAngle = dangleL self.obj.recompute() + self.trackers[0].set(self.obj.Placement.Base) + self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) self.trackers[3].set(self.getArcMid()) - elif self.editing == 2: - self.obj.LastAngle=dangle - self.obj.recompute() - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid()) - elif self.editing == 3: - self.obj.Radius = delta.Length - self.obj.recompute() - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid()) - self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) + elif Draft.getType(self.obj) == "Rectangle": delta = v.sub(self.obj.Placement.Base) if self.editing == 0: @@ -4477,7 +4531,6 @@ class Edit(Modifier): def getArcMid(self):#Returns object midpoint if Draft.getType(self.obj) == "Circle": - #self.obj.recompute() if self.obj.LastAngle>self.obj.FirstAngle: midAngle=math.radians(self.obj.FirstAngle+(self.obj.LastAngle-self.obj.FirstAngle)/2) else: @@ -4501,10 +4554,7 @@ class Edit(Modifier): self.update(v) self.doc.recompute() self.editing = None - if (Draft.getType(self.obj) == "BezCurve"): - self.ui.editUi("BezCurve") - else: - self.ui.editUi() + self.ui.editUi(self.ui.lastMode) self.node = [] def addPointOnEdge(self, newPoint, edgeIndex): @@ -4701,7 +4751,6 @@ class Edit(Modifier): objPoints = self.obj.Points[ep] if self.pl: objPoints = self.pl.multVec(objPoints) self.trackers.append(editTracker(objPoints,self.obj.Name,ep,self.obj.ViewObject.LineColor)) - class AddToGroup(): "The AddToGroup FreeCAD command definition" From 0091f2513ea6464716b36d7ddf8433be7dfcf777 Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Sun, 10 Feb 2019 12:03:26 +0100 Subject: [PATCH 6/9] Update DraftGui.py added value to store last edit toolbar mode --- src/Mod/Draft/DraftGui.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Mod/Draft/DraftGui.py b/src/Mod/Draft/DraftGui.py index 6cb6d516a6..3d76de4076 100644 --- a/src/Mod/Draft/DraftGui.py +++ b/src/Mod/Draft/DraftGui.py @@ -367,6 +367,7 @@ class DraftToolBar: self.uiloader = FreeCADGui.UiLoader() self.autogroup = None self.isCenterPlane = False + self.lastMode = None if self.taskmode: # add only a dummy widget, since widgets are created on demand From 8aa1cee1f9a9396f8b5d8205d2345a00a362c15f Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Sun, 10 Feb 2019 22:44:09 +0100 Subject: [PATCH 7/9] Update DraftTools.py --- src/Mod/Draft/DraftTools.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index f0786882f2..b76f0a8584 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -4388,7 +4388,6 @@ class Edit(Modifier): self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) else:#self.obj is an arc if self.arc3Pt == False:#edit by center radius FirstAngle LastAngle - msg("CENTRO E RAGGIO") deltaX = v[0]-self.obj.Placement.Base[0] deltaY = v[1]-self.obj.Placement.Base[1] dangle = math.degrees(math.atan2(deltaY,deltaX)) @@ -4416,7 +4415,6 @@ class Edit(Modifier): self.trackers[3].set(self.getArcMid()) self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) elif self.arc3Pt: - msg("3 PUNTI") if self.editing == 0:#keep everithing as it is for the moment p1=self.obj.Shape.Vertexes[0].Point p2=self.getArcMid() From dea44454c6fc7cae626fa5dd6a2b5033173b8432 Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Wed, 13 Feb 2019 16:40:26 +0100 Subject: [PATCH 8/9] Update Edit Tool Arc 3 points and minor other fixes --- src/Mod/Draft/DraftGui.py | 8 ++++---- src/Mod/Draft/DraftTools.py | 21 +++++++++++++++++---- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/Mod/Draft/DraftGui.py b/src/Mod/Draft/DraftGui.py index 3d76de4076..16fc091252 100644 --- a/src/Mod/Draft/DraftGui.py +++ b/src/Mod/Draft/DraftGui.py @@ -504,7 +504,7 @@ class DraftToolBar: self.sharpButton = self._pushbutton("sharpButton", self.layout, icon="Draft_BezSharpNode", width=22, checkable=True) self.tangentButton = self._pushbutton("tangentButton", self.layout, icon="Draft_BezTanNode", width=22, checkable=True) self.symmetricButton = self._pushbutton("symmetricButton", self.layout, icon="Draft_BezSymNode", width=22, checkable=True) - self.arc3PtButton = self._pushbutton("arc3PtButton", self.layout, icon="Draft_BezSymNode", width=22, checkable=True) + self.arc3PtButton = self._pushbutton("arc3PtButton", self.layout, icon="Draft_Arc", width=22, checkable=True) # point @@ -649,7 +649,7 @@ class DraftToolBar: QtCore.QObject.connect(self.sharpButton,QtCore.SIGNAL("toggled(bool)"),self.setSharpMode) QtCore.QObject.connect(self.tangentButton,QtCore.SIGNAL("toggled(bool)"),self.setTangentMode) QtCore.QObject.connect(self.symmetricButton,QtCore.SIGNAL("toggled(bool)"),self.setSymmetricMode) - QtCore.QObject.connect(self.arc3PtButton,QtCore.SIGNAL("toggled(bool)"),self.arc3PtMode) + QtCore.QObject.connect(self.arc3PtButton,QtCore.SIGNAL("toggled(bool)"),self.setArc3PtMode) QtCore.QObject.connect(self.finishButton,QtCore.SIGNAL("pressed()"),self.finish) QtCore.QObject.connect(self.closeButton,QtCore.SIGNAL("pressed()"),self.closeLine) QtCore.QObject.connect(self.wipeButton,QtCore.SIGNAL("pressed()"),self.wipeLine) @@ -794,7 +794,7 @@ class DraftToolBar: self.sharpButton.setToolTip(translate("draft", "Make Bezier node sharp")) self.tangentButton.setToolTip(translate("draft", "Make Bezier node tangent")) self.symmetricButton.setToolTip(translate("draft", "Make Bezier node symmetric")) - self.arc3PtButton.setToolTip(translate("draft", "Activate 3 point arc editing")) + self.arc3PtButton.setToolTip(translate("draft", "Toggle radius and angles arc editing")) self.undoButton.setText(translate("draft", "&Undo (CTRL+Z)")) self.undoButton.setToolTip(translate("draft", "Undo the last segment")) self.closeButton.setText(translate("draft", "Close")+" ("+inCommandShortcuts["Close"][0]+")") @@ -1982,7 +1982,7 @@ class DraftToolBar: self.addButton.setChecked(False) self.delButton.setChecked(False) - def arc3PtMode(self,bool): + def setArc3PtMode(self,bool): if self.arc3PtButton.isChecked(): self.arc3PtButton.setChecked(True) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index b76f0a8584..3aef2d562c 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -4241,7 +4241,10 @@ class Edit(Modifier): elif arg["Key"] == "f": self.finish() elif arg["Key"] == "c": - self.finish(closed=True) + self.finish(closed=True) + elif arg["Key"] == "i": + if (arg["State"] == "DOWN") and Draft.getType(self.obj) == "Circle": + self.arcInvert() elif arg["Type"] == "SoLocation2Event": #mouse movement detection self.point,ctrlPoint,info = getPoint(self,arg) if self.editing != None: @@ -4387,7 +4390,7 @@ class Edit(Modifier): self.obj.recompute() self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) else:#self.obj is an arc - if self.arc3Pt == False:#edit by center radius FirstAngle LastAngle + if self.arc3Pt == True:#edit by center radius FirstAngle LastAngle deltaX = v[0]-self.obj.Placement.Base[0] deltaY = v[1]-self.obj.Placement.Base[1] dangle = math.degrees(math.atan2(deltaY,deltaX)) @@ -4414,7 +4417,7 @@ class Edit(Modifier): self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) self.trackers[3].set(self.getArcMid()) self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) - elif self.arc3Pt: + elif self.arc3Pt == False: if self.editing == 0:#keep everithing as it is for the moment p1=self.obj.Shape.Vertexes[0].Point p2=self.getArcMid() @@ -4543,7 +4546,16 @@ class Edit(Modifier): msg("wall edit mode: get midpoint") else: msg("Failed to get object midpoint during Editing") - + + def arcInvert(self): + FA=self.obj.FirstAngle + self.obj.FirstAngle=self.obj.LastAngle + self.obj.LastAngle=FA + self.obj.recompute() + self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + self.trackers[3].set(self.getArcMid()) + def numericInput(self,v,numy=None,numz=None): '''this function gets called by the toolbar when valid x, y, and z have been entered there''' @@ -4749,6 +4761,7 @@ class Edit(Modifier): objPoints = self.obj.Points[ep] if self.pl: objPoints = self.pl.multVec(objPoints) self.trackers.append(editTracker(objPoints,self.obj.Name,ep,self.obj.ViewObject.LineColor)) + class AddToGroup(): "The AddToGroup FreeCAD command definition" From 8ee0b6859edf7b7cd0a329ddeadf91cfa933470c Mon Sep 17 00:00:00 2001 From: carlopav <47068848+carlopav@users.noreply.github.com> Date: Tue, 19 Feb 2019 16:40:43 +0100 Subject: [PATCH 9/9] Update DraftTools.py Update draf edit to: - improve arc editing - insert Undo marks - insert initial window editing support --- src/Mod/Draft/DraftTools.py | 350 ++++++++++++++++++++++-------------- 1 file changed, 219 insertions(+), 131 deletions(-) diff --git a/src/Mod/Draft/DraftTools.py b/src/Mod/Draft/DraftTools.py index 3aef2d562c..0cb7057ced 100644 --- a/src/Mod/Draft/DraftTools.py +++ b/src/Mod/Draft/DraftTools.py @@ -3334,7 +3334,6 @@ class Downgrade(Modifier): 'FreeCAD.ActiveDocument.recompute()']) self.finish() - class Trimex(Modifier): ''' The Draft_Trimex FreeCAD command definition. This tool trims or extends lines, wires and arcs, @@ -4026,33 +4025,28 @@ class Edit(Modifier): def Activated(self): if self.running: self.finish() - else: - Modifier.Activated(self,"Edit") - if FreeCADGui.Selection.getSelection(): - self.selection = FreeCADGui.Selection.getSelection() - if len(self.selection) == 1: - if "Proxy" in self.selection[0].PropertiesList: - if hasattr(self.selection[0].Proxy,"Type"): - if not Draft.getType(self.selection[0]) in ["BezCurve","Wire","BSpline","Circle","Rectangle", - "Polygon","Dimension","Space","Structure","PanelCut", - "PanelSheet","Wall"]: - msg(translate("draft", "This object type is not editable")+"\n",'warning') - self.finish() - return + + Modifier.Activated(self,"Edit") + + if FreeCADGui.Selection.getSelection(): + self.selection = FreeCADGui.Selection.getSelection() + if len(self.selection) == 1: + if "Proxy" in self.selection[0].PropertiesList: + if hasattr(self.selection[0].Proxy,"Type"): + if Draft.getType(self.selection[0]) in ["BezCurve","Wire","BSpline","Circle","Rectangle", + "Polygon","Dimension","Space","Structure","PanelCut", + "PanelSheet","Wall", "Window"]: self.proceed() return - else: - msg(translate("draft", "This object type is not editable")+"\n",'warning') - self.finish() - return - else: - msg(translate("draft", "This object type is not editable")+"\n",'warning') - self.finish() - return - else: - msg(translate("draft", "Please select only one object")+"\n",'warning') - self.finish() - return + #ELSE: + msg(translate("draft", "This object type is not editable")+"\n",'warning') + self.finish() + return + else: + msg(translate("draft", "Please select only one object")+"\n",'warning') + self.finish() + return + else: self.ghost = None self.ui.selectUi() msg(translate("draft", "Select a Draft object to edit")+"\n") @@ -4068,38 +4062,45 @@ class Edit(Modifier): self.obj = FreeCADGui.Selection.getSelection() if self.obj: self.obj = self.obj[0] - # we could skip next passage putting an "else" at the end of the proceed function + if not Draft.getType(self.obj) in ["BezCurve","Wire","BSpline","Circle","Rectangle", "Polygon","Dimension","Space","Structure","PanelCut", - "PanelSheet","Wall"]: + "PanelSheet","Wall", "Window"]: msg(translate("draft", "This object type is not editable")+"\n",'warning') self.finish() return + # store selectable state of the object if hasattr(self.obj.ViewObject,"Selectable"): self.selectstate = self.obj.ViewObject.Selectable self.obj.ViewObject.Selectable = False + FreeCADGui.Selection.clearSelection() self.editing = None self.editpoints = [] self.pl = None self.arc3Pt = False FreeCADGui.Snapper.setSelectMode(True) + # Edit Gui setup is moved inside each kind of object + # overwrite self.obj to match the right editing target if Draft.getType(self.obj) == "Wall": if Draft.getType(self.obj.Base) in ["Wire","Circle","Rectangle", "Polygon"]: self.obj=self.obj.Base + if "Placement" in self.obj.PropertiesList: self.pl = self.obj.Placement self.invpl = self.pl.inverse() # setup of different object type (set editUi, set editTrackers) + if Draft.getType(self.obj) in ["Wire","BSpline"]: self.ui.editUi("Wire") for p in self.obj.Points: if self.pl: p = self.pl.multVec(p) self.editpoints.append(p) + elif Draft.getType(self.obj) == "BezCurve": self.ui.editUi("BezCurve") self.resetTrackersBezier() @@ -4110,16 +4111,10 @@ class Edit(Modifier): plane.alignToFace(self.obj.Shape) if self.planetrack: self.planetrack.set(self.editpoints[0]) + elif Draft.getType(self.obj) == "Circle": - self.editpoints.append(self.obj.Placement.Base) - if self.obj.FirstAngle == self.obj.LastAngle:#self.obj is a circle - self.ui.editUi("Circle") - self.editpoints.append(self.obj.Shape.Vertexes[0].Point) - else:#self.obj is an arc - self.ui.editUi("Arc") - self.editpoints.append(self.obj.Shape.Vertexes[0].Point)#First endpoint - self.editpoints.append(self.obj.Shape.Vertexes[1].Point)#Second endpoint - self.editpoints.append(self.getArcMid())#Midpoint + self.setCirclePts() + elif Draft.getType(self.obj) == "Rectangle": self.ui.editUi() self.editpoints.append(self.obj.Placement.Base) @@ -4131,10 +4126,12 @@ class Edit(Modifier): self.by = v[2].Point.sub(v[1].Point) if self.obj.Height < 0: self.by = self.by.negative() + elif Draft.getType(self.obj) == "Polygon": self.ui.editUi() self.editpoints.append(self.obj.Placement.Base) self.editpoints.append(self.obj.Shape.Vertexes[0].Point) + elif Draft.getType(self.obj) == "Dimension": self.ui.editUi() p = self.obj.ViewObject.Proxy.textpos.translation.getValue() @@ -4142,12 +4139,37 @@ class Edit(Modifier): self.editpoints.append(self.obj.End) self.editpoints.append(self.obj.Dimline) self.editpoints.append(Vector(p[0],p[1],p[2])) + + elif Draft.getType(self.obj) == "Wall": + self.ui.editUi() + if Draft.getType(self.obj.Base) == "Sketch": + if self.obj.Base.GeometryCount == 1: + self.editpoints.append(self.obj.Base.getPoint(0,1)) + self.editpoints.append(self.obj.Base.getPoint(0,2)) + else: + msg(translate("draft","Wall base sketch is too complex to edit: it's suggested to edit directly the sketch")+"\n",'warning') + + elif Draft.getType(self.obj) == "Window": + msg("Window was found \n") + self.ui.editUi() + import DraftGeomUtils + pos=self.obj.Base.Placement.Base + h=float(self.obj.Height)+pos.z + normal=self.obj.Normal + angle=normal.getAngle(FreeCAD.Vector(1,0,0)) + self.editpoints.append(pos) + self.editpoints.append(FreeCAD.Vector(pos.x+float(self.obj.Width)*math.cos(angle-math.pi/2), + pos.y+float(self.obj.Width)*math.sin(angle-math.pi/2), + pos.z)) + self.editpoints.append(FreeCAD.Vector(pos.x,pos.y,h)) + elif Draft.getType(self.obj) == "Space": self.ui.editUi() try: self.editpoints.append(self.obj.ViewObject.Proxy.getTextPosition(self.obj.ViewObject)) except: pass + elif Draft.getType(self.obj) == "Structure": self.ui.editUi() if self.obj.Nodes: @@ -4161,6 +4183,7 @@ class Edit(Modifier): if self.pl: p = self.pl.multVec(p) self.editpoints.append(p) + elif Draft.getType(self.obj) == "PanelCut": self.ui.editUi() if self.obj.TagPosition.Length == 0: @@ -4168,19 +4191,13 @@ class Edit(Modifier): else: pos = self.pl.multVec(self.obj.TagPosition) self.editpoints.append(pos) + elif Draft.getType(self.obj) == "PanelSheet": self.ui.editUi() self.editpoints.append(self.pl.multVec(self.obj.TagPosition)) for o in self.obj.Group: self.editpoints.append(self.pl.multVec(o.Placement.Base)) - elif Draft.getType(self.obj) == "Wall": - self.ui.editUi() - if Draft.getType(self.obj.Base) == "Sketch": - if self.obj.Base.GeometryCount == 1: - self.editpoints.append(self.obj.Base.getPoint(0,1)) - self.editpoints.append(self.obj.Base.getPoint(0,2)) - else: - msg("Wall base sketch is too complex to edit: it's suggested to edit directly the sketch") + if Draft.getType(self.obj) != "BezCurve": self.trackers = [] if self.editpoints: @@ -4197,6 +4214,7 @@ class Edit(Modifier): else: msg(translate("draft", "This object type is not editable")+"\n",'warning') self.finish() + else: self.finish() @@ -4235,6 +4253,7 @@ class Edit(Modifier): def action(self,arg): "scene event handler" + if arg["Type"] == "SoKeyboardEvent": if arg["Key"] == "ESCAPE": self.finish() @@ -4245,6 +4264,7 @@ class Edit(Modifier): elif arg["Key"] == "i": if (arg["State"] == "DOWN") and Draft.getType(self.obj) == "Circle": self.arcInvert() + elif arg["Type"] == "SoLocation2Event": #mouse movement detection self.point,ctrlPoint,info = getPoint(self,arg) if self.editing != None: @@ -4258,13 +4278,31 @@ class Edit(Modifier): else: self.obj.ViewObject.Selectable = False redraw3DView() + elif arg["Type"] == "SoMouseButtonEvent": + if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"): self.ui.redraw() + if self.editing == None: p = FreeCADGui.ActiveDocument.ActiveView.getCursorPos() - info = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo(p) + info = FreeCADGui.ActiveDocument.ActiveView.getObjectInfo(p) + msg(info) + msg("\n") + selObjs = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo(p) + msg(selObjs) if info: +# for selObj in selObjs: +# msg(print(selObj)) +# if 'EditNode' in selObj["Component"]: +# info = selObj +# #msg("edit node") +# #msg(info) +# break +# else: +# info=selObjs[0] +# #msg("/n oggetto") +# #msg(info) if info["Object"] != self.obj.Name: return if self.ui.addButton.isChecked() \ @@ -4315,6 +4353,7 @@ class Edit(Modifier): self.numericInput(self.trackers[self.editing].get()) def update(self,v): + self.doc.openTransaction("Edit") if Draft.getType(self.obj) in ["Wire","BSpline","BezCurve"]: pts = self.obj.Points editPnt = self.invpl.multVec(v) @@ -4377,82 +4416,9 @@ class Edit(Modifier): pts[self.editing] = editPnt self.obj.Points = pts self.trackers[self.editing].set(v) + elif Draft.getType(self.obj) == "Circle": - delta = v.sub(self.obj.Placement.Base) - if self.obj.FirstAngle == self.obj.LastAngle:# object is a circle - if self.editing == 0: - p = self.obj.Placement - p.move(delta) - self.obj.Placement = p - self.trackers[0].set(self.obj.Placement.Base) - if self.editing == 1: - self.obj.Radius = delta.Length - self.obj.recompute() - self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) - else:#self.obj is an arc - if self.arc3Pt == True:#edit by center radius FirstAngle LastAngle - deltaX = v[0]-self.obj.Placement.Base[0] - deltaY = v[1]-self.obj.Placement.Base[1] - dangle = math.degrees(math.atan2(deltaY,deltaX)) - if self.editing == 0: - p = self.obj.Placement - p.move(delta) - self.obj.Placement = p - self.trackers[0].set(self.obj.Placement.Base) - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid()) - elif self.editing == 1: - self.obj.FirstAngle=dangle - self.obj.recompute() - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid()) - elif self.editing == 2: - self.obj.LastAngle=dangle - self.obj.recompute() - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid()) - elif self.editing == 3: - self.obj.Radius = delta.Length - self.obj.recompute() - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid()) - self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) - elif self.arc3Pt == False: - if self.editing == 0:#keep everithing as it is for the moment - p1=self.obj.Shape.Vertexes[0].Point - p2=self.getArcMid() - p3=self.obj.Shape.Vertexes[1].Point - arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? - if self.editing == 1: - p1=v - p2=self.getArcMid() - p3=self.obj.Shape.Vertexes[1].Point - arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? - elif self.editing == 3: - p1=self.obj.Shape.Vertexes[0].Point - p2=v - p3=self.obj.Shape.Vertexes[1].Point - arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? - elif self.editing == 2: - p1=self.obj.Shape.Vertexes[0].Point - p2=self.getArcMid() - p3=v - arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? - self.obj.Placement.Base=arc.Center - self.obj.Radius = arc.Radius - deltaX = p1[0]-self.obj.Placement.Base[0] - deltaY = p1[1]-self.obj.Placement.Base[1] - dangleF = math.degrees(math.atan2(deltaY,deltaX)) - deltaX = p3[0]-self.obj.Placement.Base[0] - deltaY = p3[1]-self.obj.Placement.Base[1] - dangleL = math.degrees(math.atan2(deltaY,deltaX)) - self.obj.FirstAngle = dangleF - self.obj.LastAngle = dangleL - self.obj.recompute() - self.trackers[0].set(self.obj.Placement.Base) - self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) - self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) - self.trackers[3].set(self.getArcMid()) + self.updateCircle(v) elif Draft.getType(self.obj) == "Rectangle": delta = v.sub(self.obj.Placement.Base) @@ -4476,6 +4442,7 @@ class Edit(Modifier): self.obj.recompute() self.trackers[0].set(self.obj.Placement.Base) self.trackers[1].set(self.obj.Shape.Vertexes[2].Point) + elif Draft.getType(self.obj) == "Polygon": delta = v.sub(self.obj.Placement.Base) if self.editing == 0: @@ -4492,6 +4459,7 @@ class Edit(Modifier): self.obj.Radius = rad self.obj.recompute() self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) + elif Draft.getType(self.obj) == "Dimension": if self.editing == 0: self.obj.Start = v @@ -4501,35 +4469,155 @@ class Edit(Modifier): self.obj.Dimline = v elif self.editing == 3: self.obj.ViewObject.TextPosition = v + + elif Draft.getType(self.obj) == "Wall": + if self.editing == 0: + self.obj.Base.movePoint(0,1,v) + self.obj.Base.recompute() + if self.editing == 1: + self.obj.Base.movePoint(0,2,v) + self.obj.Base.recompute() + self.obj.recompute() + + elif Draft.getType(self.obj) == "Window": + pos=self.obj.Base.Placement.Base + if self.editing == 0: + self.obj.Base.Placement.Base=v + self.obj.Base.recompute() + if self.editing == 1: + self.obj.Width = pos.sub(v).Length + self.obj.Base.recompute() + if self.editing == 2: + self.obj.Height = pos.sub(v).Length + self.obj.Base.recompute() + for obj in self.obj.Hosts: + obj.recompute() + self.obj.recompute() + elif Draft.getType(self.obj) == "Space": if self.editing == 0: self.obj.ViewObject.TextPosition = v + elif Draft.getType(self.obj) == "Structure": nodes = self.obj.Nodes nodes[self.editing] = self.invpl.multVec(v) self.obj.Nodes = nodes + elif Draft.getType(self.obj) == "PanelCut": if self.editing == 0: self.obj.TagPosition = self.invpl.multVec(v) + elif Draft.getType(self.obj) == "PanelSheet": if self.editing == 0: self.obj.TagPosition = self.invpl.multVec(v) else: self.obj.Group[self.editing-1].Placement.Base = self.invpl.multVec(v) - elif Draft.getType(self.obj) == "Wall": - if self.editing == 0: - self.obj.Base.movePoint(0,1,v) - self.obj.Base.recompute() - self.obj.recompute() - if self.editing == 1: - self.obj.Base.movePoint(0,2,v) - self.obj.Base.recompute() - self.obj.recompute() + + self.doc.commitTransaction() try: FreeCADGui.ActiveDocument.ActiveView.redraw() except AttributeError as err: pass + def setCirclePts(self): + self.editpoints.clear() + self.editpoints.append(self.obj.Placement.Base) + if self.obj.FirstAngle == self.obj.LastAngle:#self.obj is a circle + self.ui.editUi("Circle") + self.editpoints.append(self.obj.Shape.Vertexes[0].Point) + else:#self.obj is an arc + self.ui.editUi("Arc") + self.editpoints.append(self.obj.Shape.Vertexes[0].Point)#First endpoint + self.editpoints.append(self.obj.Shape.Vertexes[1].Point)#Second endpoint + self.editpoints.append(self.getArcMid())#Midpoint + + def updateCirclePts(self,ep1=1,ep2=1,ep3=1,ep4=1): + self.obj.recompute() + if ep1 == 1: + self.trackers[0].set(self.obj.Placement.Base) + if ep2 == 1: + self.trackers[1].set(self.obj.Shape.Vertexes[0].Point) + if ep3 == 1: + self.trackers[2].set(self.obj.Shape.Vertexes[1].Point) + if ep4 == 1: + self.trackers[3].set(self.getArcMid()) + + + def updateCircle(self,v): + delta = v.sub(self.obj.Placement.Base) + if self.obj.FirstAngle == self.obj.LastAngle:# object is a circle + if self.editing == 0: + p = self.obj.Placement + p.move(delta) + self.obj.Placement = p + self.updateCirclePts(0,1,0,0) + if self.editing == 1: + self.obj.Radius = delta.Length + self.updateCirclePts(0,0,0,0) + + else:#self.obj is an arc + + if self.arc3Pt == True:#edit by center radius FirstAngle LastAngle + deltaX = v[0]-self.obj.Placement.Base[0] + deltaY = v[1]-self.obj.Placement.Base[1] + dangle = math.degrees(math.atan2(deltaY,deltaX)) + if self.editing == 0: + p = self.obj.Placement + p.move(delta) + self.obj.Placement = p + self.updateCirclePts(0,1,1,1) + elif self.editing == 1: + self.obj.FirstAngle=dangle + self.obj.recompute() + self.updateCirclePts(0,1,0,1) + elif self.editing == 2: + self.obj.LastAngle=dangle + self.obj.recompute() + self.updateCirclePts(0,0,1,1) + elif self.editing == 3: + self.obj.Radius = delta.Length + self.obj.recompute() + self.updateCirclePts(0,1,1,1) + + elif self.arc3Pt == False: + if self.editing == 0:#center point + import DraftVecUtils + p1 = self.obj.Shape.Vertexes[0].Point + p2 = self.obj.Shape.Vertexes[1].Point + p0 = DraftVecUtils.project(delta,self.getArcMid().sub(self.obj.Placement.Base)) + p0 = p0.add(self.obj.Placement.Base) + self.obj.Placement.Base = p0 + self.obj.Radius = p1.sub(p0).Length + self.obj.FirstAngle = -math.degrees(DraftVecUtils.angle(p1.sub(p0))) + self.obj.LastAngle = -math.degrees(DraftVecUtils.angle(p2.sub(p0))) + self.updateCirclePts(1,0,0,1) + return + else: + if self.editing == 1:#first point + p1=v + p2=self.getArcMid() + p3=self.obj.Shape.Vertexes[1].Point + elif self.editing == 3:#midpoint + p1=self.obj.Shape.Vertexes[0].Point + p2=v + p3=self.obj.Shape.Vertexes[1].Point + elif self.editing == 2:#second point + p1=self.obj.Shape.Vertexes[0].Point + p2=self.getArcMid() + p3=v + arc=Part.ArcOfCircle(p1,p2,p3)#object is a support, do i have to delete it someway after? + self.obj.Placement.Base=arc.Center + self.obj.Radius = arc.Radius + deltaX = p1[0]-self.obj.Placement.Base[0] + deltaY = p1[1]-self.obj.Placement.Base[1] + dangleF = math.degrees(math.atan2(deltaY,deltaX)) + deltaX = p3[0]-self.obj.Placement.Base[0] + deltaY = p3[1]-self.obj.Placement.Base[1] + dangleL = math.degrees(math.atan2(deltaY,deltaX)) + self.obj.FirstAngle = dangleF + self.obj.LastAngle = dangleL + self.updateCirclePts() + def getArcMid(self):#Returns object midpoint if Draft.getType(self.obj) == "Circle": if self.obj.LastAngle>self.obj.FirstAngle: @@ -4761,7 +4849,7 @@ class Edit(Modifier): objPoints = self.obj.Points[ep] if self.pl: objPoints = self.pl.multVec(objPoints) self.trackers.append(editTracker(objPoints,self.obj.Name,ep,self.obj.ViewObject.LineColor)) - + class AddToGroup(): "The AddToGroup FreeCAD command definition"