Draft: Added stretch tool - fixes #1163

This commit is contained in:
Yorik van Havre
2017-01-13 11:25:25 -02:00
parent d52e71d669
commit 72afcde8db
7 changed files with 445 additions and 6 deletions

View File

@@ -56,7 +56,7 @@ class ArchWorkbench(Workbench):
"Draft_Shape2DView","Draft_Draft2Sketch","Draft_Array",
"Draft_Clone"]
self.draftextratools = ["Draft_WireToBSpline","Draft_AddPoint","Draft_DelPoint","Draft_ShapeString",
"Draft_PathArray","Draft_Mirror"]
"Draft_PathArray","Draft_Mirror","Draft_Stretch"]
self.draftcontexttools = ["Draft_ApplyStyle","Draft_ToggleDisplayMode","Draft_AddToGroup",
"Draft_SelectGroup","Draft_SelectPlane",
"Draft_ShowSnapBar","Draft_ToggleGrid","Draft_UndoLine",

View File

@@ -96,10 +96,14 @@ def isNull(something):
def isPtOnEdge(pt,edge) :
'''isPtOnEdge(Vector,edge): Tests if a point is on an edge'''
v = Part.Vertex(pt)
d = v.distToShape(edge)
if d:
if round(d[0],precision()) == 0:
return True
try:
d = v.distToShape(edge)
except:
return False
else:
if d:
if round(d[0],precision()) == 0:
return True
return False
def hasCurves(shape):

View File

@@ -2670,6 +2670,149 @@ class Offset(Modifier):
self.finish()
class Stretch(Modifier):
"The Draft_Stretch FreeCAD command definition"
def GetResources(self):
return {'Pixmap' : 'Draft_Stretch',
'Accel' : "S, H",
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Stretch", "Stretch"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Draft_Stretch", "Stretches the selected objects")}
def Activated(self):
Modifier.Activated(self,"Stretch")
if self.ui:
if not FreeCADGui.Selection.getSelection():
self.ui.selectUi()
msg(translate("draft", "Select an object to stretch\n"))
self.call = self.view.addEventCallback("SoEvent",selectObject)
else:
self.proceed()
def proceed(self):
if self.call:
self.view.removeEventCallback("SoEvent",self.call)
self.sel = FreeCADGui.Selection.getSelection()
if self.ui and self.sel:
self.step = 1
self.refpoint = None
self.ui.pointUi("Stretch")
self.ui.extUi()
self.call = self.view.addEventCallback("SoEvent",self.action)
self.rectracker = rectangleTracker()
self.nodetracker = []
self.displacement = None
msg(translate("draft", "Pick first point of selection rectangle:\n"))
def action(self,arg):
"scene event handler"
if arg["Type"] == "SoKeyboardEvent":
if arg["Key"] == "ESCAPE":
self.finish()
elif arg["Type"] == "SoLocation2Event": #mouse movement detection
point,ctrlPoint,info = getPoint(self,arg) #,mobile=True) #,noTracker=(self.step < 3))
if self.step == 2:
self.rectracker.update(point)
elif arg["Type"] == "SoMouseButtonEvent":
if (arg["State"] == "DOWN") and (arg["Button"] == "BUTTON1"):
if (arg["Position"] == self.pos):
# clicked twice on the same point
self.finish()
else:
point,ctrlPoint,info = getPoint(self,arg) #,mobile=True) #,noTracker=(self.step < 3))
self.addPoint(point)
def addPoint(self,point):
if self.step == 1:
# first rctangle point
msg(translate("draft", "Pick opposite point of selection rectangle:\n"))
self.ui.setRelative()
self.rectracker.setorigin(point)
self.rectracker.on()
if self.planetrack:
self.planetrack.set(point)
self.step = 2
elif self.step == 2:
# second rectangle point
msg(translate("draft", "Pick start point of displacement:\n"))
self.rectracker.off()
nodes = []
self.ops = []
for o in self.sel:
tp = Draft.getType(o)
if tp in ["Wire","BSpline","BezCurve"]:
np = []
iso = False
for p in o.Points:
p = o.Placement.multVec(p)
isi = self.rectracker.isInside(p)
np.append(isi)
if isi:
iso = True
nodes.append(p)
if iso:
self.ops.append([o,np])
elif tp == "Circle":
self.ops.append([o])
nodes.append(o.Placement.Base)
else:
print "Draft Stretch: Skipping unsupported object: ",o.Label
for n in nodes:
nt = editTracker(n)
nt.on()
self.nodetracker.append(nt)
self.step = 3
elif self.step == 3:
# first point of displacement line
msg(translate("draft", "Pick end point of displacement:\n"))
self.displacement = point
self.node = [point]
self.step = 4
elif self.step == 4:
self.displacement = point.sub(self.displacement)
self.doStretch()
if self.point:
self.ui.redraw()
def numericInput(self,numx,numy,numz):
"this function gets called by the toolbar when valid x, y, and z have been entered there"
point = Vector(numx,numy,numz)
self.addPoint(point)
def finish(self,closed=False):
if self.rectracker:
self.rectracker.finalize()
if self.nodetracker:
for n in self.nodetracker:
n.finalize()
Modifier.finish(self)
def doStretch(self):
"does the actual stretching"
commitops = []
if self.displacement:
if self.displacement.Length > 0:
for ops in self.ops:
tp = Draft.getType(ops[0])
if tp in ["Wire","BSpline","BezCurve"]:
pts = []
for i in range(len(ops[1])):
if ops[1][i] == False:
pts.append(ops[0].Points[i])
else:
pts.append(ops[0].Points[i].add(self.displacement))
pts = str(pts).replace("Vector","FreeCAD.Vector")
commitops.append("FreeCAD.ActiveDocument."+ops[0].Name+".Points="+pts)
elif tp == "Circle":
commitops.append("FreeCAD.ActiveDocument."+ops[0].Name+".Placement.Base=FreeCAD."+str(ops[0].Placement.Base.add(self.displacement)))
if commitops:
commitops.append("FreeCAD.ActiveDocument.recompute()")
FreeCADGui.addModule("Draft")
self.commit(translate("draft","Stretch"),commitops)
self.finish()
class Upgrade(Modifier):
'''The Draft_Upgrade FreeCAD command definition.'''
@@ -4923,6 +5066,7 @@ FreeCADGui.addCommand('Draft_Heal',Heal())
FreeCADGui.addCommand('Draft_VisGroup',VisGroup())
FreeCADGui.addCommand('Draft_Mirror',Mirror())
FreeCADGui.addCommand('Draft_Slope',Draft_Slope())
FreeCADGui.addCommand('Draft_Stretch',Stretch())
# context commands
FreeCADGui.addCommand('Draft_FinishLine',FinishLine())

View File

@@ -245,6 +245,20 @@ class rectangleTracker(Tracker):
def getNormal(self):
"returns the normal of the rectangle"
return (self.u.cross(self.v)).normalize()
def isInside(self,point):
"returns True if the given point is inside the rectangle"
vp = point.sub(self.p1())
uv = self.p2().sub(self.p1())
vv = self.p4().sub(self.p1())
uvp = DraftVecUtils.project(vp,uv)
vvp = DraftVecUtils.project(vp,vv)
if uvp.getAngle(uv) < 1:
if vvp.getAngle(vv) < 1:
if uvp.Length <= uv.Length:
if vvp.Length <= vv.Length:
return True
return False
class dimTracker(Tracker):
"A Dimension tracker, used by the dimension tool"

View File

@@ -76,7 +76,7 @@ class DraftWorkbench (Workbench):
"Draft_Trimex", "Draft_Upgrade", "Draft_Downgrade", "Draft_Scale",
"Draft_Edit","Draft_WireToBSpline","Draft_AddPoint",
"Draft_DelPoint","Draft_Shape2DView","Draft_Draft2Sketch","Draft_Array",
"Draft_PathArray","Draft_Clone","Draft_Drawing","Draft_Mirror"]
"Draft_PathArray","Draft_Clone","Draft_Drawing","Draft_Mirror","Draft_Stretch"]
self.treecmdList = ["Draft_ApplyStyle","Draft_ToggleDisplayMode","Draft_AddToGroup",
"Draft_SelectGroup","Draft_SelectPlane",
"Draft_ShowSnapBar","Draft_ToggleGrid"]

View File

@@ -71,6 +71,7 @@
<file>icons/Draft_Grid.svg</file>
<file>icons/Draft_Slope.svg</file>
<file>icons/DraftWorkbench.svg</file>
<file>icons/Draft_Stretch.svg</file>
<file>patterns/concrete.svg</file>
<file>patterns/cross.svg</file>
<file>patterns/line.svg</file>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB