[Draft] Edit _ code cleanup
According to @vocx_fc suggestions, this commit is a first cleanup of the code.
This commit is contained in:
committed by
Yorik van Havre
parent
99f9aa42f7
commit
df846aaea4
@@ -58,9 +58,13 @@ if FreeCAD.GuiUp:
|
||||
|
||||
|
||||
class Edit():
|
||||
|
||||
"The Draft_Edit FreeCAD command definition"
|
||||
|
||||
"""
|
||||
The Draft_Edit FreeCAD command definition.
|
||||
A tool to graphically edit FreeCAD objects.
|
||||
Current implementation use many parts of pivy graphics code by user "looo".
|
||||
The tool collect editpoints from objects and display Trackers on them to allow
|
||||
editing their Shape and their parameters.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.running = False
|
||||
self.trackers = {'object':[]}
|
||||
@@ -91,9 +95,10 @@ class Edit():
|
||||
self.supportedObjs = ["BezCurve","Wire","BSpline","Circle","Rectangle",
|
||||
"Polygon","Dimension","Space","Structure","PanelCut",
|
||||
"PanelSheet","Wall", "Window"]
|
||||
|
||||
#list of supported Part objects (they don't have a proxy)
|
||||
#TODO: Add support for "Part::Circle" "Part::RegularPolygon" "Part::Plane" "Part::Ellipse" "Part::Vertex" "Part::Spiral"
|
||||
self.supportedPartObjs = ["Sketch", "Sketcher::SketchObject", \
|
||||
self.supportedPartObjs = ["Sketch", "Sketcher::SketchObject",
|
||||
"Part", "Part::Line", "Part::Box"]
|
||||
|
||||
def GetResources(self):
|
||||
@@ -106,9 +111,16 @@ class Edit():
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def Activated(self):
|
||||
if self.running: self.finish()
|
||||
"""
|
||||
Activated is run when user launch Edit command.
|
||||
If something is selected -> call self.proceed()
|
||||
If nothing is selected -> self.register_selection_callback()
|
||||
"""
|
||||
if self.running:
|
||||
self.finish()
|
||||
DraftTools.Modifier.Activated(self,"Edit")
|
||||
if not FreeCAD.ActiveDocument: self.finish()
|
||||
if not FreeCAD.ActiveDocument:
|
||||
self.finish()
|
||||
|
||||
self.ui = FreeCADGui.draftToolBar
|
||||
self.view = Draft.get3DView()
|
||||
@@ -117,14 +129,17 @@ class Edit():
|
||||
self.proceed()
|
||||
else:
|
||||
self.ui.selectUi()
|
||||
FreeCAD.Console.PrintMessage(translate("draft", "Select a Draft object to edit")+"\n")
|
||||
FreeCAD.Console.PrintMessage(translate("draft",
|
||||
"Select a Draft object to edit") +
|
||||
"\n")
|
||||
self.register_selection_callback()
|
||||
|
||||
def proceed(self):
|
||||
"this method defines editpoints and set the editTrackers"
|
||||
self.unregister_selection_callback()
|
||||
self.objs = self.getObjsFromSelection()
|
||||
if not self.objs: return self.finish()
|
||||
if not self.objs:
|
||||
return self.finish()
|
||||
|
||||
# Save selectstate and turn selectable false.
|
||||
# Object can remain selectable commenting following lines,
|
||||
@@ -159,7 +174,8 @@ class Edit():
|
||||
if "Closed" in self.obj.PropertiesList:
|
||||
if not self.obj.Closed:
|
||||
self.obj.Closed = True
|
||||
if self.ui: self.removeTrackers()
|
||||
if self.ui:
|
||||
self.removeTrackers()
|
||||
self.restoreSelectState(self.obj)
|
||||
if Draft.getType(self.obj) == "Structure":
|
||||
if self.originalDisplayMode != None:
|
||||
@@ -174,7 +190,8 @@ class Edit():
|
||||
self.originalNodes = None
|
||||
DraftTools.Modifier.finish(self)
|
||||
FreeCAD.DraftWorkingPlane.restore()
|
||||
if FreeCADGui.Snapper.grid: FreeCADGui.Snapper.grid.set()
|
||||
if FreeCADGui.Snapper.grid:
|
||||
FreeCADGui.Snapper.grid.set()
|
||||
self.running = False
|
||||
# delay resetting edit mode otherwise it doesn't happen
|
||||
from PySide import QtCore
|
||||
@@ -214,15 +231,15 @@ class Edit():
|
||||
def unregister_editing_callbacks(self):
|
||||
"remove callbacks used during editing if they exhist"
|
||||
view = FreeCADGui.ActiveDocument.ActiveView
|
||||
if self._keyPressedCB:
|
||||
if self._keyPressedCB:
|
||||
view.removeEventCallbackSWIG(coin.SoKeyboardEvent.getClassTypeId(), self._keyPressedCB)
|
||||
self._keyPressedCB = None
|
||||
#FreeCAD.Console.PrintMessage("Draft edit keyboard callback unregistered \n")
|
||||
if self._mouseMovedCB:
|
||||
if self._mouseMovedCB:
|
||||
view.removeEventCallbackSWIG(coin.SoLocation2Event.getClassTypeId(), self._mouseMovedCB)
|
||||
self._mouseMovedCB = None
|
||||
#FreeCAD.Console.PrintMessage("Draft edit location callback unregistered \n")
|
||||
if self._mousePressedCB:
|
||||
if self._mousePressedCB:
|
||||
view.removeEventCallbackSWIG(coin.SoMouseButtonEvent.getClassTypeId(), self._mousePressedCB)
|
||||
self._mousePressedCB = None
|
||||
#FreeCAD.Console.PrintMessage("Draft edit mouse button callback unregistered \n")
|
||||
@@ -245,7 +262,8 @@ class Edit():
|
||||
if key == 111: # "o"
|
||||
self.finish(closed=True)
|
||||
if key == 105: # "i"
|
||||
if Draft.getType(self.obj) == "Circle": self.arcInvert(self.obj)
|
||||
if Draft.getType(self.obj) == "Circle":
|
||||
self.arcInvert(self.obj)
|
||||
|
||||
def mousePressed(self, event_callback):
|
||||
"mouse button event handler, calls: startEditing, endEditing, addPoint, delPoint"
|
||||
@@ -264,10 +282,12 @@ class Edit():
|
||||
pos = event.getPosition()
|
||||
node = self.getEditNode(pos)
|
||||
ep = self.getEditNodeIndex(node)
|
||||
if ep is None: return
|
||||
if ep is None:
|
||||
return
|
||||
doc = FreeCAD.getDocument(str(node.documentName.getValue()))
|
||||
self.obj = doc.getObject(str(node.objectName.getValue()))
|
||||
if self.obj is None: return
|
||||
if self.obj is None:
|
||||
return
|
||||
if self.ui.sharpButton.isChecked():
|
||||
return self.smoothBezPoint(self.obj, ep, 'Sharp')
|
||||
elif self.ui.tangentButton.isChecked():
|
||||
@@ -289,8 +309,9 @@ class Edit():
|
||||
pos = event.getPosition()
|
||||
node = self.getEditNode(pos)
|
||||
ep = self.getEditNodeIndex(node)
|
||||
if ep != None:
|
||||
if self.overNode != None: self.overNode.setColor(COLORS["default"])
|
||||
if ep != None:
|
||||
if self.overNode != None:
|
||||
self.overNode.setColor(COLORS["default"])
|
||||
self.trackers[str(node.objectName.getValue())][ep].setColor(COLORS["red"])
|
||||
self.overNode = self.trackers[str(node.objectName.getValue())][ep]
|
||||
else:
|
||||
@@ -303,14 +324,17 @@ class Edit():
|
||||
pos = event.getPosition()
|
||||
node = self.getEditNode(pos)
|
||||
ep = self.getEditNodeIndex(node)
|
||||
if ep is None: return
|
||||
if ep is None:
|
||||
return
|
||||
|
||||
doc = FreeCAD.getDocument(str(node.documentName.getValue()))
|
||||
self.obj = doc.getObject(str(node.objectName.getValue()))
|
||||
if self.obj is None: return
|
||||
if self.obj is None:
|
||||
return
|
||||
self.setPlacement(self.obj)
|
||||
|
||||
FreeCAD.Console.PrintMessage(str(self.obj.Name)+str(": editing node: n° ")+str(ep)+"\n")
|
||||
FreeCAD.Console.PrintMessage(str(self.obj.Name) + str(
|
||||
": editing node: n° ") + str(ep) + "\n")
|
||||
|
||||
self.ui.lineUi()
|
||||
self.ui.isRelative.show()
|
||||
@@ -330,7 +354,8 @@ class Edit():
|
||||
snappedPos = FreeCADGui.Snapper.snap((pos[0],pos[1]),self.node[-1], constrain=orthoConstrain)
|
||||
self.trackers[self.obj.Name][self.editing].set(snappedPos)
|
||||
self.ui.displayPoint(snappedPos,self.node[-1])
|
||||
if self.ghost: self.updateGhost(obj=self.obj,idx=self.editing,pt=snappedPos)
|
||||
if self.ghost:
|
||||
self.updateGhost(obj=self.obj,idx=self.editing,pt=snappedPos)
|
||||
|
||||
def endEditing(self, obj, nodeIndex):
|
||||
"terminate editing and start object updating process"
|
||||
@@ -351,8 +376,8 @@ class Edit():
|
||||
self.objs = []
|
||||
if len(selection) > self.maxObjects:
|
||||
FreeCAD.Console.PrintMessage(translate("draft",
|
||||
"Too many objects selected, max number set to: "+
|
||||
str(self.maxObjects)+"\n"))
|
||||
"Too many objects selected, max number set to: " +
|
||||
str(self.maxObjects) + "\n"))
|
||||
return None
|
||||
for obj in selection:
|
||||
if "Proxy" in selection[0].PropertiesList and hasattr(selection[0].Proxy,"Type"):
|
||||
@@ -366,7 +391,10 @@ class Edit():
|
||||
continue
|
||||
except:
|
||||
pass
|
||||
FreeCAD.Console.PrintWarning(translate("draft", str(obj.Name)+": this object is not editable")+"\n")
|
||||
FreeCAD.Console.PrintWarning(translate("draft",
|
||||
str(obj.Name) +
|
||||
": this object is not editable") +
|
||||
"\n")
|
||||
return self.objs
|
||||
|
||||
def numericInput(self, obj, nodeIndex, v, numy=None,numz=None):
|
||||
@@ -395,7 +423,8 @@ class Edit():
|
||||
|
||||
def setPlacement(self,obj):
|
||||
"set self.pl and self.invpl to self.obj placement and inverse placement"
|
||||
if not obj: return
|
||||
if not obj:
|
||||
return
|
||||
if "Placement" in obj.PropertiesList:
|
||||
self.pl = obj.getGlobalPlacement()
|
||||
self.invpl = self.pl.inverse()
|
||||
@@ -451,9 +480,12 @@ class Edit():
|
||||
def setTrackers(self, obj, points=None):
|
||||
"set Edit Trackers for editpoints collected from self.obj"
|
||||
if points == None or len(points) == 0:
|
||||
FreeCAD.Console.PrintWarning(translate("draft", "No edit point found for selected object")+"\n")
|
||||
FreeCAD.Console.PrintWarning(translate("draft",
|
||||
"No edit point found for selected object") +
|
||||
"\n")
|
||||
# do not finish if some trackers are still present
|
||||
if self.trackers == {'object':[]}: self.finish()
|
||||
if self.trackers == {'object':[]}:
|
||||
self.finish()
|
||||
return
|
||||
self.trackers[obj.Name] = []
|
||||
if Draft.getType(obj) == "BezCurve":
|
||||
@@ -513,13 +545,15 @@ class Edit():
|
||||
self.ghost.on()
|
||||
pointList = self.applyPlacement(obj.Points)
|
||||
pointList[idx] = pt
|
||||
if obj.Closed: pointList.append(pointList[0])
|
||||
if obj.Closed:
|
||||
pointList.append(pointList[0])
|
||||
self.ghost.updateFromPointlist(pointList)
|
||||
elif Draft.getType(obj) == "BSpline":
|
||||
self.ghost.on()
|
||||
pointList = self.applyPlacement(obj.Points)
|
||||
pointList[idx] = pt
|
||||
if obj.Closed: pointList.append(pointList[0])
|
||||
if obj.Closed:
|
||||
pointList.append(pointList[0])
|
||||
self.ghost.update(pointList)
|
||||
elif Draft.getType(obj) == "BezCurve":
|
||||
self.ghost.on()
|
||||
@@ -532,8 +566,9 @@ class Edit():
|
||||
self.ghost.setRadius(obj.Radius)
|
||||
if self.obj.FirstAngle == self.obj.LastAngle:#self.obj is a circle
|
||||
self.ghost.circle = True
|
||||
if self.editing == 0: self.ghost.setCenter(pt)
|
||||
elif self.editing == 1:
|
||||
if self.editing == 0:
|
||||
self.ghost.setCenter(pt)
|
||||
elif self.editing == 1:
|
||||
radius = pt.sub(obj.getGlobalPlacement().Base).Length
|
||||
self.ghost.setRadius(radius)
|
||||
else:
|
||||
@@ -564,26 +599,31 @@ class Edit():
|
||||
p1=self.obj.Shape.Vertexes[0].Point
|
||||
p2=self.getArcMid(self.obj)
|
||||
p3=self.obj.Shape.Vertexes[1].Point
|
||||
if self.editing == 1: p1=pt
|
||||
elif self.editing == 3: p2=pt
|
||||
elif self.editing == 2: p3=pt
|
||||
if self.editing == 1:
|
||||
p1=pt
|
||||
elif self.editing == 3:
|
||||
p2=pt
|
||||
elif self.editing == 2:
|
||||
p3=pt
|
||||
self.ghost.setBy3Points(p1,p2,p3)
|
||||
DraftTools.redraw3DView()
|
||||
|
||||
def applyPlacement(self,pointList):
|
||||
if self.pl:
|
||||
plist =[]
|
||||
plist = []
|
||||
for p in pointList:
|
||||
point = self.pl.multVec(p)
|
||||
plist.append(point)
|
||||
return plist
|
||||
else: return pointList
|
||||
else:
|
||||
return pointList
|
||||
|
||||
def finalizeGhost(self):
|
||||
try:
|
||||
self.ghost.finalize()
|
||||
self.ghost = None
|
||||
except: return
|
||||
except:
|
||||
return
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# EDIT OBJECT TOOLS : Add/Delete Vertexes
|
||||
@@ -594,21 +634,25 @@ class Edit():
|
||||
pos = event.getPosition()
|
||||
#self.setSelectState(self.obj, True)
|
||||
selobjs = FreeCADGui.ActiveDocument.ActiveView.getObjectsInfo((pos[0],pos[1]))
|
||||
if not selobjs: return
|
||||
if not selobjs:
|
||||
return
|
||||
for info in selobjs:
|
||||
if not info: return
|
||||
if not info:
|
||||
return
|
||||
for o in self.objs:
|
||||
if o.Name != info["Object"]: continue
|
||||
if o.Name != info["Object"]:
|
||||
continue
|
||||
self.obj = o
|
||||
break
|
||||
if Draft.getType(self.obj) == "Wire" and 'Edge' in info["Component"]:
|
||||
pt = FreeCAD.Vector(info["x"],info["y"],info["z"])
|
||||
pt = FreeCAD.Vector(info["x"], info["y"], info["z"])
|
||||
self.addPointToWire(pt, int(info["Component"][4:]))
|
||||
elif Draft.getType(self.obj) in ["BSpline","BezCurve"]: #to fix double vertex created
|
||||
elif Draft.getType(self.obj) in ["BSpline", "BezCurve"]: #to fix double vertex created
|
||||
#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"])
|
||||
else: continue
|
||||
pt = FreeCAD.Vector(info["x"], info["y"], info["z"])
|
||||
else:
|
||||
continue
|
||||
self.addPointToCurve(pt,info)
|
||||
self.obj.recompute()
|
||||
self.removeTrackers(self.obj)
|
||||
@@ -631,17 +675,18 @@ class Edit():
|
||||
|
||||
def addPointToCurve(self,point,info=None):
|
||||
import Part
|
||||
if not (Draft.getType(self.obj) in ["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'):
|
||||
return # clicked control point
|
||||
edgeindex = int(info['Component'].lstrip('Edge'))-1
|
||||
wire=self.obj.Shape.Wires[0]
|
||||
bz=wire.Edges[edgeindex].Curve
|
||||
param=bz.parameter(point)
|
||||
seg1=wire.Edges[edgeindex].copy().Curve
|
||||
seg2=wire.Edges[edgeindex].copy().Curve
|
||||
edgeindex = int(info['Component'].lstrip('Edge')) -1
|
||||
wire = self.obj.Shape.Wires[0]
|
||||
bz = wire.Edges[edgeindex].Curve
|
||||
param = bz.parameter(point)
|
||||
seg1 = wire.Edges[edgeindex].copy().Curve
|
||||
seg2 = wire.Edges[edgeindex].copy().Curve
|
||||
seg1.segment(seg1.FirstParameter,param)
|
||||
seg2.segment(param,seg2.LastParameter)
|
||||
if edgeindex == len(wire.Edges):
|
||||
@@ -649,18 +694,18 @@ class Edit():
|
||||
degree=wire.Edges[0].Curve.Degree
|
||||
seg1.increase(degree)
|
||||
seg2.increase(degree)
|
||||
edges=wire.Edges[0:edgeindex]+[Part.Edge(seg1),Part.Edge(seg2)]\
|
||||
+ wire.Edges[edgeindex+1:]
|
||||
edges = wire.Edges[0:edgeindex] + [Part.Edge(seg1),Part.Edge(seg2)] \
|
||||
+ wire.Edges[edgeindex + 1:]
|
||||
pts = edges[0].Curve.getPoles()[0:1]
|
||||
for edge in edges:
|
||||
pts.extend(edge.Curve.getPoles()[1:])
|
||||
if self.obj.Closed:
|
||||
pts.pop()
|
||||
c=self.obj.Continuity
|
||||
c = self.obj.Continuity
|
||||
# assume we have a tangent continuity for an arbitrarily split
|
||||
# segment, unless it's linear
|
||||
cont = 1 if (self.obj.Degree >= 2) else 0
|
||||
self.obj.Continuity = c[0:edgeindex]+[cont]+c[edgeindex:]
|
||||
self.obj.Continuity = c[0:edgeindex] + [cont] + c[edgeindex:]
|
||||
else:
|
||||
if (Draft.getType(self.obj) in ["BSpline"]):
|
||||
if (self.obj.Closed == True):
|
||||
@@ -671,9 +716,9 @@ class Edit():
|
||||
uPoints = []
|
||||
for p in self.obj.Points:
|
||||
uPoints.append(curve.parameter(p))
|
||||
for i in range(len(uPoints)-1):
|
||||
for i in range(len(uPoints) -1):
|
||||
if ( uNewPoint > uPoints[i] ) and ( uNewPoint < uPoints[i+1] ):
|
||||
pts.insert(i+1, self.invpl.multVec(point))
|
||||
pts.insert(i + 1, self.invpl.multVec(point))
|
||||
break
|
||||
# DNC: fix: add points to last segment if curve is closed
|
||||
if ( self.obj.Closed ) and ( uNewPoint > uPoints[-1] ) :
|
||||
@@ -685,15 +730,21 @@ class Edit():
|
||||
node = self.getEditNode(pos)
|
||||
ep = self.getEditNodeIndex(node)
|
||||
|
||||
if ep is None: return FreeCAD.Console.PrintWarning(
|
||||
translate("draft", "Node not found\n"))
|
||||
if ep is None:
|
||||
return FreeCAD.Console.PrintWarning(translate("draft",
|
||||
"Node not found\n"))
|
||||
|
||||
doc = FreeCAD.getDocument(str(node.documentName.getValue()))
|
||||
self.obj = doc.getObject(str(node.objectName.getValue()))
|
||||
if self.obj is None: return
|
||||
if not (Draft.getType(self.obj) in ["Wire","BSpline","BezCurve"]): return
|
||||
if len(self.obj.Points) <= 2: return FreeCAD.Console.PrintWarning(
|
||||
translate("draft", "Active object must have more than two points/nodes")+"\n")
|
||||
if self.obj is None:
|
||||
return
|
||||
if not (Draft.getType(self.obj) in ["Wire","BSpline","BezCurve"]):
|
||||
return
|
||||
if len(self.obj.Points) <= 2:
|
||||
FreeCAD.Console.PrintWarning(translate("draft",
|
||||
"Active object must have more than two points/nodes") +
|
||||
"\n")
|
||||
return
|
||||
|
||||
pts = self.obj.Points
|
||||
pts.pop(ep)
|
||||
@@ -765,23 +816,39 @@ class Edit():
|
||||
def update(self,obj, nodeIndex, v):
|
||||
"apply the vector to the modified point and update self.obj"
|
||||
|
||||
objectType = Draft.getType(obj)
|
||||
FreeCAD.ActiveDocument.openTransaction("Edit")
|
||||
|
||||
if Draft.getType(obj) in ["Wire","BSpline"]: self.updateWire(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "BezCurve": self.updateWire(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Circle": self.updateCircle(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Rectangle": self.updateRectangle(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Polygon": self.updatePolygon(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Dimension": self.updateDimension(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Sketch": self.updateSketch(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Wall": self.updateWall(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Window": self.updateWindow(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Space": self.updateSpace(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Structure": self.updateStructure(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "PanelCut": self.updatePanelCut(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "PanelSheet": self.updatePanelSheet(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Part::Line" and self.obj.TypeId == "Part::Line": self.updatePartLine(obj, nodeIndex, v)
|
||||
elif Draft.getType(obj) == "Part" and self.obj.TypeId == "Part::Box": self.updatePartBox(obj, nodeIndex, v)
|
||||
if objectType in ["Wire","BSpline"]:
|
||||
self.updateWire(obj, nodeIndex, v)
|
||||
elif objectType == "BezCurve":
|
||||
self.updateWire(obj, nodeIndex, v)
|
||||
elif objectType == "Circle":
|
||||
self.updateCircle(obj, nodeIndex, v)
|
||||
elif objectType == "Rectangle":
|
||||
self.updateRectangle(obj, nodeIndex, v)
|
||||
elif objectType == "Polygon":
|
||||
self.updatePolygon(obj, nodeIndex, v)
|
||||
elif objectType == "Dimension":
|
||||
self.updateDimension(obj, nodeIndex, v)
|
||||
elif objectType == "Sketch":
|
||||
self.updateSketch(obj, nodeIndex, v)
|
||||
elif objectType == "Wall":
|
||||
self.updateWall(obj, nodeIndex, v)
|
||||
elif objectType == "Window":
|
||||
self.updateWindow(obj, nodeIndex, v)
|
||||
elif objectType == "Space":
|
||||
self.updateSpace(obj, nodeIndex, v)
|
||||
elif objectType == "Structure":
|
||||
self.updateStructure(obj, nodeIndex, v)
|
||||
elif objectType == "PanelCut":
|
||||
self.updatePanelCut(obj, nodeIndex, v)
|
||||
elif objectType == "PanelSheet":
|
||||
self.updatePanelSheet(obj, nodeIndex, v)
|
||||
elif objectType == "Part::Line" and self.obj.TypeId == "Part::Line":
|
||||
self.updatePartLine(obj, nodeIndex, v)
|
||||
elif objectType == "Part" and self.obj.TypeId == "Part::Box":
|
||||
self.updatePartBox(obj, nodeIndex, v)
|
||||
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
|
||||
@@ -806,13 +873,20 @@ class Edit():
|
||||
editPnt = obj.getGlobalPlacement().inverse().multVec(v)
|
||||
# DNC: allows to close the curve by placing ends close to each other
|
||||
tol = 0.001
|
||||
if ( ( nodeIndex == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or ( nodeIndex == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
|
||||
if ( ( nodeIndex == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or (
|
||||
nodeIndex == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
|
||||
obj.Closed = True
|
||||
# DNC: fix error message if edited point coincides with one of the existing points
|
||||
if ( editPnt in pts ) == True: # checks if point enter is equal to other, this could cause a OCC problem
|
||||
FreeCAD.Console.PrintMessage(translate("draft", "Is not possible to have two coincident points in this object, please try again.")+"\n")
|
||||
if Draft.getType(obj) in ["BezCurve"]: self.resetTrackers(obj)
|
||||
else: self.trackers[obj.Name][nodeIndex].set(obj.getGlobalPlacement().multVec(obj.Points[nodeIndex]))
|
||||
FreeCAD.Console.PrintMessage(translate("draft",
|
||||
"It is not possible to have two coincident points in this \
|
||||
object, please try again.") +
|
||||
"\n")
|
||||
if Draft.getType(obj) in ["BezCurve"]:
|
||||
self.resetTrackers(obj)
|
||||
else:
|
||||
self.trackers[obj.Name][nodeIndex].set(obj.getGlobalPlacement().
|
||||
multVec(obj.Points[nodeIndex]))
|
||||
return
|
||||
if Draft.getType(obj) in ["BezCurve"]:
|
||||
pts = self.recomputePointsBezier(obj,pts,nodeIndex,v,obj.Degree,moveTrackers=False)
|
||||
@@ -830,12 +904,15 @@ class Edit():
|
||||
|
||||
|
||||
def recomputePointsBezier(self,obj,pts,idx,v,degree,moveTrackers=True):
|
||||
"Point list, index of changed point, vector of new point, move trackers; return the new point list"
|
||||
|
||||
editPnt = v#self.invpl.multVec(v)
|
||||
"""
|
||||
(object, Points as list, nodeIndex as Int, vector of new point, moveTrackers as Bool)
|
||||
return the new point list, applying the vector to the given index point
|
||||
"""
|
||||
editPnt = v
|
||||
# DNC: allows to close the curve by placing ends close to each other
|
||||
tol = 0.001
|
||||
if ( ( idx == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or ( idx == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
|
||||
if ( ( idx == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or (
|
||||
idx == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
|
||||
obj.Closed = True
|
||||
# DNC: fix error message if edited point coincides with one of the existing points
|
||||
#if ( editPnt in pts ) == False:
|
||||
@@ -843,17 +920,20 @@ class Edit():
|
||||
ispole = idx % degree
|
||||
|
||||
if ispole == 0: #knot
|
||||
if degree >=3:
|
||||
if degree >= 3:
|
||||
if idx >= 1: #move left pole
|
||||
knotidx = idx if idx < len(pts) else 0
|
||||
pts[idx-1] = pts[idx-1] + editPnt - pts[knotidx]
|
||||
if moveTrackers: self.trackers[obj.Name][idx-1].set(pts[idx-1])
|
||||
if moveTrackers:
|
||||
self.trackers[obj.Name][idx-1].set(pts[idx-1])
|
||||
if idx < len(pts)-1: #move right pole
|
||||
pts[idx+1] = pts[idx+1] + editPnt - pts[idx]
|
||||
if moveTrackers: self.trackers[obj.Name][idx+1].set(pts[idx+1])
|
||||
if moveTrackers:
|
||||
self.trackers[obj.Name][idx+1].set(pts[idx+1])
|
||||
if idx == 0 and obj.Closed: # move last pole
|
||||
pts[-1] = pts [-1] + editPnt -pts[idx]
|
||||
if moveTrackers: self.trackers[obj.Name][-1].set(pts[-1])
|
||||
if moveTrackers:
|
||||
self.trackers[obj.Name][-1].set(pts[-1])
|
||||
|
||||
elif ispole == 1 and (idx >=2 or obj.Closed): #right pole
|
||||
knot = idx -1
|
||||
@@ -869,16 +949,16 @@ class Edit():
|
||||
|
||||
if knot is not None: # we need to modify the opposite pole
|
||||
segment = int(knot / degree) -1
|
||||
cont=obj.Continuity[segment] if \
|
||||
len(obj.Continuity) > segment else 0
|
||||
cont = obj.Continuity[segment] if len(obj.Continuity) > segment else 0
|
||||
if cont == 1: #tangent
|
||||
pts[changep] = obj.Proxy.modifytangentpole(\
|
||||
pts[knot],editPnt,pts[changep])
|
||||
if moveTrackers: self.trackers[obj.Name][changep].set(pts[changep])
|
||||
elif cont ==2: #symmetric
|
||||
pts[changep] = obj.Proxy.modifysymmetricpole(\
|
||||
pts[knot],editPnt)
|
||||
if moveTrackers: self.trackers[obj.Name][changep].set(pts[changep])
|
||||
pts[changep] = obj.Proxy.modifytangentpole(pts[knot],
|
||||
editPnt,pts[changep])
|
||||
if moveTrackers:
|
||||
self.trackers[obj.Name][changep].set(pts[changep])
|
||||
elif cont == 2: #symmetric
|
||||
pts[changep] = obj.Proxy.modifysymmetricpole(pts[knot],editPnt)
|
||||
if moveTrackers:
|
||||
self.trackers[obj.Name][changep].set(pts[changep])
|
||||
pts[idx]=v
|
||||
|
||||
return pts #returns the list of new points, taking into account knot continuity
|
||||
@@ -890,33 +970,34 @@ class Edit():
|
||||
coin.SoMarkerSet.SQUARE_FILLED_9_9, #tangent
|
||||
coin.SoMarkerSet.HOURGLASS_FILLED_9_9) #symmetric
|
||||
polemarker = coin.SoMarkerSet.CIRCLE_FILLED_9_9 #pole
|
||||
self.trackers[obj.Name]=[]
|
||||
cont=obj.Continuity
|
||||
self.trackers[obj.Name] = []
|
||||
cont = obj.Continuity
|
||||
firstknotcont = cont[-1] if (obj.Closed and cont) else 0
|
||||
pointswithmarkers=[(obj.Shape.Edges[0].Curve.\
|
||||
pointswithmarkers = [(obj.Shape.Edges[0].Curve.
|
||||
getPole(1),knotmarkers[firstknotcont])]
|
||||
for edgeindex, edge in enumerate(obj.Shape.Edges):
|
||||
poles=edge.Curve.getPoles()
|
||||
pointswithmarkers.extend([(point,polemarker) for \
|
||||
point in poles[1:-1]])
|
||||
poles = edge.Curve.getPoles()
|
||||
pointswithmarkers.extend([(point,polemarker) for point in poles[1:-1]])
|
||||
if not obj.Closed or len(obj.Shape.Edges) > edgeindex +1:
|
||||
knotmarkeri=cont[edgeindex] if len(cont) > edgeindex else 0
|
||||
knotmarkeri = cont[edgeindex] if len(cont) > edgeindex else 0
|
||||
pointswithmarkers.append((poles[-1],knotmarkers[knotmarkeri]))
|
||||
for index,pwm in enumerate(pointswithmarkers):
|
||||
p,marker=pwm
|
||||
for index, pwm in enumerate(pointswithmarkers):
|
||||
p,marker = pwm
|
||||
#if self.pl: p = self.pl.multVec(p)
|
||||
self.trackers[obj.Name].append(editTracker(p,obj.Name,\
|
||||
index,obj.ViewObject.LineColor,\
|
||||
marker=marker))
|
||||
self.trackers[obj.Name].append(editTracker(p,obj.Name,
|
||||
index,obj.ViewObject.LineColor,marker=marker))
|
||||
|
||||
def smoothBezPoint(self, obj, point, style='Symmetric'):
|
||||
"called when changing the continuity of a knot"
|
||||
style2cont = {'Sharp':0,'Tangent':1,'Symmetric':2}
|
||||
if point is None: return
|
||||
if not (Draft.getType(obj) == "BezCurve"):return
|
||||
if point is None:
|
||||
return
|
||||
if not (Draft.getType(obj) == "BezCurve"):
|
||||
return
|
||||
pts = obj.Points
|
||||
deg = obj.Degree
|
||||
if deg < 2: return
|
||||
if deg < 2:
|
||||
return
|
||||
if point % deg != 0: #point is a pole
|
||||
if deg >=3: #allow to select poles
|
||||
if (point % deg == 1) and (point > 2 or obj.Closed): #right pole
|
||||
@@ -934,19 +1015,22 @@ class Edit():
|
||||
keepp = point
|
||||
changep = 1
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(translate("draft", "Can't change Knot belonging to pole %d"%point)+"\n")
|
||||
FreeCAD.Console.PrintWarning(translate("draft",
|
||||
"Can't change Knot belonging to pole %d"%point) +
|
||||
"\n")
|
||||
return
|
||||
if knot:
|
||||
if style == 'Tangent':
|
||||
pts[changep] = obj.Proxy.modifytangentpole(\
|
||||
pts[knot],pts[keepp],pts[changep])
|
||||
pts[changep] = obj.Proxy.modifytangentpole(pts[knot],
|
||||
pts[keepp],pts[changep])
|
||||
elif style == 'Symmetric':
|
||||
pts[changep] = obj.Proxy.modifysymmetricpole(\
|
||||
pts[knot],pts[keepp])
|
||||
pts[changep] = obj.Proxy.modifysymmetricpole(pts[knot],
|
||||
pts[keepp])
|
||||
else: #sharp
|
||||
pass #
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(translate("draft", "Selection is not a Knot\n"))
|
||||
FreeCAD.Console.PrintWarning(translate("draft",
|
||||
"Selection is not a Knot\n"))
|
||||
return
|
||||
else: #point is a knot
|
||||
if style == 'Sharp':
|
||||
@@ -955,38 +1039,40 @@ class Edit():
|
||||
else:
|
||||
knot = point
|
||||
elif style == 'Tangent' and point > 0 and point < len(pts)-1:
|
||||
prev, next = obj.Proxy.tangentpoles(pts[point],pts[point-1],pts[point+1])
|
||||
prev, next = obj.Proxy.tangentpoles(pts[point], pts[point-1], pts[point+1])
|
||||
pts[point-1] = prev
|
||||
pts[point+1] = next
|
||||
knot = point #index for continuity
|
||||
elif style == 'Symmetric' and point > 0 and point < len(pts)-1:
|
||||
prev, next = obj.Proxy.symmetricpoles(pts[point],pts[point-1],pts[point+1])
|
||||
prev, next = obj.Proxy.symmetricpoles(pts[point], pts[point-1], pts[point+1])
|
||||
pts[point-1] = prev
|
||||
pts[point+1] = next
|
||||
knot = point #index for continuity
|
||||
elif obj.Closed and (style == 'Symmetric' or style == 'Tangent'):
|
||||
if style == 'Tangent':
|
||||
pts[1],pts[-1] = obj.Proxy.tangentpoles(pts[0],pts[1],pts[-1])
|
||||
pts[1], pts[-1] = obj.Proxy.tangentpoles(pts[0], pts[1], pts[-1])
|
||||
elif style == 'Symmetric':
|
||||
pts[1],pts[-1] = obj.Proxy.symmetricpoles(pts[0],pts[1],pts[-1])
|
||||
pts[1], pts[-1] = obj.Proxy.symmetricpoles(pts[0], pts[1], pts[-1])
|
||||
knot = 0
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(translate("draft", "Endpoint of BezCurve can't be smoothed")+"\n")
|
||||
FreeCAD.Console.PrintWarning(translate("draft",
|
||||
"Endpoint of BezCurve can't be smoothed") +
|
||||
"\n")
|
||||
return
|
||||
segment = knot // deg #segment index
|
||||
newcont=obj.Continuity[:] #don't edit a property inplace !!!
|
||||
if not obj.Closed and (len(obj.Continuity) == segment -1 or \
|
||||
segment == 0) : pass # open curve
|
||||
elif len(obj.Continuity) >= segment or \
|
||||
obj.Closed and segment == 0 and \
|
||||
len(obj.Continuity) >1:
|
||||
newcont = obj.Continuity[:] #don't edit a property inplace !!!
|
||||
if not obj.Closed and (len(obj.Continuity) == segment -1 or
|
||||
segment == 0) :
|
||||
pass # open curve
|
||||
elif (len(obj.Continuity) >= segment or obj.Closed and segment == 0 and
|
||||
len(obj.Continuity) >1):
|
||||
newcont[segment-1] = style2cont.get(style)
|
||||
else: #should not happen
|
||||
FreeCAD.Console.PrintWarning('Continuity indexing error:'+\
|
||||
'point:%d deg:%d len(cont):%d' % (knot,deg,\
|
||||
FreeCAD.Console.PrintWarning('Continuity indexing error:'+
|
||||
'point:%d deg:%d len(cont):%d' % (knot,deg,
|
||||
len(obj.Continuity)))
|
||||
obj.Points = pts
|
||||
obj.Continuity=newcont
|
||||
obj.Continuity = newcont
|
||||
self.resetTrackers(obj)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
@@ -1092,11 +1178,11 @@ class Edit():
|
||||
self.setPlacement(self.obj)
|
||||
self.updateCircleTrackers(obj)
|
||||
elif self.editing == 1:
|
||||
self.obj.FirstAngle=dangle
|
||||
self.obj.FirstAngle = dangle
|
||||
self.obj.recompute()
|
||||
self.updateCircleTrackers(obj)
|
||||
elif self.editing == 2:
|
||||
self.obj.LastAngle=dangle
|
||||
self.obj.LastAngle = dangle
|
||||
self.obj.recompute()
|
||||
self.updateCircleTrackers(obj)
|
||||
elif self.editing == 3:
|
||||
@@ -1155,17 +1241,17 @@ class Edit():
|
||||
|
||||
def getArcMid(self, obj):#Returns object midpoint
|
||||
if Draft.getType(obj) == "Circle":
|
||||
if obj.LastAngle>obj.FirstAngle:
|
||||
midAngle=obj.FirstAngle+(obj.LastAngle-obj.FirstAngle)/2
|
||||
if obj.LastAngle > obj.FirstAngle:
|
||||
midAngle = obj.FirstAngle + (obj.LastAngle - obj.FirstAngle) / 2.0
|
||||
else:
|
||||
midAngle=(obj.FirstAngle+(obj.LastAngle-obj.FirstAngle)/2)+180.0
|
||||
midAngle = (obj.FirstAngle + (obj.LastAngle - obj.FirstAngle) / 2.0) + 180.0
|
||||
return self.pointOnCircle(obj, midAngle)
|
||||
|
||||
def pointOnCircle(self, obj, angle):
|
||||
if Draft.getType(obj) == "Circle":
|
||||
px=obj.Radius*math.cos(math.radians(angle))
|
||||
py=obj.Radius*math.sin(math.radians(angle))
|
||||
p = obj.getGlobalPlacement().multVec(FreeCAD.Vector(px,py,0.0))
|
||||
px = obj.Radius * math.cos(math.radians(angle))
|
||||
py = obj.Radius * math.sin(math.radians(angle))
|
||||
p = obj.getGlobalPlacement().multVec(FreeCAD.Vector(px, py, 0.0))
|
||||
return p
|
||||
return None
|
||||
|
||||
@@ -1244,8 +1330,10 @@ class Edit():
|
||||
editpoints.append(obj.getGlobalPlacement().multVec(obj.getPoint(0,2)))
|
||||
return editpoints
|
||||
else:
|
||||
FreeCAD.Console.PrintWarning(translate("draft","Sketch is too complex\
|
||||
to edit: it is suggested to use sketcher default editor")+"\n")
|
||||
FreeCAD.Console.PrintWarning(translate("draft",
|
||||
"Sketch is too complex to edit: \
|
||||
it is suggested to use sketcher default editor") +
|
||||
"\n")
|
||||
return None
|
||||
|
||||
def updateSketch(self, obj, nodeIndex, v):
|
||||
@@ -1297,12 +1385,13 @@ class Edit():
|
||||
delta= obj.getGlobalPlacement().inverse().multVec(v)
|
||||
vz=DraftVecUtils.project(delta,FreeCAD.Vector(0,0,1))
|
||||
if vz.Length > 0:
|
||||
obj.Height=vz.Length
|
||||
obj.Height = vz.Length
|
||||
elif nodeIndex > 0:
|
||||
if obj.Base:
|
||||
if Draft.getType(obj.Base) in ["Wire","Circle","Rectangle",
|
||||
"Polygon", "Sketch"]:
|
||||
self.update(obj.Base, nodeIndex-1, obj.Placement.inverse().multVec(v))
|
||||
self.update(obj.Base, nodeIndex - 1,
|
||||
obj.Placement.inverse().multVec(v))
|
||||
obj.recompute()
|
||||
|
||||
|
||||
@@ -1311,15 +1400,15 @@ class Edit():
|
||||
def getWindowPts(self, obj):
|
||||
import DraftGeomUtils
|
||||
editpoints = []
|
||||
pos=obj.Base.Placement.Base
|
||||
h=float(obj.Height)+pos.z
|
||||
normal=obj.Normal
|
||||
angle=normal.getAngle(FreeCAD.Vector(1,0,0))
|
||||
pos = obj.Base.Placement.Base
|
||||
h = float(obj.Height) + pos.z
|
||||
normal = obj.Normal
|
||||
angle = normal.getAngle(FreeCAD.Vector(1, 0, 0))
|
||||
editpoints.append(pos)
|
||||
editpoints.append(FreeCAD.Vector(pos.x+float(obj.Width)*math.cos(angle-math.pi/2),
|
||||
pos.y+float(obj.Width)*math.sin(angle-math.pi/2),
|
||||
editpoints.append(FreeCAD.Vector(pos.x + float(obj.Width) * math.cos(angle-math.pi / 2.0),
|
||||
pos.y + float(obj.Width) * math.sin(angle-math.pi / 2.0),
|
||||
pos.z))
|
||||
editpoints.append(FreeCAD.Vector(pos.x,pos.y,h))
|
||||
editpoints.append(FreeCAD.Vector(pos.x, pos.y, h))
|
||||
return editpoints
|
||||
|
||||
def updateWindow(self, obj, nodeIndex, v):
|
||||
|
||||
Reference in New Issue
Block a user