[Draft] Edit: add support for arc editing in App::Part
This commit is contained in:
committed by
Yorik van Havre
parent
18350dbf9d
commit
c87bc0a8ef
@@ -191,6 +191,12 @@ class Edit():
|
||||
it is initialized when user clicks on a editTracker
|
||||
by self.startEditing() function.
|
||||
|
||||
alt_edit_mode : Int
|
||||
Allows alternative editing modes for objects.
|
||||
ATM supported for:
|
||||
- arcs: if 0 edit by 3 points, if 1 edit by center,
|
||||
radius, angles
|
||||
|
||||
supportedObjs : List
|
||||
List of supported Draft Objects.
|
||||
The tool use Draft.getType(obj) to compare object type
|
||||
@@ -230,7 +236,7 @@ class Edit():
|
||||
self.maxObjects = param.GetInt("DraftEditMaxObjects", 5)
|
||||
self.pick_radius = param.GetInt("DraftEditPickRadius", 20)
|
||||
|
||||
self.arc_edit_mode = 1 # set 1 for 3 points, 0 for angle and radius
|
||||
self.alt_edit_mode = 0 # alternative edit mode for objects
|
||||
|
||||
# preview
|
||||
self.ghost = None
|
||||
@@ -535,7 +541,7 @@ class Edit():
|
||||
# position should be updated manually
|
||||
self.trackers[obj.Name][nodeIndex].set(v)
|
||||
self.update(obj, nodeIndex, v)
|
||||
self.arc_edit_mode = 1
|
||||
self.alt_edit_mode = 0
|
||||
self.ui.editUi(self.ui.lastMode)
|
||||
self.node = []
|
||||
self.editing = None
|
||||
@@ -584,8 +590,8 @@ class Edit():
|
||||
return obj
|
||||
|
||||
def numericInput(self, v, numy=None, numz=None):
|
||||
'''this function gets called by the toolbar
|
||||
or by the mouse click and activate the update function'''
|
||||
"""this function gets called by the toolbar
|
||||
or by the mouse click and activate the update function"""
|
||||
if (numy is not None):
|
||||
v = App.Vector(v,numy,numz)
|
||||
self.endEditing(self.obj, self.editing, v)
|
||||
@@ -771,7 +777,8 @@ class Edit():
|
||||
self.ghost.on()
|
||||
self.ghost.setCenter(obj.getGlobalPlacement().Base)
|
||||
self.ghost.setRadius(obj.Radius)
|
||||
if self.obj.FirstAngle == self.obj.LastAngle:#self.obj is a circle
|
||||
if self.obj.FirstAngle == self.obj.LastAngle:
|
||||
# self.obj is a circle
|
||||
self.ghost.circle = True
|
||||
if self.editing == 0:
|
||||
self.ghost.setCenter(pt)
|
||||
@@ -779,7 +786,33 @@ class Edit():
|
||||
radius = pt.sub(obj.getGlobalPlacement().Base).Length
|
||||
self.ghost.setRadius(radius)
|
||||
else:
|
||||
if self.arc_edit_mode == 0:
|
||||
if self.alt_edit_mode == 0:
|
||||
# edit by 3 points
|
||||
if self.editing == 0:
|
||||
# center point
|
||||
import DraftVecUtils
|
||||
p1 = self.invpl.multVec(self.obj.Shape.Vertexes[0].Point)
|
||||
p2 = self.invpl.multVec(self.obj.Shape.Vertexes[1].Point)
|
||||
p0 = DraftVecUtils.project(self.invpl.multVec(pt),self.invpl.multVec(self.getArcMid(obj, global_placement=True)))
|
||||
self.ghost.autoinvert=False
|
||||
self.ghost.setRadius(p1.sub(p0).Length)
|
||||
self.ghost.setStartPoint(self.obj.Shape.Vertexes[1].Point)
|
||||
self.ghost.setEndPoint(self.obj.Shape.Vertexes[0].Point)
|
||||
self.ghost.setCenter(self.pl.multVec(p0))
|
||||
return
|
||||
else:
|
||||
p1=self.getArcStart(obj,global_placement=True)
|
||||
p2=self.getArcMid(obj,global_placement=True)
|
||||
p3=self.getArcEnd(obj,global_placement=True)
|
||||
if self.editing == 1:
|
||||
p1=pt
|
||||
elif self.editing == 3:
|
||||
p2=pt
|
||||
elif self.editing == 2:
|
||||
p3=pt
|
||||
self.ghost.setBy3Points(p1,p2,p3)
|
||||
elif self.alt_edit_mode == 1:
|
||||
# edit by center radius angles
|
||||
self.ghost.setStartAngle(math.radians(obj.FirstAngle))
|
||||
self.ghost.setEndAngle(math.radians(obj.LastAngle))
|
||||
if self.editing == 0:
|
||||
@@ -790,29 +823,6 @@ class Edit():
|
||||
self.ghost.setEndPoint(pt)
|
||||
elif self.editing == 3:
|
||||
self.ghost.setRadius(self.invpl.multVec(pt).Length)
|
||||
elif self.arc_edit_mode == 1:
|
||||
if self.editing == 0:#center point
|
||||
import DraftVecUtils
|
||||
p1 = self.invpl.multVec(self.obj.Shape.Vertexes[0].Point)
|
||||
p2 = self.invpl.multVec(self.obj.Shape.Vertexes[1].Point)
|
||||
p0 = DraftVecUtils.project(self.invpl.multVec(pt),self.invpl.multVec(self.getArcMid(self.obj)))
|
||||
self.ghost.autoinvert=False
|
||||
self.ghost.setRadius(p1.sub(p0).Length)
|
||||
self.ghost.setStartPoint(self.obj.Shape.Vertexes[1].Point)
|
||||
self.ghost.setEndPoint(self.obj.Shape.Vertexes[0].Point)
|
||||
self.ghost.setCenter(self.pl.multVec(p0))
|
||||
return
|
||||
else:
|
||||
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
|
||||
self.ghost.setBy3Points(p1,p2,p3)
|
||||
DraftTools.redraw3DView()
|
||||
|
||||
def applyPlacement(self,pointList):
|
||||
@@ -980,9 +990,9 @@ class Edit():
|
||||
self.editpoints = []
|
||||
|
||||
def getEditPoints(self, obj):
|
||||
'''
|
||||
"""
|
||||
(object) return a list of App.Vectors relative to object edit nodes
|
||||
'''
|
||||
"""
|
||||
objectType = Draft.getType(obj)
|
||||
|
||||
if objectType in ["Wire","BSpline"]:
|
||||
@@ -1292,12 +1302,12 @@ class Edit():
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def getRectanglePts(self, obj):
|
||||
'''
|
||||
"""
|
||||
returns the list of edipoints for the given Draft Rectangle
|
||||
0 : Placement.Base
|
||||
1 : Length
|
||||
2 : Height
|
||||
'''
|
||||
"""
|
||||
editpoints = []
|
||||
editpoints.append(obj.getGlobalPlacement().Base)
|
||||
editpoints.append(obj.getGlobalPlacement().multVec(App.Vector(obj.Length,0,0)))
|
||||
@@ -1337,7 +1347,7 @@ class Edit():
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def getCirclePts(self, obj):
|
||||
'''
|
||||
"""
|
||||
returns the list of edipoints for the given Draft Arc or Circle
|
||||
circle:
|
||||
0 : Placement.Base or center
|
||||
@@ -1347,123 +1357,121 @@ class Edit():
|
||||
1 : first endpoint
|
||||
2 : second endpoint
|
||||
3 : midpoint
|
||||
'''
|
||||
"""
|
||||
editpoints = []
|
||||
editpoints.append(obj.getGlobalPlacement().Base)
|
||||
if obj.FirstAngle == obj.LastAngle:#self.obj is a circle
|
||||
if obj.FirstAngle == obj.LastAngle:
|
||||
# obj is a circle
|
||||
self.ui.editUi("Circle")
|
||||
editpoints.append(obj.getGlobalPlacement().multVec(App.Vector(obj.Radius,0,0)))
|
||||
else:#self.obj is an arc
|
||||
else:
|
||||
# obj is an arc
|
||||
self.ui.editUi("Arc")
|
||||
editpoints.append(self.getArcStart(obj))#First endpoint
|
||||
editpoints.append(self.getArcEnd(obj))#Second endpoint
|
||||
editpoints.append(self.getArcMid(obj))#Midpoint
|
||||
editpoints.append(self.getArcStart(obj, global_placement=True))#First endpoint
|
||||
editpoints.append(self.getArcEnd(obj, global_placement=True))#Second endpoint
|
||||
editpoints.append(self.getArcMid(obj, global_placement=True))#Midpoint
|
||||
return editpoints
|
||||
|
||||
def updateCircleTrackers(self,obj):
|
||||
def updateCircleTrackers(self, obj):
|
||||
self.trackers[obj.Name][0].set(obj.getGlobalPlacement().Base)
|
||||
self.trackers[obj.Name][1].set(self.getArcStart(obj))
|
||||
if len(self.trackers[obj.Name]) > 2: # object is a circle
|
||||
self.trackers[obj.Name][2].set(self.getArcEnd(obj))
|
||||
self.trackers[obj.Name][3].set(self.getArcMid(obj))
|
||||
self.trackers[obj.Name][1].set(self.getArcStart(obj, global_placement=True))
|
||||
if len(self.trackers[obj.Name]) > 2:
|
||||
# object is an arc
|
||||
self.trackers[obj.Name][2].set(self.getArcEnd(obj, global_placement=True))
|
||||
self.trackers[obj.Name][3].set(self.getArcMid(obj, global_placement=True))
|
||||
|
||||
def updateCircle(self, obj, nodeIndex, v):
|
||||
delta = obj.getGlobalPlacement().inverse().multVec(v)
|
||||
if obj.FirstAngle == obj.LastAngle:# object is a circle
|
||||
if self.editing == 0:
|
||||
obj.Placement.move(delta)
|
||||
elif self.editing == 1:
|
||||
local_v = obj.Placement.multVec(delta)
|
||||
|
||||
if obj.FirstAngle == obj.LastAngle:
|
||||
# object is a circle
|
||||
if nodeIndex == 0:
|
||||
obj.Placement.Base = local_v
|
||||
elif nodeIndex == 1:
|
||||
obj.Radius = delta.Length
|
||||
self.obj.recompute()
|
||||
self.updateCircleTrackers(obj)
|
||||
|
||||
else:#self.obj is an arc
|
||||
|
||||
if self.arc_edit_mode == 0:#edit by center radius FirstAngle LastAngle
|
||||
#deltaX = v[0]-self.obj.Placement.Base[0]
|
||||
#deltaY = v[1]-self.obj.Placement.Base[1]
|
||||
dangle = math.degrees(math.atan2(delta[1],delta[0]))
|
||||
if self.editing == 0:
|
||||
p = self.obj.Placement
|
||||
p.move(delta)
|
||||
self.obj.Placement = p
|
||||
self.setPlacement(self.obj)
|
||||
self.updateCircleTrackers(obj)
|
||||
elif self.editing == 1:
|
||||
self.obj.FirstAngle = dangle
|
||||
self.obj.recompute()
|
||||
self.updateCircleTrackers(obj)
|
||||
elif self.editing == 2:
|
||||
self.obj.LastAngle = dangle
|
||||
self.obj.recompute()
|
||||
self.updateCircleTrackers(obj)
|
||||
elif self.editing == 3:
|
||||
self.obj.Radius = delta.Length
|
||||
self.obj.recompute()
|
||||
self.updateCircleTrackers(obj)
|
||||
|
||||
elif self.arc_edit_mode == 1:
|
||||
else:
|
||||
# obj is an arc
|
||||
if self.alt_edit_mode == 0:
|
||||
# edit arc by 3 points
|
||||
import Part
|
||||
if self.editing == 0:#center point
|
||||
if nodeIndex == 0:
|
||||
#center point
|
||||
import DraftVecUtils
|
||||
p1 = self.invpl.multVec(self.obj.Shape.Vertexes[0].Point)
|
||||
p2 = self.invpl.multVec(self.obj.Shape.Vertexes[1].Point)
|
||||
p0 = DraftVecUtils.project(delta,self.invpl.multVec(self.getArcMid(self.obj)))
|
||||
self.obj.Radius = p1.sub(p0).Length
|
||||
self.obj.FirstAngle = -math.degrees(DraftVecUtils.angle(p1.sub(p0)))
|
||||
self.obj.LastAngle = -math.degrees(DraftVecUtils.angle(p2.sub(p0)))
|
||||
self.obj.Placement.Base = self.pl.multVec(p0)
|
||||
self.setPlacement(self.obj)
|
||||
self.updateCircleTrackers(obj)
|
||||
return
|
||||
p1 = self.getArcStart(obj)
|
||||
p2 = self.getArcEnd(obj)
|
||||
p0 = DraftVecUtils.project(delta,self.getArcMid(obj))
|
||||
obj.Radius = p1.sub(p0).Length
|
||||
obj.FirstAngle = -math.degrees(DraftVecUtils.angle(p1.sub(p0)))
|
||||
obj.LastAngle = -math.degrees(DraftVecUtils.angle(p2.sub(p0)))
|
||||
obj.Placement.Base = obj.Placement.multVec(p0)
|
||||
self.setPlacement(obj)
|
||||
|
||||
else:
|
||||
if self.editing == 1:#first point
|
||||
if nodeIndex == 1:#first point
|
||||
p1=v
|
||||
p2=self.getArcMid(self.obj)
|
||||
p3=self.obj.Shape.Vertexes[1].Point
|
||||
elif self.editing == 3:#midpoint
|
||||
p1=self.obj.Shape.Vertexes[0].Point
|
||||
p2=self.getArcMid(obj,global_placement=True)
|
||||
p3=self.getArcEnd(obj,global_placement=True)
|
||||
elif nodeIndex == 3:#midpoint
|
||||
p1=self.getArcStart(obj,global_placement=True)
|
||||
p2=v
|
||||
p3=self.obj.Shape.Vertexes[1].Point
|
||||
elif self.editing == 2:#second point
|
||||
p1=self.obj.Shape.Vertexes[0].Point
|
||||
p2=self.getArcMid(self.obj)
|
||||
p3=self.getArcEnd(obj,global_placement=True)
|
||||
elif nodeIndex == 2:#second point
|
||||
p1=self.getArcStart(obj,global_placement=True)
|
||||
p2=self.getArcMid(obj,global_placement=True)
|
||||
p3=v
|
||||
arc=Part.ArcOfCircle(p1,p2,p3)
|
||||
e = arc.toShape()
|
||||
self.obj.Placement.Base=arc.Center
|
||||
self.setPlacement(self.obj)
|
||||
self.obj.Radius = arc.Radius
|
||||
obj.Placement.Base = obj.Placement.multVec(obj.getGlobalPlacement().inverse().multVec(arc.Location))
|
||||
self.setPlacement(obj)
|
||||
obj.Radius = arc.Radius
|
||||
delta = self.invpl.multVec(p1)
|
||||
dangleF = math.degrees(math.atan2(delta[1],delta[0]))
|
||||
obj.FirstAngle = math.degrees(math.atan2(delta[1],delta[0]))
|
||||
delta = self.invpl.multVec(p3)
|
||||
dangleL = math.degrees(math.atan2(delta[1],delta[0]))
|
||||
self.obj.FirstAngle = dangleF
|
||||
self.obj.LastAngle = dangleL
|
||||
self.updateCircleTrackers(obj)
|
||||
obj.LastAngle = math.degrees(math.atan2(delta[1],delta[0]))
|
||||
|
||||
def getArcStart(self, obj):#Returns object midpoint
|
||||
elif self.alt_edit_mode == 1:
|
||||
# edit arc by center radius FirstAngle LastAngle
|
||||
if nodeIndex == 0:
|
||||
obj.Placement.Base = local_v
|
||||
self.setPlacement(obj)
|
||||
else:
|
||||
dangle = math.degrees(math.atan2(delta[1],delta[0]))
|
||||
if nodeIndex == 1:
|
||||
obj.FirstAngle = dangle
|
||||
elif nodeIndex == 2:
|
||||
obj.LastAngle = dangle
|
||||
elif nodeIndex == 3:
|
||||
obj.Radius = delta.Length
|
||||
|
||||
obj.recompute()
|
||||
self.updateCircleTrackers(obj)
|
||||
|
||||
|
||||
def getArcStart(self, obj, global_placement=False):#Returns object midpoint
|
||||
if Draft.getType(obj) == "Circle":
|
||||
return self.pointOnCircle(obj, obj.FirstAngle)
|
||||
return self.pointOnCircle(obj, obj.FirstAngle, global_placement)
|
||||
|
||||
def getArcEnd(self, obj):#Returns object midpoint
|
||||
def getArcEnd(self, obj, global_placement=False):#Returns object midpoint
|
||||
if Draft.getType(obj) == "Circle":
|
||||
return self.pointOnCircle(obj, obj.LastAngle)
|
||||
return self.pointOnCircle(obj, obj.LastAngle, global_placement)
|
||||
|
||||
def getArcMid(self, obj):#Returns object midpoint
|
||||
def getArcMid(self, obj, global_placement=False):#Returns object midpoint
|
||||
if Draft.getType(obj) == "Circle":
|
||||
if obj.LastAngle > obj.FirstAngle:
|
||||
midAngle = obj.FirstAngle + (obj.LastAngle - obj.FirstAngle) / 2.0
|
||||
else:
|
||||
midAngle = obj.FirstAngle + (obj.LastAngle - obj.FirstAngle) / 2.0
|
||||
midAngle += App.Units.Quantity(180,App.Units.Angle)
|
||||
return self.pointOnCircle(obj, midAngle)
|
||||
return self.pointOnCircle(obj, midAngle, global_placement)
|
||||
|
||||
def pointOnCircle(self, obj, angle):
|
||||
def pointOnCircle(self, obj, angle, global_placement=False):
|
||||
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(App.Vector(px, py, 0.0))
|
||||
p = App.Vector(px, py, 0.0)
|
||||
if global_placement == True:
|
||||
p = obj.getGlobalPlacement().multVec(p)
|
||||
return p
|
||||
return None
|
||||
|
||||
@@ -1529,11 +1537,11 @@ class Edit():
|
||||
# SKETCH: just if it's composed by a single segment-------------------------
|
||||
|
||||
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:
|
||||
editpoints.append(obj.getGlobalPlacement().multVec(obj.getPoint(0,1)))
|
||||
@@ -1547,12 +1555,12 @@ class Edit():
|
||||
return None
|
||||
|
||||
def updateSketch(self, obj, nodeIndex, v):
|
||||
'''
|
||||
"""
|
||||
(single segment sketch object, node index as Int, App.Vector)
|
||||
move a single line sketch (WallTrace) vertex according to a given App.Vector
|
||||
0 : startpoint
|
||||
1 : endpoint
|
||||
'''
|
||||
"""
|
||||
if nodeIndex == 0:
|
||||
obj.movePoint(0,1,obj.getGlobalPlacement().inverse().multVec(v))
|
||||
elif nodeIndex == 1:
|
||||
@@ -1563,11 +1571,11 @@ class Edit():
|
||||
#WALL-----------------------------------------------------------------------
|
||||
|
||||
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(App.Vector(0,0,obj.Height)))
|
||||
@@ -1584,9 +1592,9 @@ class Edit():
|
||||
|
||||
|
||||
def updateWallTrackers(self, obj):
|
||||
'''
|
||||
"""
|
||||
update self.trackers[obj.Name][0] to match with given object
|
||||
'''
|
||||
"""
|
||||
pass
|
||||
|
||||
def updateWall(self, obj, nodeIndex, v):
|
||||
@@ -1815,7 +1823,7 @@ class Edit():
|
||||
self.addPoint(self.event)
|
||||
# arc tools
|
||||
elif action_label in ["move arc","set radius", "set first angle", "set last angle"]:
|
||||
self.arc_edit_mode = 0
|
||||
self.alt_edit_mode = 1
|
||||
self.startEditing(self.event)
|
||||
elif action_label == "invert arc":
|
||||
pos = self.event.getPosition()
|
||||
|
||||
Reference in New Issue
Block a user