Merge pull request #336 from sliptonic/feature/MillFacing

Feature/mill facing
This commit is contained in:
Yorik van Havre
2016-11-14 11:54:34 -02:00
committed by GitHub
17 changed files with 2258 additions and 312 deletions

View File

@@ -33,6 +33,7 @@ SET(PathScripts_SRCS
PathScripts/PathProfile.py
PathScripts/PathProfileEdges.py
PathScripts/PathContour.py
PathScripts/PathMillFace.py
PathScripts/PathPocket.py
PathScripts/PathDrilling.py
PathScripts/PathDressup.py

View File

@@ -45,6 +45,7 @@
<file>icons/Path-Profile-Edges.svg</file>
<file>icons/Path-Profile-Face.svg</file>
<file>icons/Path-SelectLoop.svg</file>
<file>icons/Path-Face.svg</file>
<file>translations/Path_de.qm</file>
<file>translations/Path_af.qm</file>
<file>translations/Path_zh-CN.qm</file>
@@ -84,6 +85,7 @@
<file>panels/ToolEdit.ui</file>
<file>panels/DlgJobChooser.ui</file>
<file>panels/ContourEdit.ui</file>
<file>panels/MillFaceEdit.ui</file>
<file>panels/ProfileEdgesEdit.ui</file>
<file>panels/DogboneEdit.ui</file>
<file>panels/DlgSelectPostProcessor.ui</file>

View File

@@ -0,0 +1,926 @@
<?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="svg2816"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="Path-Face.svg">
<defs
id="defs2818">
<linearGradient
id="linearGradient4513">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4515" />
<stop
style="stop-color:#999999;stop-opacity:1;"
offset="1"
id="stop4517" />
</linearGradient>
<linearGradient
id="linearGradient3681">
<stop
id="stop3697"
offset="0"
style="stop-color:#fff110;stop-opacity:1;" />
<stop
style="stop-color:#cf7008;stop-opacity:1;"
offset="1"
id="stop3685" />
</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="perspective2824" />
<inkscape:perspective
id="perspective3622"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3622-9"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3653"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3675"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3697"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3720"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3742"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3764"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3785"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3806"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3806-3"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3835"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3614"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3614-8"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3643"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3643-3"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3672"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3672-5"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3701"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3701-8"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3746"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<pattern
patternTransform="matrix(0.67643728,-0.81829155,2.4578314,1.8844554,-26.450606,18.294947)"
id="pattern5231"
xlink:href="#Strips1_1-4"
inkscape:collect="always" />
<inkscape:perspective
id="perspective5224"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<pattern
inkscape:stockid="Stripes 1:1"
id="Strips1_1-4"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
height="1"
width="2"
patternUnits="userSpaceOnUse"
inkscape:collect="always">
<rect
id="rect4483-4"
height="2"
width="1"
y="-0.5"
x="0"
style="fill:black;stroke:none" />
</pattern>
<inkscape:perspective
id="perspective5224-9"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<pattern
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,39.618381,8.9692804)"
id="pattern5231-4"
xlink:href="#Strips1_1-6"
inkscape:collect="always" />
<inkscape:perspective
id="perspective5224-3"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<pattern
inkscape:stockid="Stripes 1:1"
id="Strips1_1-6"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
height="1"
width="2"
patternUnits="userSpaceOnUse"
inkscape:collect="always">
<rect
id="rect4483-0"
height="2"
width="1"
y="-0.5"
x="0"
style="fill:black;stroke:none" />
</pattern>
<pattern
patternTransform="matrix(0.66513382,-1.0631299,2.4167603,2.4482973,-49.762569,2.9546807)"
id="pattern5296"
xlink:href="#pattern5231-3"
inkscape:collect="always" />
<inkscape:perspective
id="perspective5288"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<pattern
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,-26.336284,10.887197)"
id="pattern5231-3"
xlink:href="#Strips1_1-4-3"
inkscape:collect="always" />
<pattern
inkscape:stockid="Stripes 1:1"
id="Strips1_1-4-3"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
height="1"
width="2"
patternUnits="userSpaceOnUse"
inkscape:collect="always">
<rect
id="rect4483-4-6"
height="2"
width="1"
y="-0.5"
x="0"
style="fill:black;stroke:none" />
</pattern>
<pattern
patternTransform="matrix(0.42844886,-0.62155849,1.5567667,1.431396,27.948414,13.306456)"
id="pattern5330"
xlink:href="#Strips1_1-9"
inkscape:collect="always" />
<inkscape:perspective
id="perspective5323"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<pattern
inkscape:stockid="Stripes 1:1"
id="Strips1_1-9"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
height="1"
width="2"
patternUnits="userSpaceOnUse"
inkscape:collect="always">
<rect
id="rect4483-3"
height="2"
width="1"
y="-0.5"
x="0"
style="fill:black;stroke:none" />
</pattern>
<inkscape:perspective
id="perspective5361"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective5383"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective5411"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3681"
id="linearGradient3687"
x1="37.89756"
y1="41.087898"
x2="4.0605712"
y2="40.168594"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(127.27273,-51.272729)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3681"
id="linearGradient3695"
x1="37.894287"
y1="40.484772"
x2="59.811455"
y2="43.558987"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(127.27273,-51.272729)" />
<linearGradient
id="linearGradient3681-3">
<stop
id="stop3697-3"
offset="0"
style="stop-color:#fff110;stop-opacity:1;" />
<stop
style="stop-color:#cf7008;stop-opacity:1;"
offset="1"
id="stop3685-4" />
</linearGradient>
<linearGradient
y2="43.558987"
x2="59.811455"
y1="40.484772"
x1="37.894287"
gradientTransform="translate(-37.00068,-20.487365)"
gradientUnits="userSpaceOnUse"
id="linearGradient3608"
xlink:href="#linearGradient3681-3"
inkscape:collect="always" />
<linearGradient
id="linearGradient4513-2">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4515-2" />
<stop
style="stop-color:#999999;stop-opacity:1;"
offset="1"
id="stop4517-4" />
</linearGradient>
<radialGradient
r="23.634638"
fy="7.9319997"
fx="32.151962"
cy="7.9319997"
cx="32.151962"
gradientTransform="matrix(1,0,0,1.1841158,-8.5173246,-3.4097568)"
gradientUnits="userSpaceOnUse"
id="radialGradient4538"
xlink:href="#linearGradient4513-2"
inkscape:collect="always" />
<linearGradient
id="linearGradient4513-1">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4515-8" />
<stop
style="stop-color:#999999;stop-opacity:1;"
offset="1"
id="stop4517-6" />
</linearGradient>
<radialGradient
r="23.634638"
fy="7.9319997"
fx="32.151962"
cy="7.9319997"
cx="32.151962"
gradientTransform="matrix(1,0,0,1.1841158,-8.5173246,-3.4097568)"
gradientUnits="userSpaceOnUse"
id="radialGradient4538-6"
xlink:href="#linearGradient4513-1"
inkscape:collect="always" />
<linearGradient
id="linearGradient4513-1-3">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4515-8-7" />
<stop
style="stop-color:#999999;stop-opacity:1;"
offset="1"
id="stop4517-6-5" />
</linearGradient>
<radialGradient
r="23.634638"
fy="35.869175"
fx="32.151962"
cy="35.869175"
cx="32.151962"
gradientTransform="matrix(0.39497909,0,0,1.1841158,-2.716491,-26.067007)"
gradientUnits="userSpaceOnUse"
id="radialGradient3069"
xlink:href="#linearGradient4513-1-3"
inkscape:collect="always" />
<linearGradient
id="linearGradient4513-1-2">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop4515-8-6" />
<stop
style="stop-color:#999999;stop-opacity:1;"
offset="1"
id="stop4517-6-6" />
</linearGradient>
<radialGradient
r="23.634638"
fy="35.869175"
fx="32.151962"
cy="35.869175"
cx="32.151962"
gradientTransform="matrix(0.39497909,0,0,1.1841158,-2.716491,-26.067007)"
gradientUnits="userSpaceOnUse"
id="radialGradient3102"
xlink:href="#linearGradient4513-1-2"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4513-1"
id="radialGradient3132"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.39497909,0,0,1.1841158,39.898269,-8.9520575)"
cx="32.151962"
cy="27.950663"
fx="32.151962"
fy="27.950663"
r="23.634638" />
<inkscape:perspective
id="perspective2824-0"
inkscape:persp3d-origin="32 : 21.333333 : 1"
inkscape:vp_z="64 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 32 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3622-93" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3622-9-6" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3653-0" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3675-6" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3697-2" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3720-6" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3742-1" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3764-8" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3785-7" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3806-9" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3806-3-2" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3835-0" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3614-2" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3614-8-3" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3643-7" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3643-3-5" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3672-9" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3672-5-2" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3701-2" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3701-8-8" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective3746-9" />
<pattern
inkscape:collect="always"
xlink:href="#Strips1_1-4-1"
id="pattern5231-7"
patternTransform="matrix(0.67643728,-0.81829155,2.4578314,1.8844554,-26.450606,18.294947)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5224-36" />
<pattern
inkscape:collect="always"
patternUnits="userSpaceOnUse"
width="2"
height="1"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
id="Strips1_1-4-1"
inkscape:stockid="Stripes 1:1">
<rect
style="fill:black;stroke:none"
x="0"
y="-0.5"
width="1"
height="2"
id="rect4483-4-2" />
</pattern>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5224-9-9" />
<pattern
inkscape:collect="always"
xlink:href="#Strips1_1-6-9"
id="pattern5231-4-3"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,39.618381,8.9692804)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5224-3-1" />
<pattern
inkscape:collect="always"
patternUnits="userSpaceOnUse"
width="2"
height="1"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
id="Strips1_1-6-9"
inkscape:stockid="Stripes 1:1">
<rect
style="fill:black;stroke:none"
x="0"
y="-0.5"
width="1"
height="2"
id="rect4483-0-4" />
</pattern>
<pattern
inkscape:collect="always"
xlink:href="#pattern5231-3-4"
id="pattern5296-7"
patternTransform="matrix(0.66513382,-1.0631299,2.4167603,2.4482973,-49.762569,2.9546807)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5288-8" />
<pattern
inkscape:collect="always"
xlink:href="#Strips1_1-4-3-5"
id="pattern5231-3-4"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,-26.336284,10.887197)" />
<pattern
inkscape:collect="always"
patternUnits="userSpaceOnUse"
width="2"
height="1"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
id="Strips1_1-4-3-5"
inkscape:stockid="Stripes 1:1">
<rect
style="fill:black;stroke:none"
x="0"
y="-0.5"
width="1"
height="2"
id="rect4483-4-6-0" />
</pattern>
<pattern
inkscape:collect="always"
xlink:href="#Strips1_1-9-1"
id="pattern5330-3"
patternTransform="matrix(0.42844886,-0.62155849,1.5567667,1.431396,27.948414,13.306456)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5323-6" />
<pattern
inkscape:collect="always"
patternUnits="userSpaceOnUse"
width="2"
height="1"
patternTransform="matrix(0.66772843,-1.0037085,2.4261878,2.3114548,3.4760987,3.534923)"
id="Strips1_1-9-1"
inkscape:stockid="Stripes 1:1">
<rect
style="fill:black;stroke:none"
x="0"
y="-0.5"
width="1"
height="2"
id="rect4483-3-0" />
</pattern>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5361-6" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5383-3" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
id="perspective5411-2" />
<linearGradient
gradientTransform="translate(127.27273,-51.272729)"
gradientUnits="userSpaceOnUse"
y2="40.168594"
x2="4.0605712"
y1="41.087898"
x1="37.89756"
id="linearGradient4460"
xlink:href="#linearGradient3681"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(127.27273,-51.272729)"
gradientUnits="userSpaceOnUse"
y2="43.558987"
x2="59.811455"
y1="40.484772"
x1="37.894287"
id="linearGradient4462"
xlink:href="#linearGradient3681"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3681"
id="linearGradient4464"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-37.00068,-20.487365)"
x1="37.894287"
y1="40.484772"
x2="59.811455"
y2="43.558987" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4513"
id="radialGradient4538-5"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.1841158,-8.5173246,-3.4097568)"
cx="32.151962"
cy="7.9319997"
fx="32.151962"
fy="7.9319997"
r="23.634638" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4513"
id="radialGradient4538-6-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,1.1841158,-8.5173246,-3.4097568)"
cx="32.151962"
cy="7.9319997"
fx="32.151962"
fy="7.9319997"
r="23.634638" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4513"
id="radialGradient3069-9"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.39497909,0,0,1.1841158,-2.716491,-26.067007)"
cx="32.151962"
cy="35.869175"
fx="32.151962"
fy="35.869175"
r="23.634638" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient4513"
id="radialGradient3102-4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.39497909,0,0,1.1841158,-2.716491,-26.067007)"
cx="32.151962"
cy="35.869175"
fx="32.151962"
fy="35.869175"
r="23.634638" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="5.4"
inkscape:cx="30.313471"
inkscape:cy="21.635873"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
inkscape:snap-bbox-midpoints="true"
inkscape:object-paths="true"
inkscape:object-nodes="true"
inkscape:window-width="1162"
inkscape:window-height="1041"
inkscape:window-x="1778"
inkscape:window-y="18"
inkscape:window-maximized="0"
inkscape:snap-global="true"
showguides="true"
inkscape:guide-bbox="true" />
<metadata
id="metadata2821">
<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">
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#0047ff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:2.69342875;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="M 4.1534094,8.0397726 4.4584685,61.429158 60.875469,61.492988 60.965909,8.0397756 Z"
id="path4211"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0"
id="path4479"
d="m 10.811928,56.359694 45.307669,-0.287647 -0.203151,-13.606439 -45.14925,0 0.04473,-13.136118 45.307356,0.04984 3.12e-4,-12.425251 -45.14925,0"
style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5.78900003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#00ab00;stroke-width:5.78900003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
d="M 9.8860025,54.878213 55.193671,54.590566 54.99052,40.984127 l -45.1492502,0 0.044733,-13.136118 45.3073562,0.04984 3.12e-4,-12.425251 -45.14925,0"
id="path3418"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient3132);fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.97430003;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m 43.60191,2.5424407 0,17.4659093 0,8.59375 17.343749,-8.59375 0,-1.90625 0,-15.5596593 z M 60.945659,25.1021 43.60191,33.6646 l 0,7.03125 17.343749,-8.59375 z m 0,12.09375 -17.102182,8.806052 11.224972,0.201655 5.83932,-3.800835 z"
id="rect4417"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -23,56 +23,28 @@
<item row="0" column="0">
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>4</number>
<number>0</number>
</property>
<widget class="QWidget" name="Geometry">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
</rect>
</property>
<property name="toolTip">
<string>Contour works on shape outer loop but maybe could work on something else</string>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<normaloff>:/icons/Path-BaseGeometry.svg</normaloff>:/icons/Path-BaseGeometry.svg</iconset>
</attribute>
<attribute name="label">
<string>Base Geometry</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
<widget class="QWidget" name="Depths">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
<height>318</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path-Depths.svg</normaloff>:/icons/Path-Depths.svg</iconset>
</attribute>
<attribute name="label">
<string>Depths</string>
</attribute>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="Gui::InputField" name="startDepth">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
@@ -114,6 +86,13 @@
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="Gui::InputField" name="startDepth">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="Heights">
@@ -122,11 +101,11 @@
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
<height>318</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path-Heights.svg</normaloff>:/icons/Path-Heights.svg</iconset>
</attribute>
<attribute name="label">
@@ -172,7 +151,7 @@
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
<height>318</height>
</rect>
</property>
<attribute name="label">
@@ -193,7 +172,7 @@
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2" colspan="2">
<item row="0" column="0" colspan="2">
<widget class="QTreeWidget" name="tagTree">
<column>
<property name="text">
@@ -230,11 +209,11 @@
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
<height>318</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path-OperationB.svg</normaloff>:/icons/Path-OperationB.svg</iconset>
</attribute>
<attribute name="label">
@@ -358,8 +337,8 @@
</customwidget>
</customwidgets>
<resources>
<include location="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc"/>
<include location="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc"/>
<include location="../Path.qrc"/>
<include location="../Path.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -0,0 +1,418 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPanel</class>
<widget class="QWidget" name="TaskPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>374</width>
<height>453</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>400</height>
</size>
</property>
<property name="windowTitle">
<string>Mill Facing</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="Geometry">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>340</width>
<height>277</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path-BaseGeometry.svg</normaloff>:/icons/Path-BaseGeometry.svg</iconset>
</attribute>
<attribute name="label">
<string>Base Geometry</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="3">
<widget class="QListWidget" name="baseList">
<property name="toolTip">
<string>Drag to reorder, then update.</string>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="addBase">
<property name="toolTip">
<string>Add item selected in window.</string>
</property>
<property name="text">
<string>add</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="deleteBase">
<property name="toolTip">
<string>Remove Item selected in list, then update.</string>
</property>
<property name="text">
<string>Remove</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="reorderBase">
<property name="toolTip">
<string>Update the path with the removed and reordered items.</string>
</property>
<property name="text">
<string>Update</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="text">
<string>All objects will be processed using the same operation properties.</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="Depths">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<height>124</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path-Depths.svg</normaloff>:/icons/Path-Depths.svg</iconset>
</attribute>
<attribute name="label">
<string>Depths</string>
</attribute>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="Gui::InputField" name="startDepth">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Start Depth</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::InputField" name="finalDepth">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Final Depth</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="Gui::InputField" name="finishDepth">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Finish Depth</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QDoubleSpinBox" name="stepDown">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Step Down</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="Heights">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<height>95</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path-Heights.svg</normaloff>:/icons/Path-Heights.svg</iconset>
</attribute>
<attribute name="label">
<string>Heights</string>
</attribute>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="Gui::InputField" name="safeHeight">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Safe Height</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::InputField" name="clearanceHeight">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Clearance Height</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>356</width>
<height>296</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../Path.qrc">
<normaloff>:/icons/Path-OperationB.svg</normaloff>:/icons/Path-OperationB.svg</iconset>
</attribute>
<attribute name="label">
<string>Operation</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QWidget" name="widget_4" native="true">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Pass Extension</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="extraOffset">
<property name="minimum">
<double>-99.000000000000000</double>
</property>
<property name="maximum">
<double>99.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Step Over Percent</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="stepOverPercent">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>10</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QCheckBox" name="useZigZag">
<property name="text">
<string>Use ZigZag</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_10">
<property name="text">
<string>ZigZag Angle</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QSpinBox" name="zigZagAngle"/>
</item>
<item row="1" column="0" colspan="2">
<widget class="QCheckBox" name="zigZagUnidirectional">
<property name="text">
<string>ZigZag Unidirectional</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QWidget" name="widget_3" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Cut Mode</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Boundary Shape</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="boundaryShape">
<item>
<property name="text">
<string>Perimeter</string>
</property>
</item>
<item>
<property name="text">
<string>Boundbox</string>
</property>
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="cutMode">
<item>
<property name="text">
<string>Climb</string>
</property>
</item>
<item>
<property name="text">
<string>Conventional</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item row="1" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::InputField</class>
<extends>QLineEdit</extends>
<header>Gui/InputField.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../Path.qrc"/>
<include location="../Path.qrc"/>
</resources>
<connections/>
</ui>

View File

@@ -111,8 +111,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>319</height>
<width>168</width>
<height>99</height>
</rect>
</property>
<attribute name="icon">
@@ -178,8 +178,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>319</height>
<width>165</width>
<height>70</height>
</rect>
</property>
<attribute name="icon">
@@ -250,7 +250,7 @@
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2" colspan="2">
<item row="0" column="0" colspan="2">
<widget class="QTreeWidget" name="tagTree">
<column>
<property name="text">
@@ -286,8 +286,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>319</height>
<width>322</width>
<height>306</height>
</rect>
</property>
<attribute name="icon">

View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>352</width>
<height>525</height>
<width>399</width>
<height>519</height>
</rect>
</property>
<property name="minimumSize">
@@ -33,8 +33,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>358</height>
<width>381</width>
<height>353</height>
</rect>
</property>
<attribute name="icon">
@@ -45,22 +45,6 @@
<string>Base Geometry</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="3">
<widget class="QListWidget" name="baseList">
<property name="toolTip">
<string>Drag to reorder, then update.</string>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="addBase">
<property name="toolTip">
@@ -104,6 +88,22 @@
</property>
</widget>
</item>
<item row="0" column="0" colspan="3">
<widget class="QListWidget" name="baseList">
<property name="toolTip">
<string>Drag to reorder, then update.</string>
</property>
<property name="dragDropMode">
<enum>QAbstractItemView::DragDrop</enum>
</property>
<property name="defaultDropAction">
<enum>Qt::MoveAction</enum>
</property>
<property name="sortingEnabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="Depths">
@@ -111,8 +111,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>358</height>
<width>381</width>
<height>353</height>
</rect>
</property>
<attribute name="icon">
@@ -178,8 +178,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>358</height>
<width>381</width>
<height>353</height>
</rect>
</property>
<attribute name="icon">
@@ -228,14 +228,28 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>358</height>
<width>381</width>
<height>353</height>
</rect>
</property>
<attribute name="label">
<string>Holding</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QPushButton" name="addTag">
<property name="text">
<string>Add New</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="deleteTag">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QTreeWidget" name="tagTree">
<column>
@@ -265,20 +279,6 @@
</column>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="addTag">
<property name="text">
<string>Add New</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="deleteTag">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
@@ -286,8 +286,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>358</height>
<width>381</width>
<height>353</height>
</rect>
</property>
<attribute name="icon">
@@ -301,28 +301,107 @@
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Algorithm</string>
</property>
<item row="4" column="0" colspan="2">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="0">
<widget class="QCheckBox" name="useEndPoint">
<property name="text">
<string>Use End Point</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="useStartPoint">
<property name="text">
<string>Use Start Point</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="useCompensation">
<property name="text">
<string>Use Compensation</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QCheckBox" name="processHoles">
<property name="text">
<string>Process Holes</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QCheckBox" name="processPerimeter">
<property name="text">
<string>Process Perimeter</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QWidget" name="widget_4" native="true">
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Extra Offset</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="extraOffset"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Segment Length</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="segLen"/>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="rollRadius"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Roll Radius</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Plunge Angle</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="plungeAngle"/>
</item>
</layout>
</widget>
</item>
<item row="6" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="algorithmSelect">
<item>
<property name="text">
<string>OCC Native</string>
</property>
</item>
<item>
<property name="text">
<string>libarea</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QWidget" name="widget_3" native="true">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
@@ -375,86 +454,6 @@
</layout>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QCheckBox" name="useStartPoint">
<property name="text">
<string>Use Start Point</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="useCompensation">
<property name="text">
<string>Use Compensation</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="useEndPoint">
<property name="text">
<string>Use End Point</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="processHoles">
<property name="text">
<string>Process Holes</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QWidget" name="widget_4" native="true">
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Extra Offset</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="extraOffset"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Segment Length</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="segLen"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Roll Radius</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="rollRadius"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Plunge Angle</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="plungeAngle"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>

View File

@@ -74,13 +74,14 @@ class PathWorkbench (Workbench):
from PathScripts import PathContour
from PathScripts import PathProfileEdges
from PathScripts import DogboneDressup
from PathScripts import PathMillFace
import PathCommands
# build commands list
projcmdlist = ["Path_Job", "Path_Post", "Path_Inspect", "Path_Sanity"]
toolcmdlist = ["Path_ToolLibraryEdit", "Path_LoadTool"]
prepcmdlist = ["Path_Plane", "Path_Fixture", "Path_ToolLenOffset", "Path_Comment", "Path_Stop", "Path_FaceProfile", "Path_FacePocket", "Path_Custom", "Path_FromShape"]
twodopcmdlist = ["Path_Contour", "Path_Profile", "Path_Profile_Edges", "Path_Pocket", "Path_Drilling", "Path_Engrave"]
twodopcmdlist = ["Path_Contour", "Path_Profile", "Path_Profile_Edges", "Path_Pocket", "Path_Drilling", "Path_Engrave", "Path_MillFace"]
threedopcmdlist = ["Path_Surfacing"]
modcmdlist = ["Path_Copy", "Path_CompoundExtended", "Path_Array", "Path_SimpleCopy" ]
dressupcmdlist = ["Dogbone_Dressup", "DragKnife_Dressup"]
@@ -135,7 +136,7 @@ class PathWorkbench (Workbench):
if len(FreeCADGui.Selection.getSelection()) == 1:
if FreeCADGui.Selection.getSelection()[0].isDerivedFrom("Path::Feature"):
self.appendContextMenu("", ["Path_Inspect"])
if "Profile" in FreeCADGui.Selection.getSelection()[0].Name:
if "Profile" or "Contour" in FreeCADGui.Selection.getSelection()[0].Name:
self.appendContextMenu("", ["Add_Tag"])
self.appendContextMenu("", ["Set_StartPoint"])
self.appendContextMenu("", ["Set_EndPoint"])

View File

@@ -25,6 +25,7 @@
import FreeCAD
import Path
from FreeCAD import Vector
import TechDraw
from PathScripts import PathUtils
from PathScripts.PathUtils import depth_params
@@ -246,8 +247,7 @@ class ObjectContour:
baseobject = parentJob.Base
if baseobject is None:
return
print "base object: " + baseobject.Name
contourwire = PathUtils.silhouette(baseobject)
contourwire = TechDraw.findShapeOutline(baseobject.Shape,1, Vector(0,0,1))
edgelist = contourwire.Edges
edgelist = Part.__sortEdges__(edgelist)
@@ -419,7 +419,6 @@ class TaskPanel:
self.updating = False
def accept(self):
print "removed"
self.getFields()
FreeCADGui.ActiveDocument.resetEdit()
@@ -428,7 +427,6 @@ class TaskPanel:
FreeCAD.ActiveDocument.recompute()
def reject(self):
print "removed1"
FreeCADGui.Control.closeDialog()
FreeCADGui.Selection.removeObserver(self.s)
FreeCAD.ActiveDocument.recompute()
@@ -482,6 +480,7 @@ class TaskPanel:
if index >= 0:
self.form.direction.setCurrentIndex(index)
self.form.tagTree.blockSignals(True)
for i in range(len(self.obj.locs)):
item = QtGui.QTreeWidgetItem(self.form.tagTree)
item.setText(0, str(i+1))
@@ -492,6 +491,7 @@ class TaskPanel:
item.setText(4, str(self.obj.angles[i]))
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
item.setTextAlignment(0, QtCore.Qt.AlignLeft)
self.form.tagTree.blockSignals(False)
def open(self):
self.s = SelObserver()

View File

@@ -189,15 +189,26 @@ class ObjectDrilling:
drillable = False
if obj.ShapeType == 'Vertex':
drillable = True
elif obj.ShapeType == 'Solid':
elif obj.ShapeType in['Solid', 'Compound']:
if sub[0:4] == 'Face':
subobj = obj.getElement(sub)
if isinstance(subobj.Edges[0].Curve, Part.Circle):
drillable = True
if str(subobj.Surface) == "<Cylinder object>":
drillable = True
if len(subobj.Edges[0].Vertexes) > 1:
drillable = False
if len(subobj.Edges) == 3:
cedge = []
ledge = []
for e in subobj.Edges:
if isinstance (e.Curve, Part.Circle):
cedge.append(e)
elif isinstance (e.Curve, Part.Line):
ledge.append(e)
if len(cedge) == 2 and len(ledge) == 1:
drillable = True
else:
#if len(subobj.Edges[0].Vertexes) > 1:
drillable = False
if sub[0:4] == 'Edge':
o = obj.getElement(sub)
if isinstance(o.Curve, Part.Circle) and len(o.Vertexes) == 1:

View File

@@ -302,26 +302,26 @@ def profile2(curve, direction="on", radius=1.0, vertfeed=0.0,
extend_at_start=0.0, extend_at_end=0.0, lead_in_line_len=0.0,
lead_out_line_len=0.0):
print "direction: " + str(direction)
print "radius: " + str(radius)
print "vertfeed: " + str(vertfeed)
print "horizfeed: " + str(horizfeed)
print "offset_extra: " + str(offset_extra)
print "roll_radius: " + str(roll_radius)
print "roll_on: " + str(roll_on)
print "roll_off: " + str(roll_off)
print "depthparams: " + str(depthparams)
print "extend_at_start: " + str(extend_at_start)
print "extend_at_end: " + str(extend_at_end)
print "lead_in_line_len: " + str(lead_in_line_len)
print "lead_out_line_len: " + str(lead_out_line_len)
print "in profile2: 318"
# print "direction: " + str(direction)
# print "radius: " + str(radius)
# print "vertfeed: " + str(vertfeed)
# print "horizfeed: " + str(horizfeed)
# print "offset_extra: " + str(offset_extra)
# print "roll_radius: " + str(roll_radius)
# print "roll_on: " + str(roll_on)
# print "roll_off: " + str(roll_off)
# print "depthparams: " + str(depthparams)
# print "extend_at_start: " + str(extend_at_start)
# print "extend_at_end: " + str(extend_at_end)
# print "lead_in_line_len: " + str(lead_in_line_len)
# print "lead_out_line_len: " + str(lead_out_line_len)
# print "in profile2: 318"
global tags
direction = direction.lower()
offset_curve = area.Curve(curve)
print "curve: " , str(curve)
print "result curve: ", offset_curve.__dict__
# print "curve: " , str(curve)
# print "result curve: ", offset_curve.__dict__
if direction == "on":
use_CRC() == False

View File

@@ -26,6 +26,7 @@
import FreeCAD
import FreeCADGui
import PathUtils
import Path
import Part
import PathScripts
from PySide import QtCore, QtGui
@@ -74,6 +75,15 @@ class LoadTool():
else:
commands += 'M4S' + str(obj.SpindleSpeed) + '\n'
# print output
if commands == "":
commands += "(No commands processed)"
path = Path.Path(commands)
obj.Path = path
obj.ViewObject.Visibility = True
def onChanged(self, obj, prop):
mode = 2
obj.setEditorMode('Placement', mode)

View File

@@ -0,0 +1,635 @@
# -*- coding: utf-8 -*-
# ***************************************************************************
# * *
# * Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
import FreeCAD
import Path
from PySide import QtCore, QtGui
from PathScripts import PathUtils
import Part
import PathScripts.PathKurveUtils
import area
import TechDraw
from FreeCAD import Vector
FreeCADGui = None
if FreeCAD.GuiUp:
import FreeCADGui
"""Path Face object and FreeCAD command"""
# Qt tanslation handling
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def translate(context, text, disambig=None):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def translate(context, text, disambig=None):
return QtGui.QApplication.translate(context, text, disambig)
class ObjectFace:
def __init__(self, obj):
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","The base geometry of this object"))
obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","Make False, to prevent operation from generating code"))
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","An optional comment for this profile"))
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","User Assigned Label"))
# Tool Properties
obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber", "Tool", QtCore.QT_TRANSLATE_NOOP("App::Property","The tool number in use"))
obj.ToolNumber = (0, 0, 1000, 0)
obj.setEditorMode('ToolNumber', 1) # make this read only
obj.addProperty("App::PropertyString", "ToolDescription", "Tool", QtCore.QT_TRANSLATE_NOOP("App::Property","The description of the tool "))
obj.setEditorMode('ToolDescription', 1) # make this read only
# Depth Properties
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","The height needed to clear clamps and obstructions"))
obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Rapid Safety Height between locations."))
obj.addProperty("App::PropertyFloatConstraint", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Incremental Step Down of Tool"))
obj.StepDown = (0.0, 0.01, 100.0, 0.5)
obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Starting Depth of Tool- first cut depth in Z"))
obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Final Depth of Tool- lowest value in Z"))
obj.addProperty("App::PropertyDistance", "FinishDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","Maximum material removed on final pass."))
# Face Properties
obj.addProperty("App::PropertyEnumeration", "CutMode", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW"))
obj.CutMode = ['Climb', 'Conventional']
obj.addProperty("App::PropertyDistance", "PassExtension", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","How far the cutter should extend past the boundary"))
obj.addProperty("App::PropertyEnumeration", "StartAt", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Start Faceing at center or boundary"))
obj.StartAt = ['Center', 'Edge']
obj.addProperty("App::PropertyPercent", "StepOver", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Percent of cutter diameter to step over on each pass"))
#obj.StepOver = (1, 1, 100, 1)
obj.addProperty("App::PropertyBool", "KeepToolDown", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Attempts to avoid unnecessary retractions."))
obj.addProperty("App::PropertyBool", "ZigUnidirectional", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Lifts tool at the end of each pass to respect cut mode."))
obj.addProperty("App::PropertyBool", "UseZigZag", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Use Zig Zag pattern to clear area."))
obj.addProperty("App::PropertyFloat", "ZigZagAngle", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Angle of the zigzag pattern"))
obj.addProperty("App::PropertyEnumeration", "BoundaryShape", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property","Shape to use for calculating Boundary"))
obj.BoundaryShape = ['Perimeter', 'Boundbox']
# Start Point Properties
obj.addProperty("App::PropertyVector", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property","The start point of this path"))
obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property","make True, if specifying a Start Point"))
obj.Proxy = self
def onChanged(self, obj, prop):
if prop == "UserLabel":
obj.Label = obj.UserLabel + " :" + obj.ToolDescription
if prop == "StepOver":
if obj.StepOver == 0:
obj.StepOver = 1
def __getstate__(self):
return None
def __setstate__(self, state):
return None
def _guessDepths(self, obj, ss, sub=""):
try:
bb = ss.Shape.BoundBox # parent boundbox
subobj = ss.Shape.getElement(sub)
fbb = subobj.BoundBox # feature boundbox
obj.StartDepth = bb.ZMax
obj.ClearanceHeight = bb.ZMax + 5.0
obj.SafeHeight = bb.ZMax + 3.0
if fbb.ZMax == fbb.ZMin and fbb.ZMax == bb.ZMax: # top face
obj.FinalDepth = bb.ZMin
elif fbb.ZMax > fbb.ZMin and fbb.ZMax == bb.ZMax: # vertical face, full cut
obj.FinalDepth = fbb.ZMin
elif fbb.ZMax > fbb.ZMin and fbb.ZMin > bb.ZMin: # internal vertical wall
obj.FinalDepth = fbb.ZMin
elif fbb.ZMax == fbb.ZMin and fbb.ZMax > bb.ZMin: # face/shelf
obj.FinalDepth = fbb.ZMin
else: # catch all
obj.FinalDepth = bb.ZMin
except:
obj.StartDepth = 5.0
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0
def addFacebase(self, obj, ss, sub=""):
baselist = obj.Base
if baselist is None:
baselist = []
if len(baselist) == 0: # When adding the first base object, guess at heights
self._guessDepths(obj, ss, sub)
item = (ss, sub)
if item in baselist:
FreeCAD.Console.PrintWarning(translate("Path", "this object already in the list" + "\n"))
elif PathUtils.findParentJob(obj).Base.Name != ss.Name:
FreeCAD.Console.PrintWarning(translate("Path", "Please select features from the Job model object" +"\n"))
else:
baselist.append(item)
obj.Base = baselist
self.execute(obj)
def getStock(self, obj):
"""find and return a stock object from hosting project if any"""
for o in obj.InList:
if hasattr(o, "Group"):
for g in o.Group:
if hasattr(g, "Height_Allowance"):
return o
# not found? search one level up
for o in obj.InList:
return self.getStock(o)
return None
def buildpathlibarea(self, obj, a):
"""Build the face path using libarea algorithm"""
import PathScripts.PathAreaUtils as PathAreaUtils
from PathScripts.PathUtils import depth_params
FreeCAD.Console.PrintMessage(translate("PathFace", "Generating toolpath with libarea offsets.\n"))
depthparams = depth_params(
obj.ClearanceHeight.Value,
obj.SafeHeight.Value,
obj.StartDepth.Value,
obj.StepDown,
obj.FinishDepth.Value,
obj.FinalDepth.Value)
extraoffset = 1 - obj.PassExtension.Value
stepover = (self.radius * 2) * (float(obj.StepOver)/100)
use_zig_zag = obj.UseZigZag
zig_angle = obj.ZigZagAngle
from_center = (obj.StartAt == "Center")
keep_tool_down = obj.KeepToolDown
zig_unidirectional = obj.ZigUnidirectional
start_point = None
cut_mode = obj.CutMode
PathAreaUtils.flush_nc()
PathAreaUtils.output('mem')
PathAreaUtils.feedrate_hv(self.horizFeed, self.vertFeed)
if obj.UseStartPoint:
start_point = (obj.StartPoint.x, obj.StartPoint.y)
PathAreaUtils.pocket(
a,
self.radius,
extraoffset,
stepover,
depthparams,
from_center,
keep_tool_down,
use_zig_zag,
zig_angle,
zig_unidirectional,
start_point,
cut_mode)
return PathAreaUtils.retrieve_gcode()
# To reload this from FreeCAD, use: import PathScripts.PathFace; reload(PathScripts.PathFace)
def execute(self, obj):
if not obj.Active:
path = Path.Path("(inactive operation)")
obj.Path = path
obj.ViewObject.Visibility = False
return
#Tool may have changed. Refresh data
toolLoad = PathUtils.getLastToolLoad(obj)
if toolLoad is None or toolLoad.ToolNumber == 0:
self.vertFeed = 100
self.horizFeed = 100
self.vertRapid = 100
self.horiRrapid = 100
self.radius = 0.25
obj.ToolNumber = 0
obj.ToolDescription = "UNDEFINED"
else:
self.vertFeed = toolLoad.VertFeed.Value
self.horizFeed = toolLoad.HorizFeed.Value
self.vertRapid = toolLoad.VertRapid.Value
self.horizRapid = toolLoad.HorizRapid.Value
tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
if tool.Diameter == 0:
self.radius = 0.25
else:
self.radius = tool.Diameter/2
obj.ToolNumber = toolLoad.ToolNumber
obj.ToolDescription = toolLoad.Name
#Build preliminary comments
output = ""
output += "(" + obj.Label + ")"
if obj.UserLabel == "":
obj.Label = obj.Name + " :" + obj.ToolDescription
else:
obj.Label = obj.UserLabel + " :" + obj.ToolDescription
#Facing is done either against base objects
if obj.Base:
faces = []
for b in obj.Base:
for sub in b[1]:
shape = getattr(b[0].Shape, sub)
if isinstance (shape, Part.Face):
faces.append(shape)
else:
print ('falling out')
return
planeshape = Part.makeCompound(faces)
#If no base object, do planing of top surface of entire model
else:
parentJob = PathUtils.findParentJob(obj)
if parentJob is None:
return
baseobject = parentJob.Base
if baseobject is None:
return
planeshape = baseobject.Shape
#if user wants the boundbox, calculate that
if obj.BoundaryShape == 'Boundbox':
bb = planeshape.BoundBox
bbperim = Part.makeBox(bb.XLength, bb.YLength, 1, Vector(bb.XMin, bb.YMin, bb.ZMin), Vector(0,0,1))
contourwire = TechDraw.findShapeOutline(bbperim, 1, Vector(0,0,1))
else:
contourwire = TechDraw.findShapeOutline(planeshape, 1, Vector(0,0,1))
edgelist = contourwire.Edges
edgelist = Part.__sortEdges__(edgelist)
#use libarea to build the pattern
a = area.Area()
c = PathScripts.PathKurveUtils.makeAreaCurve(edgelist, 'CW')
a.append(c)
a.Reorder()
output += self.buildpathlibarea(obj, a)
path = Path.Path(output)
obj.Path = path
obj.ViewObject.Visibility = True
class _CommandSetFaceStartPoint:
def GetResources(self):
return {'Pixmap': 'Path-StartPoint',
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathFace", "Pick Start Point"),
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathFace", "Pick Start Point")}
def IsActive(self):
return FreeCAD.ActiveDocument is not None
def setpoint(self, point, o):
obj = FreeCADGui.Selection.getSelection()[0]
obj.StartPoint.x = point.x
obj.StartPoint.y = point.y
def Activated(self):
FreeCADGui.Snapper.getPoint(callback=self.setpoint)
class ViewProviderFace:
def __init__(self, vobj):
vobj.Proxy = self
def attach(self, vobj):
self.Object = vobj.Object
return
def setEdit(self, vobj, mode=0):
FreeCADGui.Control.closeDialog()
taskd = TaskPanel()
taskd.obj = vobj.Object
taskd.setupUi()
FreeCADGui.Control.showDialog(taskd)
return True
def getIcon(self):
return ":/icons/Path-Face.svg"
def __getstate__(self):
return None
def __setstate__(self, state):
return None
class CommandPathMillFace:
def GetResources(self):
return {'Pixmap': 'Path-Face',
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathFace", "Face"),
'Accel': "P, O",
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathFace", "Create a Facing Operation from a model or face")}
def IsActive(self):
if FreeCAD.ActiveDocument is not None:
for o in FreeCAD.ActiveDocument.Objects:
if o.Name[:3] == "Job":
return True
return False
def Activated(self):
# zbottom = 0.0
ztop = 10.0
# if everything is ok, execute and register the transaction in the undo/redo stack
FreeCAD.ActiveDocument.openTransaction(translate("PathFace", "Create Face"))
FreeCADGui.addModule("PathScripts.PathMillFace")
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Face")')
FreeCADGui.doCommand('PathScripts.PathMillFace.ObjectFace(obj)')
FreeCADGui.doCommand('obj.Active = True')
FreeCADGui.doCommand('PathScripts.PathMillFace.ViewProviderFace(obj.ViewObject)')
FreeCADGui.doCommand('from PathScripts import PathUtils')
FreeCADGui.doCommand('obj.StepOver = 50')
FreeCADGui.doCommand('obj.ClearanceHeight = 10') # + str(bb.ZMax + 2.0))
FreeCADGui.doCommand('obj.StepDown = 1.0')
FreeCADGui.doCommand('obj.StartDepth = ' + str(ztop + 1))
FreeCADGui.doCommand('obj.FinalDepth =' + str(ztop))
FreeCADGui.doCommand('obj.ZigZagAngle = 0.0')
FreeCADGui.doCommand('obj.UseZigZag = True')
FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)')
snippet = '''
parentJob = PathUtils.findParentJob(obj)
if parentJob is None:
pass
else:
baseobject = parentJob.Base
if baseobject is None:
pass
else:
obj.StartDepth = str(baseobject.Shape.BoundBox.ZMax + 1)
obj.FinalDepth = str(baseobject.Shape.BoundBox.ZMax)
'''
FreeCADGui.doCommand(snippet)
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
FreeCADGui.doCommand('obj.ViewObject.startEditing()')
class TaskPanel:
def __init__(self):
#self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/MillFaceEdit.ui")
self.form = FreeCADGui.PySideUic.loadUi(":/panels/MillFaceEdit.ui")
self.updating = False
def accept(self):
self.getFields()
FreeCADGui.ActiveDocument.resetEdit()
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
FreeCADGui.Selection.removeObserver(self.s)
def reject(self):
FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
FreeCADGui.Selection.removeObserver(self.s)
def getFields(self):
if self.obj:
if hasattr(self.obj, "StartDepth"):
self.obj.StartDepth = self.form.startDepth.text()
if hasattr(self.obj, "FinalDepth"):
self.obj.FinalDepth = self.form.finalDepth.text()
if hasattr(self.obj, "FinishDepth"):
self.obj.FinishDepth = self.form.finishDepth.text()
if hasattr(self.obj, "SafeHeight"):
self.obj.SafeHeight = self.form.safeHeight.text()
if hasattr(self.obj, "ClearanceHeight"):
self.obj.ClearanceHeight = self.form.clearanceHeight.text()
if hasattr(self.obj, "StepDown"):
self.obj.StepDown = self.form.stepDown.value()
if hasattr(self.obj, "PassExtension"):
self.obj.PassExtension = self.form.extraOffset.value()
# if hasattr(self.obj, "UseStartPoint"):
# self.obj.UseStartPoint = self.form.useStartPoint.isChecked()
if hasattr(self.obj, "CutMode"):
self.obj.CutMode = str(self.form.cutMode.currentText())
if hasattr(self.obj, "UseZigZag"):
self.obj.UseZigZag = self.form.useZigZag.isChecked()
if hasattr(self.obj, "ZigUnidirectional"):
self.obj.ZigUnidirectional = self.form.zigZagUnidirectional.isChecked()
if hasattr(self.obj, "ZigZagAngle"):
self.obj.ZigZagAngle = self.form.zigZagAngle.value()
if hasattr(self.obj, "StepOver"):
self.obj.StepOver = self.form.stepOverPercent.value()
if hasattr(self.obj, "BoundaryShape"):
self.obj.BoundaryShape = str(self.form.boundaryShape.currentText())
self.obj.Proxy.execute(self.obj)
def setFields(self):
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
self.form.finishDepth.setText(str(self.obj.FinishDepth.Value))
self.form.stepDown.setValue(self.obj.StepDown)
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
self.form.stepOverPercent.setValue(self.obj.StepOver)
self.form.useZigZag.setChecked(self.obj.UseZigZag)
self.form.zigZagUnidirectional.setChecked(self.obj.ZigUnidirectional)
self.form.zigZagAngle.setValue(self.obj.ZigZagAngle)
#self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
self.form.extraOffset.setValue(self.obj.PassExtension.Value)
index = self.form.cutMode.findText(
self.obj.CutMode, QtCore.Qt.MatchFixedString)
if index >=0:
self.form.cutMode.blockSignals(True)
self.form.cutMode.setCurrentIndex(index)
self.form.cutMode.blockSignals(False)
index = self.form.boundaryShape.findText(
self.obj.BoundaryShape, QtCore.Qt.MatchFixedString)
if index >=0:
self.form.boundaryShape.blockSignals(True)
self.form.boundaryShape.setCurrentIndex(index)
self.form.boundaryShape.blockSignals(False)
for i in self.obj.Base:
for sub in i[1]:
self.form.baseList.addItem(i[0].Name + "." + sub)
def open(self):
self.s = SelObserver()
# install the function mode resident
FreeCADGui.Selection.addObserver(self.s)
def addBase(self):
# check that the selection contains exactly what we want
selection = FreeCADGui.Selection.getSelectionEx()
if len(selection) != 1:
FreeCAD.Console.PrintError(translate("PathProject", "Please select only faces from one solid\n"))
return
sel = selection[0]
if not sel.HasSubObjects:
FreeCAD.Console.PrintError(translate("PathProject", "Please select faces from one solid\n"))
return
if not selection[0].SubObjects[0].ShapeType == "Face":
FreeCAD.Console.PrintError(translate("PathProject", "Please select faces from one solid\n"))
return
for i in sel.SubElementNames:
self.obj.Proxy.addFacebase(self.obj, sel.Object, i)
self.setFields() # defaults may have changed. Reload.
self.form.baseList.clear()
for i in self.obj.Base:
for sub in i[1]:
self.form.baseList.addItem(i[0].Name + "." + sub)
def deleteBase(self):
dlist = self.form.baseList.selectedItems()
newlist = []
for d in dlist:
deletebase = d.text().partition(".")[0]
deletesub = d.text().partition(".")[2]
for i in self.obj.Base:
sublist = []
#baseobj = i[0]
basesubs = i[1]
for sub in basesubs:
if sub != deletesub:
sublist.append(sub)
if len(sublist) >= 1:
newlist.append ((deletebase, tuple(sublist)))
if i[0].Name != d.text().partition(".")[0] and d.text().partition(".")[2] not in i[1]:
newlist.append(i)
self.form.baseList.takeItem(self.form.baseList.row(d))
self.obj.Base = newlist
self.obj.Proxy.execute(self.obj)
FreeCAD.ActiveDocument.recompute()
def itemActivated(self):
print self.form.baseList.selectedItems()[0].text()
FreeCADGui.Selection.clearSelection()
slist = self.form.baseList.selectedItems()
for i in slist:
objstring = i.text().partition(".")
obj = FreeCAD.ActiveDocument.getObject(objstring[0])
if objstring[2] != "":
FreeCADGui.Selection.addSelection(obj, objstring[2])
else:
FreeCADGui.Selection.addSelection(obj)
FreeCADGui.updateGui()
def reorderBase(self):
newlist = []
for i in range(self.form.baseList.count()):
s = self.form.baseList.item(i).text()
objstring = s.partition(".")
obj = FreeCAD.ActiveDocument.getObject(objstring[0])
item = (obj, str(objstring[2]))
newlist.append(item)
self.obj.Base = newlist
self.obj.Proxy.execute(self.obj)
FreeCAD.ActiveDocument.recompute()
def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Ok)
def edit(self, item, column):
if not self.updating:
self.resetObject()
def resetObject(self, remove=None):
"transfers the values from the widget to the object"
self.obj.touch()
FreeCAD.ActiveDocument.recompute()
def setupUi(self):
# Connect Signals and Slots
# Base Controls
self.form.baseList.itemSelectionChanged.connect(self.itemActivated)
self.form.addBase.clicked.connect(self.addBase)
self.form.deleteBase.clicked.connect(self.deleteBase)
self.form.reorderBase.clicked.connect(self.reorderBase)
# Depths
self.form.startDepth.editingFinished.connect(self.getFields)
self.form.finalDepth.editingFinished.connect(self.getFields)
self.form.finishDepth.editingFinished.connect(self.getFields)
self.form.stepDown.editingFinished.connect(self.getFields)
# Heights
self.form.safeHeight.editingFinished.connect(self.getFields)
self.form.clearanceHeight.editingFinished.connect(self.getFields)
# operation
self.form.cutMode.currentIndexChanged.connect(self.getFields)
#self.form.useStartPoint.clicked.connect(self.getFields)
self.form.extraOffset.editingFinished.connect(self.getFields)
self.form.boundaryShape.currentIndexChanged.connect(self.getFields)
self.form.stepOverPercent.editingFinished.connect(self.getFields)
self.form.useZigZag.clicked.connect(self.getFields)
self.form.zigZagUnidirectional.clicked.connect(self.getFields)
self.form.zigZagAngle.editingFinished.connect(self.getFields)
self.setFields()
sel = FreeCADGui.Selection.getSelectionEx()
if len(sel) != 0 and sel[0].HasSubObjects:
self.addBase()
class SelObserver:
def __init__(self):
import PathScripts.PathSelection as PST
PST.pocketselect()
def __del__(self):
import PathScripts.PathSelection as PST
PST.clear()
def addSelection(self, doc, obj, sub, pnt):
FreeCADGui.doCommand('Gui.Selection.addSelection(FreeCAD.ActiveDocument.' + obj + ')')
FreeCADGui.updateGui()
if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('Path_MillFace', CommandPathMillFace())
FreeCADGui.addCommand('Set_FaceStartPoint', _CommandSetFaceStartPoint())
FreeCAD.Console.PrintLog("Loading PathMillFace... done\n")

View File

@@ -25,6 +25,7 @@
import FreeCAD
import Path
import numpy
import TechDraw
from FreeCAD import Vector
from PathScripts import PathUtils
from PathScripts.PathUtils import depth_params
@@ -58,14 +59,11 @@ class ObjectProfile:
obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","An optional comment for this profile"))
obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property","User Assigned Label"))
obj.addProperty("App::PropertyEnumeration", "Algorithm", "Algorithm", QtCore.QT_TRANSLATE_NOOP("App::Property","The library or algorithm used to generate the path"))
obj.Algorithm = ['OCC Native', 'libarea']
obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber", "Tool", "The tool number in use")
obj.ToolNumber = (0, 0, 1000, 1)
obj.setEditorMode('ToolNumber', 1) # make this read only
obj.addProperty("App::PropertyString", "ToolDescription", "Tool", "The description of the tool ")
obj.setEditorMode('ToolDescription', 1) # make this read onlyt
obj.setEditorMode('ToolDescription', 1) # make this read only
# Depth Properties
obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property","The height needed to clear clamps and obstructions"))
@@ -98,7 +96,8 @@ class ObjectProfile:
obj.addProperty("App::PropertyDistance", "OffsetExtra", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property","Extra value to stay away from final profile- good for roughing toolpath"))
obj.addProperty("App::PropertyLength", "SegLen", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property","Tesselation value for tool paths made from beziers, bsplines, and ellipses"))
obj.addProperty("App::PropertyAngle", "PlungeAngle", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property","Plunge angle with which the tool enters the work piece. Straight down is 90 degrees, if set small enough or zero the tool will descent exactly one layer depth down per turn"))
obj.addProperty("App::PropertyBool", "processHoles", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property","Handl holes as well as the outline"))
obj.addProperty("App::PropertyBool", "processHoles", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property","Profile holes as well as the outline"))
obj.addProperty("App::PropertyBool", "processPerimeter", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property","Profile the outline"))
obj.addProperty("App::PropertyVectorList", "locs", "Tags", QtCore.QT_TRANSLATE_NOOP("App::Property","List of holding tag locations"))
@@ -114,7 +113,6 @@ class ObjectProfile:
obj.angles = angles
obj.lengths = lengths
obj.heights = heights
#obj.ToolDescription = "UNDEFINED"
obj.Proxy = self
@@ -167,29 +165,6 @@ class ObjectProfile:
obj.Base = baselist
self.execute(obj)
def _buildPathOCC(self, obj, wire):
import DraftGeomUtils
output = ""
if obj.Comment != "":
output += '(' + str(obj.Comment)+')\n'
if obj.Direction == 'CCW':
clockwise = False
else:
clockwise = True
FirstEdge = None
PathClosed = DraftGeomUtils.isReallyClosed(wire)
output += PathUtils.MakePath(
wire, obj.Side, self.radius, clockwise,
obj.ClearanceHeight.Value, obj.StepDown, obj.StartDepth.Value,
obj.FinalDepth.Value, FirstEdge, PathClosed, obj.SegLen.Value,
self.vertFeed, self.horizFeed, self.vertRapid, self.horizRapid,
PlungeAngle=obj.PlungeAngle.Value)
return output
def _buildPathLibarea(self, obj, edgelist, isHole):
import PathScripts.PathKurveUtils as PathKurveUtils
import math
@@ -228,7 +203,6 @@ print "y - " + str(point.y)
start location
CRC
or probably other features in heekscnc'''
# output += PathKurveUtils.profile(curve, side, radius, vf, hf, offset_extra, rapid_safety_space, clearance, start_depth, step_down, final_depth, use_CRC)
'''The following calls the original procedure from h
toolLoad = obj.activeTCeekscnc profile function. This, in turn, calls many other procedures to modify the profile.
@@ -273,8 +247,6 @@ print "y - " + str(point.y)
output = ""
toolLoad = PathUtils.getLastToolLoad(obj)
# obj.ToolController = PathUtils.getToolControllers(obj)
# toolLoad = PathUtils.getToolLoad(obj, obj.ToolController)
if toolLoad is None or toolLoad.ToolNumber == 0:
self.vertFeed = 100
@@ -309,62 +281,32 @@ print "y - " + str(point.y)
output += "(Uncompensated Tool Path)"
if obj.Base:
hfaces = []
vfaces = []
wires = []
holes = []
faces = []
for b in obj.Base:
for sub in b[1]:
# we only consider the outer wire if this is a Face
# Horizontal and vertical faces are handled differently
shape = getattr(b[0].Shape, sub)
if numpy.isclose(abs(shape.normalAt(0, 0).z), 1): # horizontal face
hfaces.append(shape)
if isinstance (shape, Part.Face):
faces.append(shape)
if numpy.isclose(abs(shape.normalAt(0, 0).z), 1): # horizontal face
holes += shape.Wires[1:]
elif numpy.isclose(shape.normalAt(0, 0).z, 0): # vertical face
vfaces.append(shape)
else:
FreeCAD.Console.PrintError(translate("Path", "Face doesn't appear to be parallel or perpendicular to the XY plane. No path will be generated for: \n"))
FreeCAD.Console.PrintError(b[0].Name + "." + sub + "\n")
print ("found a base object which is not a face. Can't continue.")
return
profileshape = Part.makeCompound(faces)
profilewire = TechDraw.findShapeOutline(profileshape, 1, Vector(0,0,1))
if obj.processHoles:
for h in hfaces:
holes += h.Wires[1:]
for h in hfaces:
wires.append(h.OuterWire)
tempshell = Part.makeShell(vfaces)
slices = tempshell.slice(FreeCAD.Base.Vector(0, 0, 1), tempshell.CenterOfMass.z )
wires = wires + slices
for wire in holes:
if obj.Algorithm == "OCC Native":
output += self._buildPathOCC(obj, wire)
else:
try:
import area
except:
FreeCAD.Console.PrintError(translate("Path", "libarea needs to be installed for this command to work.\n"))
return
for wire in holes:
edgelist = wire.Edges
edgelist = Part.__sortEdges__(edgelist)
output += self._buildPathLibarea(obj, edgelist, True)
for wire in wires:
if obj.Algorithm == "OCC Native":
output += self._buildPathOCC(obj, wire)
else:
try:
import area
except:
FreeCAD.Console.PrintError(translate("Path", "libarea needs to be installed for this command to work.\n"))
return
edgelist = wire.Edges
edgelist = Part.__sortEdges__(edgelist)
output += self._buildPathLibarea(obj, edgelist, False)
if obj.processPerimeter:
edgelist = profilewire.Edges
edgelist = Part.__sortEdges__(edgelist)
output += self._buildPathLibarea(obj, edgelist, False)
if obj.Active:
path = Path.Path(output)
@@ -500,12 +442,9 @@ class CommandPathProfile:
FreeCADGui.addModule("PathScripts.PathProfile")
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Profile")')
FreeCADGui.doCommand('PathScripts.PathProfile.ObjectProfile(obj)')
FreeCADGui.doCommand('PathScripts.PathProfile._ViewProviderProfile(obj.ViewObject)')
FreeCADGui.doCommand('obj.Active = True')
FreeCADGui.doCommand('obj.Algorithm = "libarea"')
FreeCADGui.doCommand('obj.ClearanceHeight = ' + str(ztop + 10.0))
FreeCADGui.doCommand('obj.StepDown = 1.0')
FreeCADGui.doCommand('obj.StartDepth= ' + str(ztop))
@@ -514,11 +453,12 @@ class CommandPathProfile:
FreeCADGui.doCommand('obj.SafeHeight = ' + str(ztop + 2.0))
FreeCADGui.doCommand('obj.Side = "Left"')
FreeCADGui.doCommand('obj.OffsetExtra = 0.0')
FreeCADGui.doCommand('obj.Direction = "CW"')
FreeCADGui.doCommand('obj.Direction = "CCW"')
FreeCADGui.doCommand('obj.UseComp = False')
FreeCADGui.doCommand('obj.processHoles = False')
FreeCADGui.doCommand('obj.processHoles = False')
FreeCADGui.doCommand('obj.processPerimeter = True')
FreeCADGui.doCommand('obj.PlungeAngle = 90.0')
#FreeCADGui.doCommand('obj.ActiveTC = None')
FreeCADGui.doCommand('PathScripts.PathProfile._ViewProviderProfile(obj.ViewObject)')
FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)')
FreeCAD.ActiveDocument.commitTransaction()
@@ -570,14 +510,14 @@ class TaskPanel:
self.obj.UseStartPoint = self.form.useStartPoint.isChecked()
if hasattr(self.obj, "UseEndPoint"):
self.obj.UseEndPoint = self.form.useEndPoint.isChecked()
if hasattr(self.obj, "Algorithm"):
self.obj.Algorithm = str(self.form.algorithmSelect.currentText())
if hasattr(self.obj, "Side"):
self.obj.Side = str(self.form.cutSide.currentText())
if hasattr(self.obj, "Direction"):
self.obj.Direction = str(self.form.direction.currentText())
if hasattr(self.obj, "processHoles"):
self.obj.processHoles = self.form.processHoles.isChecked()
if hasattr(self.obj, "processPerimeter"):
self.obj.processPerimeter = self.form.processPerimeter.isChecked()
self.obj.Proxy.execute(self.obj)
def setFields(self):
@@ -594,13 +534,7 @@ class TaskPanel:
self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
self.form.useEndPoint.setChecked(self.obj.UseEndPoint)
self.form.processHoles.setChecked(self.obj.processHoles)
index = self.form.algorithmSelect.findText(
self.obj.Algorithm, QtCore.Qt.MatchFixedString)
if index >= 0:
self.form.algorithmSelect.blockSignals(True)
self.form.algorithmSelect.setCurrentIndex(index)
self.form.algorithmSelect.blockSignals(False)
self.form.processPerimeter.setChecked(self.obj.processPerimeter)
index = self.form.cutSide.findText(
self.obj.Side, QtCore.Qt.MatchFixedString)
@@ -616,10 +550,13 @@ class TaskPanel:
self.form.direction.setCurrentIndex(index)
self.form.direction.blockSignals(False)
self.form.baseList.blockSignals(True)
for i in self.obj.Base:
for sub in i[1]:
self.form.baseList.addItem(i[0].Name + "." + sub)
self.form.baseList.blockSignals(False)
self.form.tagTree.blockSignals(True)
for i in range(len(self.obj.locs)):
item = QtGui.QTreeWidgetItem(self.form.tagTree)
item.setText(0, str(i+1))
@@ -630,6 +567,9 @@ class TaskPanel:
item.setText(4, str(self.obj.angles[i]))
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
item.setTextAlignment(0, QtCore.Qt.AlignLeft)
self.form.tagTree.blockSignals(False)
self.form.update()
def open(self):
self.s = SelObserver()
@@ -807,7 +747,6 @@ class TaskPanel:
self.form.clearanceHeight.editingFinished.connect(self.getFields)
# operation
self.form.algorithmSelect.currentIndexChanged.connect(self.getFields)
self.form.cutSide.currentIndexChanged.connect(self.getFields)
self.form.direction.currentIndexChanged.connect(self.getFields)
self.form.useCompensation.clicked.connect(self.getFields)
@@ -817,6 +756,7 @@ class TaskPanel:
self.form.segLen.editingFinished.connect(self.getFields)
self.form.rollRadius.editingFinished.connect(self.getFields)
self.form.processHoles.clicked.connect(self.getFields)
self.form.processPerimeter.clicked.connect(self.getFields)
# Tag Form
QtCore.QObject.connect(

View File

@@ -528,11 +528,13 @@ class TaskPanel:
self.obj.Direction, QtCore.Qt.MatchFixedString)
if index >= 0:
self.form.direction.setCurrentIndex(index)
self.form.baseList.blockSignals(True)
for i in self.obj.Base:
for sub in i[1]:
self.form.baseList.addItem(i[0].Name + "." + sub)
self.form.baseList.blockSignals(False)
self.form.tagTree.blockSignals(True)
for i in range(len(self.obj.locs)):
item = QtGui.QTreeWidgetItem(self.form.tagTree)
item.setText(0, str(i+1))
@@ -543,6 +545,8 @@ class TaskPanel:
item.setText(4, str(self.obj.angles[i]))
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
item.setTextAlignment(0, QtCore.Qt.AlignLeft)
self.form.tagTree.blockSignals(False)
def open(self):
self.s = SelObserver()

View File

@@ -100,7 +100,7 @@ class DRILLGate:
return False
if obj.ShapeType == 'Vertex':
drillable = True
elif obj.ShapeType == 'Solid':
elif obj.ShapeType in['Solid', 'Compound']:
if sub[0:4] == 'Face':
subobj = obj.getElement(sub)
drillable = isinstance(subobj.Edges[0].Curve, Part.Circle)

View File

@@ -84,8 +84,26 @@ def curvetowire(obj, steps):
# fixme set at 4 decimal places for testing
def fmt(val): return format(val, '.4f')
def getProjected(shape,direction):
"returns projected edges from a shape and a direction"
import Part,Drawing
edges = []
groups = Drawing.projectEx(shape,direction)
for g in groups[0:5]:
if g:
edges.append(g)
# if hasattr(obj,"Tessellation") and obj.Tessellation:
# return DraftGeomUtils.cleanProjection(Part.makeCompound(edges),obj.Tessellation,obj.SegmentLength)
# else:
return Part.makeCompound(edges)
def silhouette(obj):
w = TechDraw.findOuterWire(obj.Shape.Edges)
from FreeCAD import Vector
s = getProjected(obj.Shape, Vector(0,0,1))
print s
w = TechDraw.findOuterWire(s.Edges)
return w
def isSameEdge(e1, e2):
@@ -591,7 +609,9 @@ def addToJob(obj, jobname = None):
elif len(jobs) == 1:
job = jobs[0]
else:
form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/DlgJobChooser.ui")
#form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/DlgJobChooser.ui")
form = FreeCADGui.PySideUic.loadUi(":/panels/DlgJobChooser.ui")
mylist = [i.Name for i in jobs]
form.cboProject.addItems(mylist)
r = form.exec_()