Draft: bugfix on Edit BezCurve

This commit is contained in:
carlopav
2020-05-24 15:28:13 +02:00
committed by Yorik van Havre
parent f4a47d0ecf
commit b6b48b43ec
2 changed files with 79 additions and 92 deletions

View File

@@ -209,7 +209,7 @@ class Edit(gui_base_original.Modifier):
The tool use utils.get_type(obj) to compare object type
to the list.
supportedPartObjs: List
supportedCppObjs: List
List of supported Part Objects.
The tool use utils.get_type(obj) and obj.TypeId to compare
object type to the list.
@@ -246,7 +246,7 @@ class Edit(gui_base_original.Modifier):
#list of supported objects
self.supportedObjs = edit_draft.get_supported_draft_objects() + \
edit_arch.get_supported_arch_objects()
self.supportedPartObjs = edit_part.get_supported_part_objects() + \
self.supportedCppObjs = edit_part.get_supported_part_objects() + \
edit_sketcher.get_supported_sketcher_objects()
@@ -538,28 +538,50 @@ class Edit(gui_base_original.Modifier):
def setTrackers(self, obj, points=None):
"""Set Edit Trackers for editpoints collected from self.obj."""
if utils.get_type(obj) == "BezCurve":
return self.resetTrackersBezier(obj)
if points is None or len(points) == 0:
App.Console.PrintWarning(translate("draft",
"No edit point found for selected object")
+ "\n")
_wrn = translate("draft", "No edit point found for selected object")
App.Console.PrintWarning(_wrn + "\n")
# do not finish if some trackers are still present
if self.trackers == {'object': []}:
self.finish()
return
self.trackers[obj.Name] = []
if utils.get_type(obj) == "BezCurve":
edit_draft.resetTrackersBezier(obj)
else:
if obj.Name in self.trackers:
self.removeTrackers(obj)
for ep in range(len(points)):
self.trackers[obj.Name].append(trackers.editTracker(pos=points[ep],name=obj.Name,idx=ep))
if obj.Name in self.trackers:
self.removeTrackers(obj)
for ep in range(len(points)):
self.trackers[obj.Name].append(trackers.editTracker(pos=points[ep], name=obj.Name, idx=ep))
def resetTrackers(self, obj):
"""Reset Edit Trackers and set them again."""
self.removeTrackers(obj)
self.setTrackers(obj, self.getEditPoints(obj))
def resetTrackersBezier(self, obj):
# in future move tracker definition to DraftTrackers
from pivy import coin
knotmarkers = (coin.SoMarkerSet.DIAMOND_FILLED_9_9,#sharp
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
firstknotcont = cont[-1] if (obj.Closed and cont) else 0
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]])
if not obj.Closed or len(obj.Shape.Edges) > edgeindex +1:
knotmarkeri = cont[edgeindex] if len(cont) > edgeindex else 0
pointswithmarkers.append((poles[-1],knotmarkers[knotmarkeri]))
for index, pwm in enumerate(pointswithmarkers):
p, marker = pwm
p = obj.getGlobalPlacement().multVec(p)
self.trackers[obj.Name].append(trackers.editTracker(p, obj.Name,
index, obj.ViewObject.LineColor, marker=marker))
def removeTrackers(self, obj=None):
"""Remove Edit Trackers."""
if obj:
@@ -641,7 +663,7 @@ class Edit(gui_base_original.Modifier):
elif utils.get_type(obj) == "BezCurve":
self.ghost.on()
plist = self.globalize_vectors(obj, obj.Points)
pointList = edit_draft.recomputePointsBezier(obj,plist,idx,pt,obj.Degree,moveTrackers=True)
pointList = edit_draft.recomputePointsBezier(obj,plist,idx,pt,obj.Degree,moveTrackers=False)
self.ghost.update(pointList,obj.Degree)
elif utils.get_type(obj) == "Circle":
self.ghost.on()
@@ -852,6 +874,9 @@ class Edit(gui_base_original.Modifier):
ep = self.overNode.get_subelement_index()
if utils.get_type(obj) in ["Line", "Wire", "BSpline"]:
actions = ["delete point"]
elif utils.get_type(obj) in ["BezCurve"]:
actions = ["make sharp", "make tangent",
"make symmetric", "delete point"]
elif utils.get_type(obj) in ["Circle"]:
if obj.FirstAngle != obj.LastAngle:
if ep == 0: # user is over arc start point
@@ -862,9 +887,6 @@ class Edit(gui_base_original.Modifier):
actions = ["set last angle"]
elif ep == 3: # user is over arc mid point
actions = ["set radius"]
elif utils.get_type(obj) in ["BezCurve"]:
actions = ["make sharp", "make tangent",
"make symmetric", "delete point"]
else:
return
else:
@@ -880,13 +902,20 @@ class Edit(gui_base_original.Modifier):
for a in actions:
self.tracker_menu.addAction(a)
self.tracker_menu.popup(Gui.getMainWindow().cursor().pos())
QtCore.QObject.connect(self.tracker_menu,QtCore.SIGNAL("triggered(QAction *)"),self.evaluate_menu_action)
QtCore.QObject.connect(self.tracker_menu,
QtCore.SIGNAL("triggered(QAction *)"),
self.evaluate_menu_action)
def evaluate_menu_action(self, labelname):
action_label = str(labelname.text())
# addPoint and deletePoint menu
if action_label == "delete point":
self.delPoint(self.event)
elif action_label == "add point":
self.addPoint(self.event)
# Bezier curve menu
if action_label in ["make sharp", "make tangent", "make symmetric"]:
elif action_label in ["make sharp", "make tangent", "make symmetric"]:
doc = self.overNode.get_doc_name()
obj = App.getDocument(doc).getObject(self.overNode.get_obj_name())
idx = self.overNode.get_subelement_index()
@@ -896,11 +925,7 @@ class Edit(gui_base_original.Modifier):
edit_draft.smoothBezPoint(obj, idx, 'Tangent')
elif action_label == "make symmetric":
edit_draft.smoothBezPoint(obj, idx, 'Symmetric')
# addPoint and deletePoint menu
elif action_label == "delete point":
self.delPoint(self.event)
elif action_label == "add point":
self.addPoint(self.event)
self.resetTrackers(obj)
# arc tools
elif action_label in ("move arc", "set radius",
"set first angle", "set last angle"):
@@ -930,8 +955,6 @@ class Edit(gui_base_original.Modifier):
eps = edit_draft.getWirePts(obj)
elif objectType == "BezCurve":
self.ui.editUi("BezCurve")
edit_draft.resetTrackersBezier(obj)
return
elif objectType == "Circle":
@@ -999,15 +1022,11 @@ class Edit(gui_base_original.Modifier):
def update(self, obj, nodeIndex, v):
"""Apply the App.Vector to the modified point and update obj."""
v = self.relativize_vector(obj, v)
App.ActiveDocument.openTransaction("Edit")
self.update_object(obj, nodeIndex, v)
App.ActiveDocument.commitTransaction()
self.resetTrackers(obj)
try:
gui_tool_utils.redraw_3d_view()
except AttributeError as err:
@@ -1096,26 +1115,22 @@ class Edit(gui_base_original.Modifier):
obj = selobj.Object
obj_matrix = selobj.Object.getSubObject(sub, retType=4)
"""
selection = Gui.Selection.getSelection()
self.edited_objects = []
if len(selection) > self.maxObjects:
App.Console.PrintMessage(translate("draft",
"Too many objects selected, max number set to: ")
+ str(self.maxObjects) + "\n")
_err = translate("draft", "Too many objects selected, max number set to: ")
App.Console.PrintMessage(_err + str(self.maxObjects) + "\n")
return None
for obj in selection:
if utils.get_type(obj) in self.supportedObjs:
self.edited_objects.append(obj)
continue
elif utils.get_type(obj) in self.supportedPartObjs:
if obj.TypeId in self.supportedPartObjs:
elif utils.get_type(obj) in self.supportedCppObjs:
if obj.TypeId in self.supportedCppObjs:
self.edited_objects.append(obj)
continue
App.Console.PrintWarning(obj.Name
+ translate("draft",
": this object is not editable")
+ "\n")
_wrn = translate("draft", ": this object is not editable")
App.Console.PrintWarning(obj.Name + _wrn + "\n")
return self.edited_objects

View File

@@ -57,7 +57,7 @@ def get_supported_draft_objects():
# -------------------------------------------------------------------------
# EDIT OBJECT TOOLS : Line/Wire/Bspline
# EDIT OBJECT TOOLS : Line/Wire/BSpline
# -------------------------------------------------------------------------
def getWirePts(obj):
@@ -106,48 +106,43 @@ def updateWire(obj, nodeIndex, v):
def updateBezCurve(obj, nodeIndex, v): #TODO: Fix it
pts = obj.Points
editPnt = v
# DNC: check for coincident startpoint/endpoint to auto close the curve
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 ( (v - pts[-1]).Length < tol) ) or (
nodeIndex == len(pts) - 1 ) and ( (v - pts[0]).Length < tol):
obj.Closed = True
# DNC: checks if point enter is equal to other, this could cause a OCC problem
if editPnt in pts:
if v in pts:
_err = translate("draft", "This object does not support possible "
"coincident points, please try again.")
App.Console.PrintMessage(_err + "\n")
return
pts = recomputePointsBezier(obj,pts,nodeIndex,v,obj.Degree,moveTrackers=False)
pts = recomputePointsBezier(obj, pts, nodeIndex, v, obj.Degree, moveTrackers=False)
if obj.Closed:
# check that the new point lies on the plane of the wire
if hasattr(obj.Shape,"normalAt"):
normal = obj.Shape.normalAt(0,0)
point_on_plane = obj.Shape.Vertexes[0].Point
print(v)
v.projectToPlane(point_on_plane, normal)
print(v)
editPnt = obj.getGlobalPlacement().inverse().multVec(v)
pts[nodeIndex] = editPnt
pts[nodeIndex] = v
obj.Points = pts
def recomputePointsBezier(obj, pts, idx, v,
degree, moveTrackers=True):
degree, moveTrackers=False):
"""
(object, Points as list, nodeIndex as Int, App.Vector of new point, moveTrackers as Bool)
return the new point list, applying the App.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 ( (v - pts[-1]).Length < tol) ) or (
idx == len(pts) - 1 ) and ( (v - 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:
#if ( v in pts ) == False:
knot = None
ispole = idx % degree
@@ -155,17 +150,17 @@ def recomputePointsBezier(obj, pts, idx, v,
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]) # TODO: Remove code to recompute trackers
pts[idx-1] = pts[idx-1] + v - pts[knotidx]
#if moveTrackers: # trackers are reseted after editing
# 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])
pts[idx+1] = pts[idx+1] + v - pts[idx]
#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])
pts[-1] = pts [-1] + v -pts[idx]
#if moveTrackers:
# self.trackers[obj.Name][-1].set(pts[-1])
elif ispole == 1 and (idx >=2 or obj.Closed): #right pole
knot = idx -1
@@ -184,40 +179,17 @@ def recomputePointsBezier(obj, pts, idx, v,
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])
v,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.modifysymmetricpole(pts[knot],v)
#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
def resetTrackersBezier(obj):
# in future move tracker definition to DraftTrackers
from pivy import coin
knotmarkers = (coin.SoMarkerSet.DIAMOND_FILLED_9_9,#sharp
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
firstknotcont = cont[-1] if (obj.Closed and cont) else 0
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]])
if not obj.Closed or len(obj.Shape.Edges) > edgeindex +1:
knotmarkeri = cont[edgeindex] if len(cont) > edgeindex else 0
pointswithmarkers.append((poles[-1],knotmarkers[knotmarkeri]))
for index, pwm in enumerate(pointswithmarkers):
p, marker = pwm
# if self.pl: p = self.pl.multVec(p)
self.trackers[obj.Name].append(trackers.editTracker(p,obj.Name,
index,obj.ViewObject.LineColor,marker=marker))
def smoothBezPoint(obj, point, style='Symmetric'):
"called when changing the continuity of a knot"