[Draft] Edit _ code cleanup

According to @vocx_fc suggestions, this commit is a first cleanup of the code.
This commit is contained in:
carlopav
2019-12-23 22:51:56 +01:00
committed by Yorik van Havre
parent 99f9aa42f7
commit df846aaea4

View File

@@ -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):