[Draft] Edit: general refactor
Changed names of several methods from set to get, changed the general set of nodes, improved placement calculation to use getGlobalPlacement instead of Placement.
This commit is contained in:
committed by
Yorik van Havre
parent
050b13e10c
commit
7042446504
@@ -24,7 +24,8 @@
|
||||
#***************************************************************************
|
||||
|
||||
__title__= "FreeCAD Draft Edit Tool"
|
||||
__author__ = "Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, Dmitry Chigrin, Carlo Pavan"
|
||||
__author__ = "Yorik van Havre, Werner Mayer, Martin Burbaum, Ken Cline, \
|
||||
Dmitry Chigrin, Carlo Pavan"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
import FreeCAD
|
||||
@@ -268,15 +269,15 @@ class Edit():
|
||||
self.obj = doc.getObject(str(node.objectName.getValue()))
|
||||
if self.obj is None: return
|
||||
if self.ui.sharpButton.isChecked():
|
||||
return self.smoothBezPoint(ep, 'Sharp')
|
||||
return self.smoothBezPoint(self.obj, ep, 'Sharp')
|
||||
elif self.ui.tangentButton.isChecked():
|
||||
return self.smoothBezPoint(ep, 'Tangent')
|
||||
return self.smoothBezPoint(self.obj, ep, 'Tangent')
|
||||
elif self.ui.symmetricButton.isChecked():
|
||||
return self.smoothBezPoint(ep, 'Symmetric')
|
||||
return self.smoothBezPoint(self.obj, ep, 'Symmetric')
|
||||
if self.editing is None:
|
||||
self.startEditing(event)
|
||||
else:
|
||||
self.endEditing()
|
||||
self.endEditing(self.obj,self.editing)
|
||||
|
||||
def mouseMoved(self, event_callback):
|
||||
"mouse moved event handler, update tracker position and update preview ghost"
|
||||
@@ -331,12 +332,12 @@ class Edit():
|
||||
self.ui.displayPoint(snappedPos,self.node[-1])
|
||||
if self.ghost: self.updateGhost(obj=self.obj,idx=self.editing,pt=snappedPos)
|
||||
|
||||
def endEditing(self):
|
||||
def endEditing(self, obj, nodeIndex):
|
||||
"terminate editing and start object updating process"
|
||||
self.finalizeGhost()
|
||||
self.trackers[self.obj.Name][self.editing].on()
|
||||
self.trackers[obj.Name][nodeIndex].on()
|
||||
FreeCADGui.Snapper.setSelectMode(True)
|
||||
self.numericInput(self.trackers[self.obj.Name][self.editing].get())
|
||||
self.numericInput(obj, nodeIndex, self.trackers[obj.Name][nodeIndex].get())
|
||||
self.showTrackers()
|
||||
DraftTools.redraw3DView()
|
||||
|
||||
@@ -368,12 +369,12 @@ class Edit():
|
||||
FreeCAD.Console.PrintWarning(translate("draft", str(obj.Name)+": this object is not editable")+"\n")
|
||||
return self.objs
|
||||
|
||||
def numericInput(self,v,numy=None,numz=None):
|
||||
def numericInput(self, obj, nodeIndex, v, numy=None,numz=None):
|
||||
'''this function gets called by the toolbar
|
||||
or by the mouse click and activate the update function'''
|
||||
if (numy != None):
|
||||
v = Vector(v,numy,numz)
|
||||
self.update(v)
|
||||
self.update(obj, nodeIndex, v)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
self.editing = None
|
||||
self.ui.editUi(self.ui.lastMode)
|
||||
@@ -396,7 +397,7 @@ class Edit():
|
||||
"set self.pl and self.invpl to self.obj placement and inverse placement"
|
||||
if not obj: return
|
||||
if "Placement" in obj.PropertiesList:
|
||||
self.pl = obj.Placement
|
||||
self.pl = obj.getGlobalPlacement()
|
||||
self.invpl = self.pl.inverse()
|
||||
|
||||
def alignWorkingPlane(self):
|
||||
@@ -447,21 +448,26 @@ class Edit():
|
||||
# EDIT TRACKERS functions
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def setTrackers(self, obj):
|
||||
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")
|
||||
# do not finish if some trackers are still present
|
||||
if self.trackers == {'object':[]}: self.finish()
|
||||
return
|
||||
self.trackers[obj.Name] = []
|
||||
if Draft.getType(obj) == "BezCurve":
|
||||
self.resetTrackersBezier(obj)
|
||||
else:
|
||||
if obj.Name in self.trackers:
|
||||
self.removeTrackers(obj)
|
||||
for ep in range(len(self.editpoints)):
|
||||
self.trackers[obj.Name].append(editTracker(pos=self.editpoints[ep],name=obj.Name,idx=ep))
|
||||
for ep in range(len(points)):
|
||||
self.trackers[obj.Name].append(editTracker(pos=points[ep],name=obj.Name,idx=ep))
|
||||
|
||||
def resetTrackers(self):
|
||||
def resetTrackers(self, obj):
|
||||
"reset Edit Trackers and set them again"
|
||||
self.removeTrackers(self.obj)
|
||||
self.setTrackers(self.obj)
|
||||
self.removeTrackers(obj)
|
||||
self.setTrackers(obj, self.getEditPoints(obj))
|
||||
|
||||
def removeTrackers(self, obj = None):
|
||||
"reset Edit Trackers and set them again"
|
||||
@@ -518,7 +524,7 @@ class Edit():
|
||||
elif Draft.getType(obj) == "BezCurve":
|
||||
self.ghost.on()
|
||||
plist = self.applyPlacement(obj.Points)
|
||||
pointList = self.recomputePointsBezier(plist,idx,pt,obj.Degree,moveTrackers=True)
|
||||
pointList = self.recomputePointsBezier(obj,plist,idx,pt,obj.Degree,moveTrackers=True)
|
||||
self.ghost.update(pointList,obj.Degree)
|
||||
elif Draft.getType(obj) == "Circle":
|
||||
self.ghost.on()
|
||||
@@ -706,78 +712,77 @@ class Edit():
|
||||
|
||||
def setEditPoints(self,obj):
|
||||
"append given object's editpoints to self.edipoints and set EditTrackers"
|
||||
self.editpoints = []
|
||||
|
||||
self.setPlacement(obj)
|
||||
self.editpoints = self.getEditPoints(obj)
|
||||
|
||||
if self.editpoints: # set trackers and align plane
|
||||
self.setTrackers(obj, self.editpoints)
|
||||
self.editpoints = []
|
||||
|
||||
def getEditPoints(self, obj):
|
||||
'''
|
||||
(object) return a list of Vectors relative to object edit nodes
|
||||
'''
|
||||
objectType = Draft.getType(obj)
|
||||
|
||||
if objectType in ["Wire","BSpline"]:
|
||||
self.ui.editUi("Wire")
|
||||
self.setWirePts(obj)
|
||||
return self.getWirePts(obj)
|
||||
elif objectType == "BezCurve":
|
||||
self.ui.editUi("BezCurve")
|
||||
self.resetTrackersBezier(obj)
|
||||
self.editpoints = []
|
||||
return
|
||||
#self.setWirePts(obj)
|
||||
elif objectType == "Circle":
|
||||
self.setCirclePts(obj)
|
||||
return self.getCirclePts(obj)
|
||||
elif objectType == "Rectangle":
|
||||
self.setRectanglePts(obj)
|
||||
return self.getRectanglePts(obj)
|
||||
elif objectType == "Polygon":
|
||||
self.setPolygonPts(obj)
|
||||
return self.getPolygonPts(obj)
|
||||
elif objectType == "Dimension":
|
||||
self.setDimensionPts(obj)
|
||||
return self.getDimensionPts(obj)
|
||||
elif objectType == "Wall":
|
||||
self.setWallPts(obj)
|
||||
return self.getWallPts(obj)
|
||||
elif objectType == "Window":
|
||||
self.setWindowPts(obj)
|
||||
return self.getWindowPts(obj)
|
||||
elif objectType == "Space":
|
||||
self.setSpacePts(obj)
|
||||
return self.getSpacePts(obj)
|
||||
elif objectType == "Structure":
|
||||
self.setStructurePts(obj)
|
||||
return self.getStructurePts(obj)
|
||||
elif objectType == "PanelCut":
|
||||
self.setPanelCutPts(obj)
|
||||
return self.getPanelCutPts(obj)
|
||||
elif objectType == "PanelSheet":
|
||||
self.setPanelSheetPts(obj)
|
||||
return self.getPanelSheetPts(obj)
|
||||
elif objectType == "Part" and obj.TypeId == "Part::Box":
|
||||
self.setPartBoxPts(obj)
|
||||
return self.getPartBoxPts(obj)
|
||||
elif objectType == "Part::Line" and obj.TypeId == "Part::Line":
|
||||
self.setPartLinePts(obj)
|
||||
return self.getPartLinePts(obj)
|
||||
elif objectType == "Sketch":
|
||||
self.setSketchPts(obj)
|
||||
|
||||
if self.editpoints: # set trackers and align plane
|
||||
self.setTrackers(obj)
|
||||
self.editpoints = []
|
||||
return self.getSketchPts(obj)
|
||||
else:
|
||||
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()
|
||||
return
|
||||
return None
|
||||
|
||||
|
||||
|
||||
def update(self,v):
|
||||
def update(self,obj, nodeIndex, v):
|
||||
"apply the vector to the modified point and update self.obj"
|
||||
|
||||
FreeCAD.ActiveDocument.openTransaction("Edit")
|
||||
|
||||
if Draft.getType(self.obj) in ["Wire","BSpline"]: self.updateWire(v)
|
||||
elif Draft.getType(self.obj) == "BezCurve": self.updateWire(v)
|
||||
elif Draft.getType(self.obj) == "Circle": self.updateCircle(v)
|
||||
elif Draft.getType(self.obj) == "Rectangle": self.updateRectangle(v)
|
||||
elif Draft.getType(self.obj) == "Polygon": self.updatePolygon(v)
|
||||
elif Draft.getType(self.obj) == "Dimension": self.updateDimension(v)
|
||||
elif Draft.getType(self.obj) == "Sketch": self.updateSketch(v)
|
||||
elif Draft.getType(self.obj) == "Wall": self.updateWall(v)
|
||||
elif Draft.getType(self.obj) == "Window": self.updateWindow(v)
|
||||
elif Draft.getType(self.obj) == "Space": self.updateSpace(v)
|
||||
elif Draft.getType(self.obj) == "Structure": self.updateStructure(v)
|
||||
elif Draft.getType(self.obj) == "PanelCut": self.updatePanelCut(v)
|
||||
elif Draft.getType(self.obj) == "PanelSheet": self.updatePanelSheet(v)
|
||||
elif Draft.getType(self.obj) == "Part::Line" and self.obj.TypeId == "Part::Line": self.updatePartLine(v)
|
||||
elif Draft.getType(self.obj) == "Part" and self.obj.TypeId == "Part::Box": self.updatePartBox(v)
|
||||
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)
|
||||
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
|
||||
@@ -790,47 +795,49 @@ class Edit():
|
||||
# EDIT OBJECT TOOLS : Line/Wire/Bspline/Bezcurve
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def setWirePts(self,obj):
|
||||
def getWirePts(self,obj):
|
||||
editpoints = []
|
||||
for p in obj.Points:
|
||||
if self.pl: p = self.pl.multVec(p)
|
||||
self.editpoints.append(p)
|
||||
p = obj.getGlobalPlacement().multVec(p)
|
||||
editpoints.append(p)
|
||||
return editpoints
|
||||
|
||||
def updateWire(self,v):
|
||||
pts = self.obj.Points
|
||||
editPnt = self.invpl.multVec(v)
|
||||
def updateWire(self, obj, nodeIndex, v):
|
||||
pts = obj.Points
|
||||
editPnt = obj.getGlobalPlacement().inverse().multVec(v)
|
||||
# DNC: allows to close the curve by placing ends close to each other
|
||||
tol = 0.001
|
||||
if ( ( self.editing == 0 ) and ( (editPnt - pts[-1]).Length < tol) ) or ( self.editing == len(pts) - 1 ) and ( (editPnt - pts[0]).Length < tol):
|
||||
self.obj.Closed = True
|
||||
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(self.obj) in ["BezCurve"]: self.resetTrackers()
|
||||
else: self.trackers[self.obj.Name][self.editing].set(self.pl.multVec(self.obj.Points[self.editing]))
|
||||
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(self.obj) in ["BezCurve"]:
|
||||
pts = self.recomputePointsBezier(pts,self.editing,v,self.obj.Degree,moveTrackers=False)
|
||||
if Draft.getType(obj) in ["BezCurve"]:
|
||||
pts = self.recomputePointsBezier(obj,pts,nodeIndex,v,obj.Degree,moveTrackers=False)
|
||||
# check that the new point lies on the plane of the wire
|
||||
import DraftGeomUtils, DraftVecUtils
|
||||
if self.obj.Closed:
|
||||
n = DraftGeomUtils.getNormal(self.obj.Shape)
|
||||
dv = editPnt.sub(pts[self.editing])
|
||||
if obj.Closed:
|
||||
n = DraftGeomUtils.getNormal(obj.Shape)
|
||||
dv = editPnt.sub(pts[nodeIndex])
|
||||
rn = DraftVecUtils.project(dv,n)
|
||||
if dv.Length:
|
||||
editPnt = editPnt.add(rn.negative())
|
||||
pts[self.editing] = editPnt
|
||||
self.obj.Points = pts
|
||||
self.trackers[self.obj.Name][self.editing].set(v)
|
||||
pts[nodeIndex] = editPnt
|
||||
obj.Points = pts
|
||||
#self.trackers[obj.Name][nodeIndex].set(v)
|
||||
|
||||
|
||||
def recomputePointsBezier(self,pts,idx,v,degree,moveTrackers=True):
|
||||
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)
|
||||
# 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):
|
||||
self.obj.Closed = True
|
||||
obj.Closed = True
|
||||
# DNC: fix error message if edited point coincides with one of the existing points
|
||||
#if ( editPnt in pts ) == False:
|
||||
knot = None
|
||||
@@ -841,15 +848,15 @@ class Edit():
|
||||
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[self.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[self.obj.Name][idx+1].set(pts[idx+1])
|
||||
if idx == 0 and self.obj.Closed: # move last pole
|
||||
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[self.obj.Name][-1].set(pts[-1])
|
||||
if moveTrackers: self.trackers[obj.Name][-1].set(pts[-1])
|
||||
|
||||
elif ispole == 1 and (idx >=2 or self.obj.Closed): #right pole
|
||||
elif ispole == 1 and (idx >=2 or obj.Closed): #right pole
|
||||
knot = idx -1
|
||||
changep = idx -2 # -1 in case of closed curve
|
||||
|
||||
@@ -857,22 +864,22 @@ class Edit():
|
||||
knot = idx +1
|
||||
changep = idx +2
|
||||
|
||||
elif ispole == degree-1 and self.obj.Closed and idx == len(pts)-1: #last pole
|
||||
elif ispole == degree-1 and obj.Closed and idx == len(pts)-1: #last pole
|
||||
knot = 0
|
||||
changep = 1
|
||||
|
||||
if knot is not None: # we need to modify the opposite pole
|
||||
segment = int(knot / degree) -1
|
||||
cont=self.obj.Continuity[segment] if \
|
||||
len(self.obj.Continuity) > segment else 0
|
||||
cont=obj.Continuity[segment] if \
|
||||
len(obj.Continuity) > segment else 0
|
||||
if cont == 1: #tangent
|
||||
pts[changep] = self.obj.Proxy.modifytangentpole(\
|
||||
pts[changep] = obj.Proxy.modifytangentpole(\
|
||||
pts[knot],editPnt,pts[changep])
|
||||
if moveTrackers: self.trackers[self.obj.Name][changep].set(pts[changep])
|
||||
if moveTrackers: self.trackers[obj.Name][changep].set(pts[changep])
|
||||
elif cont ==2: #symmetric
|
||||
pts[changep] = self.obj.Proxy.modifysymmetricpole(\
|
||||
pts[changep] = obj.Proxy.modifysymmetricpole(\
|
||||
pts[knot],editPnt)
|
||||
if moveTrackers: self.trackers[self.obj.Name][changep].set(pts[changep])
|
||||
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
|
||||
@@ -903,17 +910,17 @@ class Edit():
|
||||
index,obj.ViewObject.LineColor,\
|
||||
marker=marker))
|
||||
|
||||
def smoothBezPoint(self, point, style='Symmetric'):
|
||||
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(self.obj) == "BezCurve"):return
|
||||
pts = self.obj.Points
|
||||
deg = self.obj.Degree
|
||||
if not (Draft.getType(obj) == "BezCurve"):return
|
||||
pts = obj.Points
|
||||
deg = obj.Degree
|
||||
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 self.obj.Closed): #right pole
|
||||
if (point % deg == 1) and (point > 2 or obj.Closed): #right pole
|
||||
knot = point -1
|
||||
keepp = point
|
||||
changep = point -2
|
||||
@@ -921,7 +928,7 @@ class Edit():
|
||||
knot = point +1
|
||||
keepp = point
|
||||
changep = point +2
|
||||
elif point == len(pts)-1 and self.obj.Closed: #last pole
|
||||
elif point == len(pts)-1 and obj.Closed: #last pole
|
||||
# if the curve is closed the last pole has the last
|
||||
# index in the points lists
|
||||
knot = 0
|
||||
@@ -932,10 +939,10 @@ class Edit():
|
||||
return
|
||||
if knot:
|
||||
if style == 'Tangent':
|
||||
pts[changep] = self.obj.Proxy.modifytangentpole(\
|
||||
pts[changep] = obj.Proxy.modifytangentpole(\
|
||||
pts[knot],pts[keepp],pts[changep])
|
||||
elif style == 'Symmetric':
|
||||
pts[changep] = self.obj.Proxy.modifysymmetricpole(\
|
||||
pts[changep] = obj.Proxy.modifysymmetricpole(\
|
||||
pts[knot],pts[keepp])
|
||||
else: #sharp
|
||||
pass #
|
||||
@@ -944,52 +951,64 @@ class Edit():
|
||||
return
|
||||
else: #point is a knot
|
||||
if style == 'Sharp':
|
||||
if self.obj.Closed and point == len(pts)-1:
|
||||
if obj.Closed and point == len(pts)-1:
|
||||
knot = 0
|
||||
else:
|
||||
knot = point
|
||||
elif style == 'Tangent' and point > 0 and point < len(pts)-1:
|
||||
prev, next = self.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 = self.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 self.obj.Closed and (style == 'Symmetric' or style == 'Tangent'):
|
||||
elif obj.Closed and (style == 'Symmetric' or style == 'Tangent'):
|
||||
if style == 'Tangent':
|
||||
pts[1],pts[-1] = self.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] = self.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")
|
||||
return
|
||||
segment = knot // deg #segment index
|
||||
newcont=self.obj.Continuity[:] #don't edit a property inplace !!!
|
||||
if not self.obj.Closed and (len(self.obj.Continuity) == segment -1 or \
|
||||
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(self.obj.Continuity) >= segment or \
|
||||
self.obj.Closed and segment == 0 and \
|
||||
len(self.obj.Continuity) >1:
|
||||
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,\
|
||||
len(self.obj.Continuity)))
|
||||
self.obj.Points = pts
|
||||
self.obj.Continuity=newcont
|
||||
self.resetTrackers()
|
||||
len(obj.Continuity)))
|
||||
obj.Points = pts
|
||||
obj.Continuity=newcont
|
||||
self.resetTrackers(obj)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# EDIT OBJECT TOOLS : Rectangle
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def setRectanglePts(self, obj):
|
||||
self.editpoints.append(obj.Placement.Base)
|
||||
self.editpoints.append(obj.Shape.Vertexes[2].Point)
|
||||
def getRectanglePts(self, obj):
|
||||
'''
|
||||
returns the list of edipoints for the given Draft Rectangle
|
||||
circle:
|
||||
0 : Placement.Base or center
|
||||
1 : radius
|
||||
arc:
|
||||
0 : Placement.Base or center
|
||||
1 : first endpoint
|
||||
2 : second endpoint
|
||||
3 : midpoint
|
||||
'''
|
||||
editpoints = []
|
||||
editpoints.append(obj.getGlobalPlacement().Base)
|
||||
editpoints.append(obj.getGlobalPlacement().multVec(obj.Shape.Vertexes[2].Point))
|
||||
v = obj.Shape.Vertexes
|
||||
self.bx = v[1].Point.sub(v[0].Point)
|
||||
if obj.Length < 0:
|
||||
@@ -997,16 +1016,17 @@ class Edit():
|
||||
self.by = v[2].Point.sub(v[1].Point)
|
||||
if obj.Height < 0:
|
||||
self.by = self.by.negative()
|
||||
return editpoints
|
||||
|
||||
def updateRectangle(self,v):
|
||||
def updateRectangle(self, obj, nodeIndex, v):
|
||||
import DraftVecUtils
|
||||
delta = v.sub(self.obj.Placement.Base)
|
||||
if self.editing == 0:
|
||||
p = self.obj.Placement
|
||||
delta = v.sub(obj.Placement.Base)
|
||||
if nodeIndex == 0:
|
||||
p = obj.Placement
|
||||
p.move(delta)
|
||||
self.obj.Placement = p
|
||||
obj.Placement = p
|
||||
elif self.editing == 1:
|
||||
diag = v.sub(self.obj.Placement.Base)
|
||||
diag = v.sub(obj.Placement.Base)
|
||||
nx = DraftVecUtils.project(diag,self.bx)
|
||||
ny = DraftVecUtils.project(diag,self.by)
|
||||
ax = nx.Length
|
||||
@@ -1016,11 +1036,11 @@ class Edit():
|
||||
ax = -ax
|
||||
if abs(ny.getAngle(self.by)) > 0.1:
|
||||
ay = -ay
|
||||
self.obj.Length = ax
|
||||
self.obj.Height = ay
|
||||
self.obj.recompute()
|
||||
self.trackers[self.obj.Name][0].set(self.obj.Placement.Base)
|
||||
self.trackers[self.obj.Name][1].set(self.obj.Shape.Vertexes[2].Point)
|
||||
obj.Length = ax
|
||||
obj.Height = ay
|
||||
obj.recompute()
|
||||
self.trackers[obj.Name][0].set(obj.Placement.Base)
|
||||
self.trackers[obj.Name][1].set(obj.Shape.Vertexes[2].Point)
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# EDIT OBJECT TOOLS : Ellipse (# TODO: yet to be implemented)
|
||||
@@ -1036,19 +1056,31 @@ class Edit():
|
||||
# EDIT OBJECT TOOLS : Circle/Arc
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def setCirclePts(self, obj):
|
||||
self.editpoints.append(obj.Placement.Base)
|
||||
def getCirclePts(self, obj):
|
||||
'''
|
||||
returns the list of edipoints for the given Draft Arc or Circle
|
||||
circle:
|
||||
0 : Placement.Base or center
|
||||
1 : radius
|
||||
arc:
|
||||
0 : Placement.Base or center
|
||||
1 : first endpoint
|
||||
2 : second endpoint
|
||||
3 : midpoint
|
||||
'''
|
||||
editpoints = []
|
||||
editpoints.append(obj.Placement.Base)
|
||||
if obj.FirstAngle == obj.LastAngle:#self.obj is a circle
|
||||
self.ui.editUi("Circle")
|
||||
self.editpoints.append(obj.Shape.Vertexes[0].Point)
|
||||
editpoints.append(obj.Shape.Vertexes[0].Point)
|
||||
else:#self.obj is an arc
|
||||
self.ui.editUi("Arc")
|
||||
self.editpoints.append(obj.Shape.Vertexes[0].Point)#First endpoint
|
||||
self.editpoints.append(obj.Shape.Vertexes[1].Point)#Second endpoint
|
||||
self.editpoints.append(self.getArcMid(obj))#Midpoint
|
||||
return
|
||||
editpoints.append(obj.Shape.Vertexes[0].Point)#First endpoint
|
||||
editpoints.append(obj.Shape.Vertexes[1].Point)#Second endpoint
|
||||
editpoints.append(self.getArcMid(obj))#Midpoint
|
||||
return editpoints
|
||||
|
||||
def updateCirclePts(self,ep1=1,ep2=1,ep3=1,ep4=1):
|
||||
def updateCircleTrackers(self,ep1=1,ep2=1,ep3=1,ep4=1):
|
||||
self.obj.recompute()
|
||||
if ep1 == 1:
|
||||
self.trackers[self.obj.Name][0].set(self.obj.Placement.Base)
|
||||
@@ -1059,7 +1091,7 @@ class Edit():
|
||||
if ep4 == 1:
|
||||
self.trackers[self.obj.Name][3].set(self.getArcMid(self.obj))
|
||||
|
||||
def updateCircle(self,v):
|
||||
def updateCircle(self, obj, nodeIndex, v):
|
||||
delta = self.invpl.multVec(v)
|
||||
if self.obj.FirstAngle == self.obj.LastAngle:# object is a circle
|
||||
if self.editing == 0:
|
||||
@@ -1161,11 +1193,13 @@ class Edit():
|
||||
# EDIT OBJECT TOOLS : Polygon (maybe could also rotate the polygon)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def setPolygonPts(self, obj):
|
||||
self.editpoints.append(obj.Placement.Base)
|
||||
self.editpoints.append(obj.Shape.Vertexes[0].Point)
|
||||
def getPolygonPts(self, obj):
|
||||
editpoints = []
|
||||
editpoints.append(obj.Placement.Base)
|
||||
editpoints.append(obj.Shape.Vertexes[0].Point)
|
||||
return editpoints
|
||||
|
||||
def updatePolygon(self,v):
|
||||
def updatePolygon(self, obj, nodeIndex, v):
|
||||
delta = v.sub(self.obj.Placement.Base)
|
||||
if self.editing == 0:
|
||||
p = self.obj.Placement
|
||||
@@ -1186,14 +1220,16 @@ class Edit():
|
||||
# EDIT OBJECT TOOLS : Dimension (point on dimension line is not clickable)
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def setDimensionPts(self, obj):
|
||||
def getDimensionPts(self, obj):
|
||||
editpoints = []
|
||||
p = obj.ViewObject.Proxy.textpos.translation.getValue()
|
||||
self.editpoints.append(obj.Start)
|
||||
self.editpoints.append(obj.End)
|
||||
self.editpoints.append(obj.Dimline)
|
||||
self.editpoints.append(Vector(p[0],p[1],p[2]))
|
||||
editpoints.append(obj.Start)
|
||||
editpoints.append(obj.End)
|
||||
editpoints.append(obj.Dimline)
|
||||
editpoints.append(Vector(p[0],p[1],p[2]))
|
||||
return editpoints
|
||||
|
||||
def updateDimension(self,v):
|
||||
def updateDimension(self, obj, nodeIndex, v):
|
||||
if self.editing == 0:
|
||||
self.obj.Start = v
|
||||
elif self.editing == 1:
|
||||
@@ -1209,62 +1245,97 @@ class Edit():
|
||||
|
||||
# SKETCH: just if it's composed by a single segment-------------------------
|
||||
|
||||
def setSketchPts(self, obj):
|
||||
def getSketchPts(self, obj):
|
||||
'''
|
||||
returns the list of edipoints for the given single line sketch (WallTrace)
|
||||
0 : startpoint
|
||||
1 : endpoint
|
||||
'''
|
||||
editpoints = []
|
||||
if obj.GeometryCount == 1:
|
||||
self.editpoints.append(self.pl.multVec(obj.getPoint(0,1)))
|
||||
self.editpoints.append(self.pl.multVec(obj.getPoint(0,2)))
|
||||
editpoints.append(obj.getGlobalPlacement().multVec(obj.getPoint(0,1)))
|
||||
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 editor")+"\n")
|
||||
to edit: it is suggested to use sketcher default editor")+"\n")
|
||||
return None
|
||||
|
||||
def updateSketch(self,v):
|
||||
if self.editing == 0:
|
||||
self.obj.movePoint(0,1,self.invpl.multVec(v))
|
||||
self.obj.recompute()
|
||||
if self.editing == 1:
|
||||
self.obj.movePoint(0,2,self.invpl.multVec(v))
|
||||
self.obj.recompute()
|
||||
def updateSketch(self, obj, nodeIndex, v):
|
||||
'''
|
||||
(single segment sketch object, node index as Int, Vector)
|
||||
move a single line sketch (WallTrace) vertex according to a given vector
|
||||
0 : startpoint
|
||||
1 : endpoint
|
||||
'''
|
||||
if nodeIndex == 0:
|
||||
obj.movePoint(0,1,obj.getGlobalPlacement().inverse().multVec(v))
|
||||
elif nodeIndex == 1:
|
||||
obj.movePoint(0,2,obj.getGlobalPlacement().inverse().multVec(v))
|
||||
obj.recompute()
|
||||
|
||||
|
||||
#WALL-----------------------------------------------------------------------
|
||||
|
||||
def setWallPts(self, obj):
|
||||
def getWallPts(self, obj):
|
||||
'''
|
||||
returns the list of edipoints for the given Arch Wall object
|
||||
0 : height of the wall
|
||||
1-to end : base object editpoints, in place with the wall
|
||||
'''
|
||||
editpoints = []
|
||||
#height of the wall
|
||||
editpoints.append(obj.getGlobalPlacement().multVec(FreeCAD.Vector(0,0,obj.Height)))
|
||||
# try to add here an editpoint based on wall height (maybe should be good to associate it with a circular tracker)
|
||||
if Draft.getType(obj.Base) in ["Wire","Circle","Rectangle",
|
||||
"Polygon", "Sketch"]:
|
||||
self.setEditPoints(obj.Base)
|
||||
pl=obj.Base.Placement.multiply(obj.Placement)
|
||||
self.editpoints.append(pl.multVec(FreeCAD.Vector(0,0,obj.Height)))
|
||||
if obj.Base:
|
||||
# base points are added to self.trackers under wall-name key
|
||||
basepoints = []
|
||||
if Draft.getType(obj.Base) in ["Wire","Circle","Rectangle",
|
||||
"Polygon", "Sketch"]:
|
||||
basepoints = self.getEditPoints(obj.Base)
|
||||
for point in basepoints:
|
||||
editpoints.append(obj.Placement.multVec(point)) #works ok except if App::Part is rotated... why?
|
||||
return editpoints
|
||||
|
||||
def updateWall(self,v):
|
||||
|
||||
def updateWallTrackers(self, obj):
|
||||
'''
|
||||
update self.trackers[obj.Name][0] to match with given object
|
||||
'''
|
||||
pass
|
||||
|
||||
def updateWall(self, obj, nodeIndex, v):
|
||||
import DraftVecUtils
|
||||
if Draft.getType(self.obj.Base) in ["Wire","Circle","Rectangle",
|
||||
"Polygon", "Sketch"]:
|
||||
invpl=self.obj.Base.Placement.multiply(self.obj.Placement).inverse()
|
||||
else:
|
||||
invpl=self.invpl
|
||||
if self.editing == 0:
|
||||
delta= invpl.multVec(v)
|
||||
if nodeIndex == 0:
|
||||
delta= obj.getGlobalPlacement().inverse().multVec(v)
|
||||
vz=DraftVecUtils.project(delta,FreeCAD.Vector(0,0,1))
|
||||
self.obj.Height=vz.Length
|
||||
self.obj.recompute()
|
||||
if vz.Length > 0:
|
||||
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))
|
||||
obj.recompute()
|
||||
|
||||
|
||||
#WINDOW---------------------------------------------------------------------
|
||||
|
||||
def setWindowPts(self, obj):
|
||||
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))
|
||||
self.editpoints.append(pos)
|
||||
self.editpoints.append(FreeCAD.Vector(pos.x+float(obj.Width)*math.cos(angle-math.pi/2),
|
||||
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),
|
||||
pos.z))
|
||||
self.editpoints.append(FreeCAD.Vector(pos.x,pos.y,h))
|
||||
editpoints.append(FreeCAD.Vector(pos.x,pos.y,h))
|
||||
return editpoints
|
||||
|
||||
def updateWindow(self,v):
|
||||
def updateWindow(self, obj, nodeIndex, v):
|
||||
pos=self.obj.Base.Placement.Base
|
||||
if self.editing == 0:
|
||||
self.obj.Base.Placement.Base=v
|
||||
@@ -1281,8 +1352,9 @@ class Edit():
|
||||
|
||||
#STRUCTURE-------------------------------------------------------------------
|
||||
|
||||
def setStructurePts(self, obj):
|
||||
def getStructurePts(self, obj):
|
||||
if obj.Nodes:
|
||||
editpoints = []
|
||||
self.originalDisplayMode = obj.ViewObject.DisplayMode
|
||||
self.originalPoints = obj.ViewObject.NodeSize
|
||||
self.originalNodes = obj.ViewObject.ShowNodes
|
||||
@@ -1292,45 +1364,53 @@ class Edit():
|
||||
for p in obj.Nodes:
|
||||
if self.pl:
|
||||
p = self.pl.multVec(p)
|
||||
self.editpoints.append(p)
|
||||
else: return
|
||||
editpoints.append(p)
|
||||
return editpoints
|
||||
else:
|
||||
return None
|
||||
|
||||
def updateStructure(self,v):
|
||||
def updateStructure(self, obj, nodeIndex, v):
|
||||
nodes = self.obj.Nodes
|
||||
nodes[self.editing] = self.invpl.multVec(v)
|
||||
self.obj.Nodes = nodes
|
||||
|
||||
#SPACE----------------------------------------------------------------------
|
||||
|
||||
def setSpacePts(self, obj):
|
||||
def getSpacePts(self, obj):
|
||||
try:
|
||||
editpoints = []
|
||||
self.editpoints.append(obj.ViewObject.Proxy.getTextPosition(obj.ViewObject))
|
||||
return editpoints
|
||||
except:
|
||||
pass
|
||||
|
||||
def updateSpace(self,v):
|
||||
def updateSpace(self, obj, nodeIndex, v):
|
||||
if self.editing == 0:
|
||||
self.obj.ViewObject.TextPosition = v
|
||||
|
||||
#PANELS---------------------------------------------------------------------
|
||||
|
||||
def setPanelCutPts(self, obj):
|
||||
def getPanelCutPts(self, obj):
|
||||
editpoints = []
|
||||
if self.obj.TagPosition.Length == 0:
|
||||
pos = obj.Shape.BoundBox.Center
|
||||
else:
|
||||
pos = self.pl.multVec(obj.TagPosition)
|
||||
self.editpoints.append(pos)
|
||||
editpoints.append(pos)
|
||||
return editpoints
|
||||
|
||||
def updatePanelCut(self,v):
|
||||
def updatePanelCut(self, obj, nodeIndex, v):
|
||||
if self.editing == 0:
|
||||
self.obj.TagPosition = self.invpl.multVec(v)
|
||||
|
||||
def setPanelSheetPts(self, obj):
|
||||
self.editpoints.append(self.pl.multVec(obj.TagPosition))
|
||||
def getPanelSheetPts(self, obj):
|
||||
editpoints = []
|
||||
editpoints.append(self.pl.multVec(obj.TagPosition))
|
||||
for o in obj.Group:
|
||||
self.editpoints.append(self.pl.multVec(o.Placement.Base))
|
||||
editpoints.append(self.pl.multVec(o.Placement.Base))
|
||||
return editpoints
|
||||
|
||||
def updatePanelSheet(self,v):
|
||||
def updatePanelSheet(self, obj, nodeIndex, v):
|
||||
if self.editing == 0:
|
||||
self.obj.TagPosition = self.invpl.multVec(v)
|
||||
else:
|
||||
@@ -1338,11 +1418,13 @@ class Edit():
|
||||
|
||||
# PART::LINE----------------------------------------------------------------
|
||||
|
||||
def setPartLinePts(self, obj):
|
||||
self.editpoints.append(self.pl.multVec(FreeCAD.Vector(obj.X1,obj.Y1,obj.Z1)))
|
||||
self.editpoints.append(self.pl.multVec(FreeCAD.Vector(obj.X2,obj.Y2,obj.Z2)))
|
||||
def getPartLinePts(self, obj):
|
||||
editpoints = []
|
||||
editpoints.append(self.pl.multVec(FreeCAD.Vector(obj.X1,obj.Y1,obj.Z1)))
|
||||
editpoints.append(self.pl.multVec(FreeCAD.Vector(obj.X2,obj.Y2,obj.Z2)))
|
||||
return editpoints
|
||||
|
||||
def updatePartLine(self,v):
|
||||
def updatePartLine(self, obj, nodeIndex, v):
|
||||
pt=self.invpl.multVec(v)
|
||||
if self.editing == 0:
|
||||
self.obj.X1 = pt.x
|
||||
@@ -1355,13 +1437,15 @@ class Edit():
|
||||
|
||||
# PART::BOX-----------------------------------------------------------------
|
||||
|
||||
def setPartBoxPts(self, obj):
|
||||
self.editpoints.append(obj.Placement.Base)
|
||||
self.editpoints.append(self.pl.multVec(FreeCAD.Vector(obj.Length,0,0)))
|
||||
self.editpoints.append(self.pl.multVec(FreeCAD.Vector(0,obj.Width,0)))
|
||||
self.editpoints.append(self.pl.multVec(FreeCAD.Vector(0,0,obj.Height)))
|
||||
def getPartBoxPts(self, obj):
|
||||
editpoints = []
|
||||
editpoints.append(obj.Placement.Base)
|
||||
editpoints.append(self.pl.multVec(FreeCAD.Vector(obj.Length,0,0)))
|
||||
editpoints.append(self.pl.multVec(FreeCAD.Vector(0,obj.Width,0)))
|
||||
editpoints.append(self.pl.multVec(FreeCAD.Vector(0,0,obj.Height)))
|
||||
return editpoints
|
||||
|
||||
def updatePartBox(self,v):
|
||||
def updatePartBox(self, obj, nodeIndex, v):
|
||||
import DraftVecUtils
|
||||
delta = self.invpl.multVec(v)
|
||||
if self.editing == 0:
|
||||
|
||||
Reference in New Issue
Block a user