Draft: added workingplane snap mode - fixes #1461
This commit is contained in:
parent
b58d1caea7
commit
be33ef6f4c
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
135
src/Mod/Draft/Resources/icons/Snap_WorkingPlane.svg
Normal file
135
src/Mod/Draft/Resources/icons/Snap_WorkingPlane.svg
Normal 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 |
Loading…
Reference in New Issue
Block a user