Draft: added workingplane snap mode - fixes #1461

This commit is contained in:
Yorik van Havre 2014-03-07 15:58:51 -03:00
parent b58d1caea7
commit be33ef6f4c
7 changed files with 202 additions and 42 deletions

View File

@ -99,7 +99,7 @@ class ArchWorkbench(Workbench):
'Draft_Snap_Grid','Draft_Snap_Intersection','Draft_Snap_Parallel',
'Draft_Snap_Endpoint','Draft_Snap_Angle','Draft_Snap_Center',
'Draft_Snap_Extension','Draft_Snap_Near','Draft_Snap_Ortho',
'Draft_Snap_Dimensions']
'Draft_Snap_Dimensions','Draft_Snap_WorkingPlane']
self.appendToolbar(translate("arch","Arch tools"),self.archtools)
self.appendToolbar(translate("arch","Draft tools"),self.drafttools)

View File

@ -289,7 +289,7 @@ class Snapper:
snaps.extend(self.snapToElines(edge,eline))
else:
b = obj.Placement.Base
snaps.append([b,'endpoint',b])
snaps.append([b,'endpoint',self.toWP(b)])
elif obj.isDerivedFrom("Part::Feature"):
if Draft.getType(obj) == "Polygon":
@ -327,10 +327,10 @@ class Snapper:
# for dimensions we snap to their 2 points:
if obj.ViewObject:
if hasattr(obj.ViewObject.Proxy,"p2") and hasattr(obj.ViewObject.Proxy,"p3"):
snaps.append([obj.ViewObject.Proxy.p2,'endpoint',obj.ViewObject.Proxy.p2])
snaps.append([obj.ViewObject.Proxy.p3,'endpoint',obj.ViewObject.Proxy.p3])
snaps.append([obj.ViewObject.Proxy.p2,'endpoint',self.toWP(obj.ViewObject.Proxy.p2)])
snaps.append([obj.ViewObject.Proxy.p3,'endpoint',self.toWP(obj.ViewObject.Proxy.p3)])
#for pt in [obj.Start,obj.End,obj.Dimline]:
# snaps.append([pt,'endpoint',pt])
# snaps.append([pt,'endpoint',self.toWP(pt)])
elif Draft.getType(obj) == "Mesh":
# for meshes we only snap to vertices
@ -396,6 +396,13 @@ class Snapper:
# return the final point
return fp
def toWP(self,point):
"projects the given point on the working plane, if needed"
if self.isEnabled("WorkingPlane"):
if hasattr(FreeCAD,"DraftWorkingPlane"):
return FreeCAD.DraftWorkingPlane.projectPoint(point)
return point
def getApparentPoint(self,x,y):
"returns a 3D point, projected on the current working plane"
view = Draft.get3DView()
@ -594,16 +601,16 @@ class Snapper:
if self.isEnabled("endpoint"):
if hasattr(shape,"Vertexes"):
for v in shape.Vertexes:
snaps.append([v.Point,'endpoint',v.Point])
snaps.append([v.Point,'endpoint',self.toWP(v.Point)])
elif hasattr(shape,"Point"):
snaps.append([shape.Point,'endpoint',shape.Point])
snaps.append([shape.Point,'endpoint',self.toWP(shape.Point)])
elif hasattr(shape,"Points"):
if len(shape.Points) and hasattr(shape.Points[0],"Vector"):
for v in shape.Points:
snaps.append([v.Vector,'endpoint',v.Vector])
snaps.append([v.Vector,'endpoint',self.toWP(v.Vector)])
else:
for v in shape.Points:
snaps.append([v,'endpoint',v])
snaps.append([v,'endpoint',self.toWP(v)])
return snaps
def snapToMidpoint(self,shape):
@ -613,7 +620,7 @@ class Snapper:
if isinstance(shape,Part.Edge):
mp = DraftGeomUtils.findMidpoint(shape)
if mp:
snaps.append([mp,'midpoint',mp])
snaps.append([mp,'midpoint',self.toWP(mp)])
return snaps
def snapToPerpendicular(self,shape,last):
@ -636,7 +643,7 @@ class Snapper:
return snaps
else:
return snaps
snaps.append([np,'perpendicular',np])
snaps.append([np,'perpendicular',self.toWP(np)])
return snaps
def snapToOrtho(self,shape,last,constrain):
@ -653,7 +660,7 @@ class Snapper:
pt = DraftGeomUtils.findIntersection(tmpEdge,shape,True,True)
if pt:
for p in pt:
snaps.append([p,'ortho',p])
snaps.append([p,'ortho',self.toWP(p)])
return snaps
def snapToExtOrtho(self,last,constrain,eline):
@ -696,7 +703,7 @@ class Snapper:
pts = DraftGeomUtils.findIntersection(e1,e2,True,True)
if pts:
for p in pts:
snaps.append([p,'intersection',p])
snaps.append([p,'intersection',self.toWP(p)])
return snaps
@ -709,7 +716,7 @@ class Snapper:
for i in [0,30,45,60,90,120,135,150,180,210,225,240,270,300,315,330]:
ang = math.radians(i)
cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
snaps.append([cur,'angle',cur])
snaps.append([cur,'angle',self.toWP(cur)])
return snaps
def snapToCenter(self,shape):
@ -721,7 +728,7 @@ class Snapper:
for i in [15,37.5,52.5,75,105,127.5,142.5,165,195,217.5,232.5,255,285,307.5,322.5,345]:
ang = math.radians(i)
cur = Vector(math.sin(ang)*rad+pos.x,math.cos(ang)*rad+pos.y,pos.z)
snaps.append([cur,'center',pos])
snaps.append([cur,'center',self.toWP(pos)])
return snaps
def snapToIntersection(self,shape):
@ -739,7 +746,7 @@ class Snapper:
pt = DraftGeomUtils.findIntersection(e,shape)
if pt:
for p in pt:
snaps.append([p,'intersection',p])
snaps.append([p,'intersection',self.toWP(p)])
return snaps
def snapToPolygon(self,obj):
@ -751,8 +758,8 @@ class Snapper:
p2 = edge.Vertexes[-1].Point
v1 = p1.add((p2-p1).scale(.25,.25,.25))
v2 = p1.add((p2-p1).scale(.75,.75,.75))
snaps.append([v1,'center',c])
snaps.append([v2,'center',c])
snaps.append([v1,'center',self.toWP(c)])
snaps.append([v2,'center',self.toWP(c)])
return snaps
def snapToVertex(self,info,active=False):
@ -1068,22 +1075,24 @@ class Snapper:
self.toolbar.addWidget(b)
self.toolbarButtons.append(b)
QtCore.QObject.connect(b,QtCore.SIGNAL("toggled(bool)"),self.saveSnapModes)
# adding dimensions button
self.dimbutton = QtGui.QPushButton(None)
self.dimbutton.setIcon(QtGui.QIcon(":/icons/Snap_Dimensions.svg"))
self.dimbutton.setIconSize(QtCore.QSize(16, 16))
self.dimbutton.setMaximumSize(QtCore.QSize(26,26))
self.dimbutton.setToolTip(c)
self.dimbutton.setObjectName("SnapButtonDimensions")
self.dimbutton.setCheckable(True)
self.dimbutton.setChecked(True)
self.toolbar.addWidget(self.dimbutton)
QtCore.QObject.connect(self.dimbutton,QtCore.SIGNAL("toggled(bool)"),self.saveSnapModes)
# adding non-snap button
for n in ["Dimensions","WorkingPlane"]:
b = QtGui.QPushButton(None)
b.setIcon(QtGui.QIcon(":/icons/Snap_"+n+".svg"))
b.setIconSize(QtCore.QSize(16, 16))
b.setMaximumSize(QtCore.QSize(26,26))
b.setToolTip(c)
b.setObjectName("SnapButton"+n)
b.setCheckable(True)
b.setChecked(True)
self.toolbar.addWidget(b)
QtCore.QObject.connect(b,QtCore.SIGNAL("toggled(bool)"),self.saveSnapModes)
self.toolbarButtons.append(b)
# restoring states
t = Draft.getParam("snapModes","1111111111011")
t = Draft.getParam("snapModes","11111111110111")
if t:
c = 0
for b in [self.masterbutton]+self.toolbarButtons+[self.dimbutton]:
for b in [self.masterbutton]+self.toolbarButtons:
if len(t) > c:
b.setChecked(bool(int(t[c])))
c += 1
@ -1093,7 +1102,7 @@ class Snapper:
def saveSnapModes(self):
"saves the snap modes for next sessions"
t = ''
for b in [self.masterbutton]+self.toolbarButtons+[self.dimbutton]:
for b in [self.masterbutton]+self.toolbarButtons:
t += str(int(b.isChecked()))
Draft.setParam("snapModes",t)
@ -1123,7 +1132,7 @@ class Snapper:
def isEnabled(self,but):
"returns true if the given button is turned on"
for b in self.toolbarButtons+[self.dimbutton]:
for b in self.toolbarButtons:
if str(b.objectName()) == "SnapButton" + but:
return (b.isEnabled() and b.isChecked())
return False

View File

@ -4348,11 +4348,25 @@ class Draft_Snap_Dimensions():
def GetResources(self):
return {'Pixmap' : 'Snap_Dimensions',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Snap_Dimensions", "Dimensions"),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_Snap_Ortho", "Shows temporary dimensions when snapping to Arch objects")}
'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_Snap_Dimensions", "Shows temporary dimensions when snapping to Arch objects")}
def Activated(self):
if hasattr(FreeCADGui,"Snapper"):
if hasattr(FreeCADGui.Snapper,"dimbutton"):
FreeCADGui.Snapper.dimbutton.toggle()
if hasattr(FreeCADGui.Snapper,"toolbarButtons"):
for b in FreeCADGui.Snapper.toolbarButtons:
if b.objectName() == "SnapButtonDimensions":
b.toggle()
class Draft_Snap_WorkingPlane():
def GetResources(self):
return {'Pixmap' : 'Snap_WorkingPlane',
'MenuText': QtCore.QT_TRANSLATE_NOOP("Draft_Snap_WorkingPlane", "Working Plane"),
'ToolTip' : QtCore.QT_TRANSLATE_NOOP("Draft_Snap_WorkingPlane", "Restricts the snapped point to the current working plane")}
def Activated(self):
if hasattr(FreeCADGui,"Snapper"):
if hasattr(FreeCADGui.Snapper,"toolbarButtons"):
for b in FreeCADGui.Snapper.toolbarButtons:
if b.objectName() == "SnapButtonWorkingPlane":
b.toggle()
#---------------------------------------------------------------------------
# Adds the icons & commands to the FreeCAD command manager, and sets defaults
@ -4423,6 +4437,7 @@ FreeCADGui.addCommand('Draft_Snap_Extension',Draft_Snap_Extension())
FreeCADGui.addCommand('Draft_Snap_Near',Draft_Snap_Near())
FreeCADGui.addCommand('Draft_Snap_Ortho',Draft_Snap_Ortho())
FreeCADGui.addCommand('Draft_Snap_Dimensions',Draft_Snap_Dimensions())
FreeCADGui.addCommand('Draft_Snap_WorkingPlane',Draft_Snap_WorkingPlane())
# a global place to look for active draft Command
FreeCAD.activeDraftCommand = None

File diff suppressed because one or more lines are too long

View File

@ -124,7 +124,7 @@ class DraftWorkbench (Workbench):
'Draft_Snap_Grid','Draft_Snap_Intersection','Draft_Snap_Parallel',
'Draft_Snap_Endpoint','Draft_Snap_Angle','Draft_Snap_Center',
'Draft_Snap_Extension','Draft_Snap_Near','Draft_Snap_Ortho',
'Draft_Snap_Dimensions']
'Draft_Snap_Dimensions','Draft_Snap_WorkingPlane']
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench","Draft creation tools"),self.cmdList)
self.appendToolbar(QT_TRANSLATE_NOOP("Workbench","Draft modification tools"),self.modList)
self.appendMenu(translate("draft","&Draft"),self.cmdList+self.modList)

View File

@ -58,6 +58,7 @@
<file>icons/Snap_Ortho.svg</file>
<file>icons/Snap_Near.svg</file>
<file>icons/Snap_Dimensions.svg</file>
<file>icons/Snap_WorkingPlane.svg</file>
<file>icons/Draft_Clone.svg</file>
<file>icons/Draft_Heal.svg</file>
<file>icons/Draft_Ellipse.svg</file>

View File

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2726"
sodipodi:version="0.32"
inkscape:version="0.48.4 r9939"
sodipodi:docname="Snap_WorkingPlane.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2728">
<linearGradient
inkscape:collect="always"
id="linearGradient3144">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3146" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3148" />
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2734" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3144"
id="radialGradient3850"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
cx="225.26402"
cy="672.79736"
fx="225.26402"
fy="672.79736"
r="34.345188" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3144-1"
id="radialGradient3850-4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
cx="225.26402"
cy="672.79736"
fx="225.26402"
fy="672.79736"
r="34.345188" />
<linearGradient
inkscape:collect="always"
id="linearGradient3144-1">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop3146-9" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop3148-8" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.5"
inkscape:cx="36.730761"
inkscape:cy="31.703356"
inkscape:current-layer="g4289"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1920"
inkscape:window-height="1053"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata2731">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g4289"
transform="matrix(0.1621282,0,0,0.1621282,6.3605986,-66.108806)">
<rect
style="opacity:1;color:#000000;fill:#00b286;fill-opacity:1;fill-rule:nonzero;stroke:#002e2e;stroke-width:24.67183229000000111;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3857"
width="325.12296"
height="321.95102"
x="-1.9617189"
y="445.66345"
ry="23.899611" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#00b286;fill-opacity:1;fill-rule:nonzero;stroke:#002e2e;stroke-width:3.99999976;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path4644"
sodipodi:cx="24.727272"
sodipodi:cy="41.636364"
sodipodi:rx="7.6363635"
sodipodi:ry="7.6363635"
d="m 32.363636,41.636364 a 7.6363635,7.6363635 0 1 1 -15.272727,0 7.6363635,7.6363635 0 1 1 15.272727,0 z"
transform="matrix(6.1679584,0,0,6.1679584,-45.96059,396.5419)" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB