Draft: Added snap recenter functionality (#19728)
* Allow to align the working plane on selected edge + face of a same object, which aligns the plane with the face, but positions it on the edge (the WP is positioned on the edge's first vertex, the WP's X axis is aligned with the edge, and the face's center point provides the third point to define the plane) * Added a "Recenter" in-command shortcut. This moves the WP to be centered on the current snap position (the WorkingPlane snap button is taken into account, so one can only move the WP in the same plane or not).
This commit is contained in:
@@ -1155,6 +1155,10 @@ class DraftToolBar:
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.addHoldPoint()
|
||||
spec = True
|
||||
elif txt == _get_incmd_shortcut("Recenter"):
|
||||
if hasattr(FreeCADGui,"Snapper"):
|
||||
FreeCADGui.Snapper.recenter_workingplane()
|
||||
spec = True
|
||||
elif txt == _get_incmd_shortcut("Snap"):
|
||||
self.togglesnap()
|
||||
spec = True
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
<file>icons/Draft_Snap_Ortho.svg</file>
|
||||
<file>icons/Draft_Snap_Parallel.svg</file>
|
||||
<file>icons/Draft_Snap_Perpendicular.svg</file>
|
||||
<file>icons/Draft_Snap_Recenter.svg</file>
|
||||
<file>icons/Draft_Snap_Special.svg</file>
|
||||
<file>icons/Draft_Snap_WorkingPlane.svg</file>
|
||||
<file>icons/Draft_Split.svg</file>
|
||||
|
||||
224
src/Mod/Draft/Resources/icons/Draft_Snap_Recenter.svg
Normal file
224
src/Mod/Draft/Resources/icons/Draft_Snap_Recenter.svg
Normal file
@@ -0,0 +1,224 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="svg2726"
|
||||
height="64px"
|
||||
width="64px"
|
||||
sodipodi:docname="Draft_Snap_Recenter.svg"
|
||||
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview27"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="true"
|
||||
inkscape:zoom="8.5278495"
|
||||
inkscape:cx="48.136403"
|
||||
inkscape:cy="33.888966"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="32"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2726">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid904" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2728">
|
||||
<linearGradient
|
||||
id="linearGradient3773">
|
||||
<stop
|
||||
id="stop3775"
|
||||
offset="0"
|
||||
style="stop-color:#06989a;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop3777"
|
||||
offset="1"
|
||||
style="stop-color:#34e0e2;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3765">
|
||||
<stop
|
||||
id="stop3767"
|
||||
offset="0"
|
||||
style="stop-color:#06989a;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop3769"
|
||||
offset="1"
|
||||
style="stop-color:#34e0e2;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3144">
|
||||
<stop
|
||||
id="stop3146"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3148"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0;" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
r="34.345188"
|
||||
fy="672.79736"
|
||||
fx="225.26402"
|
||||
cy="672.79736"
|
||||
cx="225.26402"
|
||||
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3850"
|
||||
xlink:href="#linearGradient3144" />
|
||||
<radialGradient
|
||||
r="34.345188"
|
||||
fy="672.79736"
|
||||
fx="225.26402"
|
||||
cy="672.79736"
|
||||
cx="225.26402"
|
||||
gradientTransform="matrix(1,0,0,0.6985294,0,202.82863)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3850-4"
|
||||
xlink:href="#linearGradient3144-1" />
|
||||
<linearGradient
|
||||
id="linearGradient3144-1">
|
||||
<stop
|
||||
id="stop3146-9"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3148-8"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="457.10004"
|
||||
x2="133.47093"
|
||||
y1="802.50574"
|
||||
x1="207.48643"
|
||||
id="linearGradient3771"
|
||||
xlink:href="#linearGradient3765"
|
||||
gradientTransform="matrix(0.16670802,0,0,0.16316094,5.836926,-67.568816)" />
|
||||
<linearGradient
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="35.090908"
|
||||
x2="22.545454"
|
||||
y1="49.272728"
|
||||
x1="25.81818"
|
||||
id="linearGradient3779"
|
||||
xlink:href="#linearGradient3773"
|
||||
gradientTransform="matrix(0.91666668,0,0,0.91666668,13.333334,-12.166667)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3765"
|
||||
id="linearGradient970"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.16670802,0,0,0.16316094,5.836926,-67.568816)"
|
||||
x1="207.48643"
|
||||
y1="802.50574"
|
||||
x2="133.47093"
|
||||
y2="457.10004" />
|
||||
</defs>
|
||||
<g
|
||||
id="g344-7"
|
||||
transform="matrix(0.78805516,0,0,0.78805516,-0.42818596,14.42218)"
|
||||
style="opacity:0.57483108">
|
||||
<rect
|
||||
ry="4.3329797"
|
||||
y="1.9802104"
|
||||
x="2.3813963"
|
||||
height="58.36945"
|
||||
width="59.638393"
|
||||
id="rect3857-5"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient970);fill-opacity:1;fill-rule:nonzero;stroke:#042a2a;stroke-width:2.58167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
id="rect3857-3-3"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#34e0e2;stroke-width:2.53356;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 6.8880787,4.5357235 c -1.0783427,0 -1.9481926,0.9160312 -1.9481926,2.0516245 v 49.196853 c 0,1.135593 0.8698499,2.051624 1.9481926,2.051624 H 57.518586 c 1.078342,0 1.945691,-0.916031 1.945691,-2.051624 V 6.587348 c 0,-1.1355933 -0.867349,-2.0516245 -1.945691,-2.0516245 z" />
|
||||
</g>
|
||||
<g
|
||||
id="g344"
|
||||
transform="matrix(0.78805516,0,0,0.78805516,13.140579,2.42389)">
|
||||
<rect
|
||||
ry="4.3329797"
|
||||
y="1.9802104"
|
||||
x="2.3813963"
|
||||
height="58.36945"
|
||||
width="59.638393"
|
||||
id="rect3857"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient3771);fill-opacity:1;fill-rule:nonzero;stroke:#042a2a;stroke-width:2.58167;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
id="rect3857-3"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#34e0e2;stroke-width:2.53356;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
d="m 6.8880787,4.5357235 c -1.0783427,0 -1.9481926,0.9160312 -1.9481926,2.0516245 v 49.196853 c 0,1.135593 0.8698499,2.051624 1.9481926,2.051624 H 57.518586 c 1.078342,0 1.945691,-0.916031 1.945691,-2.051624 V 6.587348 c 0,-1.1355933 -0.867349,-2.0516245 -1.945691,-2.0516245 z" />
|
||||
</g>
|
||||
<g
|
||||
id="g348"
|
||||
transform="translate(2)">
|
||||
<path
|
||||
d="m 44.999999,26.000001 a 8.9999996,9.0000004 0 0 1 -9,9 A 8.9999996,9.0000004 0 0 1 27,26.000001 8.9999996,9.0000004 0 0 1 35.999999,17 a 8.9999996,9.0000004 0 0 1 9,9.000001 z"
|
||||
id="path4644"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#34e0e2;fill-opacity:1;fill-rule:nonzero;stroke:#042a2a;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
d="M 43,26.000001 A 7,7 0 0 1 36,33 7,7 0 0 1 29,26.000001 7,7 0 0 1 36,19 a 7,7 0 0 1 7,7.000001 z"
|
||||
id="path4644-6"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient3779);fill-opacity:1;stroke:#34e0e2;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
</g>
|
||||
<metadata
|
||||
id="metadata6669">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<cc:license
|
||||
rdf:resource="https://www.gnu.org/copyleft/lesser.html" />
|
||||
<dc:date>Fri Mar 7 15:58:51 2014 -0300</dc:date>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[Yorik van Havre]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_Snap_WorkingPlane.svg</dc:identifier>
|
||||
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
<dc:description>Square with small circe in lower left corner</dc:description>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>plane</rdf:li>
|
||||
<rdf:li>square</rdf:li>
|
||||
<rdf:li>circle</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.8 KiB |
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>456</width>
|
||||
<height>338</height>
|
||||
<width>513</width>
|
||||
<height>516</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -41,7 +41,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -89,7 +89,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -137,7 +137,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -185,7 +185,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -217,7 +217,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -249,7 +249,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -281,7 +281,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -313,7 +313,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -345,7 +345,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -377,7 +377,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -409,7 +409,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -441,7 +441,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -473,7 +473,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -505,7 +505,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -537,7 +537,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -569,7 +569,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -601,7 +601,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -633,7 +633,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -665,7 +665,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -697,7 +697,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -729,7 +729,7 @@
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled" stdset="0">
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
@@ -740,6 +740,38 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_inCommandShortcutRecenter">
|
||||
<property name="text">
|
||||
<string>Recenter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="Gui::PrefLineEdit" name="lineEdit_inCommandShortcutRecenter">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>25</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>D</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="clearButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>inCommandShortcutRecenter</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Draft</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -814,6 +846,12 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
@@ -241,6 +241,40 @@ class PlaneBase:
|
||||
self.position = pos + (self.axis * offset)
|
||||
return True
|
||||
|
||||
def align_to_face_and_edge(self, face, edge, offset=0):
|
||||
"""Align the WP to a face and an edge.
|
||||
|
||||
The face must be planar.
|
||||
|
||||
The WP will lie on the face, but its `position` will be the
|
||||
first vertex of the edge, and its `u` vector will be aligned
|
||||
with the edge.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
face: Part.Face
|
||||
Face.
|
||||
edge: Part.Edge
|
||||
Edge, need not be an edge of the face.
|
||||
offset: float, optional
|
||||
Defaults to zero.
|
||||
Offset along the WP `axis`.
|
||||
|
||||
Returns
|
||||
-------
|
||||
`True`/`False`
|
||||
`True` if successful.
|
||||
"""
|
||||
if face.Surface.isPlanar() is False:
|
||||
return False
|
||||
axis = face.normalAt(0,0)
|
||||
point = edge.Vertexes[0].Point
|
||||
upvec = edge.Vertexes[-1].Point.sub(point)
|
||||
return self.align_to_point_and_axis(point, axis, offset, upvec)
|
||||
#vertex = Part.Vertex(face.CenterOfMass)
|
||||
#return self.align_to_edges_vertexes([edge, vertex], offset)
|
||||
|
||||
def align_to_face(self, shape, offset=0):
|
||||
"""Align the WP to a face with an optional offset.
|
||||
|
||||
@@ -1256,11 +1290,14 @@ class PlaneGui(PlaneBase):
|
||||
objs.append(Part.getShape(sel.Object, sub, needSubElement=True, retType=1))
|
||||
|
||||
if len(objs) != 1:
|
||||
ret = False
|
||||
if all([obj[0].isNull() is False and obj[0].ShapeType in ["Edge", "Vertex"] for obj in objs]):
|
||||
ret = self.align_to_edges_vertexes([obj[0] for obj in objs], offset, _hist_add)
|
||||
else:
|
||||
ret = False
|
||||
|
||||
elif all([obj[0].isNull() is False and obj[0].ShapeType in ["Edge", "Face"] for obj in objs]):
|
||||
edges = [obj[0] for obj in objs if obj[0].ShapeType == "Edge"]
|
||||
faces = [obj[0] for obj in objs if obj[0].ShapeType == "Face"]
|
||||
if faces and edges:
|
||||
ret = self.align_to_face_and_edge(faces[0], edges[0], offset, _hist_add)
|
||||
if ret is False:
|
||||
_wrn(translate("draft", "Selected shapes do not define a plane"))
|
||||
return ret
|
||||
@@ -1329,6 +1366,13 @@ class PlaneGui(PlaneBase):
|
||||
self._handle_custom(_hist_add)
|
||||
return True
|
||||
|
||||
def align_to_face_and_edge(self, face, edge, offset=0, _hist_add=True):
|
||||
"""See PlaneBase.align_to_face."""
|
||||
if super().align_to_face_and_edge(face, edge, offset) is False:
|
||||
return False
|
||||
self._handle_custom(_hist_add)
|
||||
return True
|
||||
|
||||
def align_to_placement(self, place, offset=0, _hist_add=True):
|
||||
"""See PlaneBase.align_to_placement."""
|
||||
super().align_to_placement(place, offset)
|
||||
|
||||
@@ -49,6 +49,7 @@ import Part
|
||||
import Draft
|
||||
import DraftVecUtils
|
||||
import DraftGeomUtils
|
||||
import WorkingPlane
|
||||
from draftguitools import gui_trackers as trackers
|
||||
from draftutils import gui_utils
|
||||
from draftutils import params
|
||||
@@ -159,7 +160,7 @@ class Snapper:
|
||||
|
||||
|
||||
def _get_wp(self):
|
||||
return App.DraftWorkingPlane
|
||||
return WorkingPlane.get_working_plane()
|
||||
|
||||
|
||||
def init_active_snaps(self):
|
||||
@@ -1649,4 +1650,10 @@ class Snapper:
|
||||
self.holdTracker.on()
|
||||
self.holdPoints.append(self.spoint)
|
||||
|
||||
def recenter_workingplane(self):
|
||||
"""Recenters the working plane on the current snap position"""
|
||||
if self.spoint:
|
||||
self._get_wp().set_to_position(self.toWP(self.spoint))
|
||||
|
||||
|
||||
## @}
|
||||
|
||||
Reference in New Issue
Block a user