Merge branch 'master' of https://github.com/FreeCAD/FreeCAD into deburr+dressup
This commit is contained in:
@@ -25,6 +25,8 @@ INSTALL(
|
||||
|
||||
SET(PathScripts_SRCS
|
||||
PathCommands.py
|
||||
PathScripts/PathAdaptive.py
|
||||
PathScripts/PathAdaptiveGui.py
|
||||
PathScripts/PathAreaOp.py
|
||||
PathScripts/PathArray.py
|
||||
PathScripts/PathCircularHoleBase.py
|
||||
@@ -46,6 +48,7 @@ SET(PathScripts_SRCS
|
||||
PathScripts/PathDressupTag.py
|
||||
PathScripts/PathDressupTagGui.py
|
||||
PathScripts/PathDressupTagPreferences.py
|
||||
PathScripts/PathDressupZCorrect.py
|
||||
PathScripts/PathDrilling.py
|
||||
PathScripts/PathDrillingGui.py
|
||||
PathScripts/PathEngrave.py
|
||||
@@ -82,6 +85,8 @@ SET(PathScripts_SRCS
|
||||
PathScripts/PathPreferences.py
|
||||
PathScripts/PathPreferencesPathDressup.py
|
||||
PathScripts/PathPreferencesPathJob.py
|
||||
PathScripts/PathProbe.py
|
||||
PathScripts/PathProbeGui.py
|
||||
PathScripts/PathProfileBase.py
|
||||
PathScripts/PathProfileBaseGui.py
|
||||
PathScripts/PathProfileContour.py
|
||||
@@ -97,6 +102,7 @@ SET(PathScripts_SRCS
|
||||
PathScripts/PathSetupSheetOpPrototype.py
|
||||
PathScripts/PathSetupSheetOpPrototypeGui.py
|
||||
PathScripts/PathSimpleCopy.py
|
||||
PathScripts/PathSimulatorGui.py
|
||||
PathScripts/PathStock.py
|
||||
PathScripts/PathStop.py
|
||||
PathScripts/PathSurface.py
|
||||
@@ -110,15 +116,14 @@ SET(PathScripts_SRCS
|
||||
PathScripts/PathToolController.py
|
||||
PathScripts/PathToolControllerGui.py
|
||||
PathScripts/PathToolEdit.py
|
||||
PathScripts/PathToolLibraryManager.py
|
||||
PathScripts/PathToolLibraryEditor.py
|
||||
PathScripts/PathToolLibraryManager.py
|
||||
PathScripts/PathUtil.py
|
||||
PathScripts/PathUtils.py
|
||||
PathScripts/PathUtilsGui.py
|
||||
PathScripts/PathSimulatorGui.py
|
||||
PathScripts/PathWaterline.py
|
||||
PathScripts/PathWaterlineGui.py
|
||||
PathScripts/PostUtils.py
|
||||
PathScripts/PathAdaptiveGui.py
|
||||
PathScripts/PathAdaptive.py
|
||||
PathScripts/__init__.py
|
||||
)
|
||||
|
||||
@@ -128,6 +133,7 @@ SET(PathScripts_post_SRCS
|
||||
PathScripts/post/comparams_post.py
|
||||
PathScripts/post/dynapath_post.py
|
||||
PathScripts/post/example_pre.py
|
||||
PathScripts/post/gcode_pre.py
|
||||
PathScripts/post/grbl_post.py
|
||||
PathScripts/post/jtech_post.py
|
||||
PathScripts/post/linuxcnc_post.py
|
||||
@@ -188,8 +194,8 @@ SET(PathTests_SRCS
|
||||
PathTests/boxtest.fcstd
|
||||
PathTests/test_centroid_00.ngc
|
||||
PathTests/test_geomop.fcstd
|
||||
PathTests/test_linuxcnc_00.ngc
|
||||
PathTests/test_holes00.fcstd
|
||||
PathTests/test_linuxcnc_00.ngc
|
||||
)
|
||||
|
||||
SET(PathImages_Ops
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>icons/Path-Adaptive.svg</file>
|
||||
<file>icons/Path-ToolDuplicate.svg</file>
|
||||
<file>icons/Path-3DPocket.svg</file>
|
||||
<file>icons/Path-3DSurface.svg</file>
|
||||
<file>icons/Path-Area-View.svg</file>
|
||||
<file>icons/Path-Area-Workplane.svg</file>
|
||||
<file>icons/Path-Area.svg</file>
|
||||
<file>icons/Path-Array.svg</file>
|
||||
<file>icons/Path-Axis.svg</file>
|
||||
<file>icons/Path-BFastForward.svg</file>
|
||||
<file>icons/Path-BPause.svg</file>
|
||||
<file>icons/Path-BPlay.svg</file>
|
||||
<file>icons/Path-BStep.svg</file>
|
||||
<file>icons/Path-BStop.svg</file>
|
||||
<file>icons/Path-BaseGeometry.svg</file>
|
||||
<file>icons/Path-Comment.svg</file>
|
||||
<file>icons/Path-Compound.svg</file>
|
||||
@@ -17,9 +27,9 @@
|
||||
<file>icons/Path-Drilling.svg</file>
|
||||
<file>icons/Path-Engrave.svg</file>
|
||||
<file>icons/Path-ExportTemplate.svg</file>
|
||||
<file>icons/Path-Face.svg</file>
|
||||
<file>icons/Path-FacePocket.svg</file>
|
||||
<file>icons/Path-FaceProfile.svg</file>
|
||||
<file>icons/Path-Face.svg</file>
|
||||
<file>icons/Path-Heights.svg</file>
|
||||
<file>icons/Path-Helix.svg</file>
|
||||
<file>icons/Path-Hop.svg</file>
|
||||
@@ -27,16 +37,17 @@
|
||||
<file>icons/Path-Job.svg</file>
|
||||
<file>icons/Path-Kurve.svg</file>
|
||||
<file>icons/Path-LengthOffset.svg</file>
|
||||
<file>icons/Path-Machine.svg</file>
|
||||
<file>icons/Path-MachineLathe.svg</file>
|
||||
<file>icons/Path-MachineMill.svg</file>
|
||||
<file>icons/Path-Machine.svg</file>
|
||||
<file>icons/Path-OpActive.svg</file>
|
||||
<file>icons/Path-OpCopy.svg</file>
|
||||
<file>icons/Path-OperationA.svg</file>
|
||||
<file>icons/Path-OperationB.svg</file>
|
||||
<file>icons/Path-OpCopy.svg</file>
|
||||
<file>icons/Path-Plane.svg</file>
|
||||
<file>icons/Path-Pocket.svg</file>
|
||||
<file>icons/Path-Post.svg</file>
|
||||
<file>icons/Path-Probe.svg</file>
|
||||
<file>icons/Path-Profile-Edges.svg</file>
|
||||
<file>icons/Path-Profile-Face.svg</file>
|
||||
<file>icons/Path-Profile.svg</file>
|
||||
@@ -45,49 +56,40 @@
|
||||
<file>icons/Path-SetupSheet.svg</file>
|
||||
<file>icons/Path-Shape.svg</file>
|
||||
<file>icons/Path-SimpleCopy.svg</file>
|
||||
<file>icons/Path-Simulator.svg</file>
|
||||
<file>icons/Path-Speed.svg</file>
|
||||
<file>icons/Path-Stock.svg</file>
|
||||
<file>icons/Path-Stop.svg</file>
|
||||
<file>icons/Path-ToolBit.svg</file>
|
||||
<file>icons/Path-ToolChange.svg</file>
|
||||
<file>icons/Path-ToolController.svg</file>
|
||||
<file>icons/Path-ToolDuplicate.svg</file>
|
||||
<file>icons/Path-Toolpath.svg</file>
|
||||
<file>icons/Path-ToolTable.svg</file>
|
||||
<file>icons/Path-Area.svg</file>
|
||||
<file>icons/Path-Area-View.svg</file>
|
||||
<file>icons/Path-Area-Workplane.svg</file>
|
||||
<file>icons/Path-Simulator.svg</file>
|
||||
<file>icons/Path-BFastForward.svg</file>
|
||||
<file>icons/Path-BPause.svg</file>
|
||||
<file>icons/Path-BPlay.svg</file>
|
||||
<file>icons/Path-BStep.svg</file>
|
||||
<file>icons/Path-BStop.svg</file>
|
||||
<file>icons/Path-Waterline.svg</file>
|
||||
<file>icons/arrow-ccw.svg</file>
|
||||
<file>icons/arrow-cw.svg</file>
|
||||
<file>icons/arrow-down.svg</file>
|
||||
<file>icons/arrow-left.svg</file>
|
||||
<file>icons/arrow-left-down.svg</file>
|
||||
<file>icons/arrow-left-up.svg</file>
|
||||
<file>icons/arrow-right.svg</file>
|
||||
<file>icons/arrow-left.svg</file>
|
||||
<file>icons/arrow-right-down.svg</file>
|
||||
<file>icons/arrow-right-up.svg</file>
|
||||
<file>icons/arrow-right.svg</file>
|
||||
<file>icons/arrow-up.svg</file>
|
||||
<file>icons/edge-join-miter.svg</file>
|
||||
<file>icons/edge-join-miter-not.svg</file>
|
||||
<file>icons/edge-join-round.svg</file>
|
||||
<file>icons/edge-join-miter.svg</file>
|
||||
<file>icons/edge-join-round-not.svg</file>
|
||||
<file>icons/edge-join-round.svg</file>
|
||||
<file>icons/preferences-path.svg</file>
|
||||
<file>icons/Path-Adaptive.svg</file>
|
||||
<file>panels/DlgJobChooser.ui</file>
|
||||
<file>panels/DlgJobCreate.ui</file>
|
||||
<file>panels/DlgJobModelSelect.ui</file>
|
||||
<file>panels/DlgJobTemplateExport.ui</file>
|
||||
<file>panels/DlgSelectPostProcessor.ui</file>
|
||||
<file>panels/DlgTCChooser.ui</file>
|
||||
<file>panels/DlgToolControllerEdit.ui</file>
|
||||
<file>panels/DlgToolCopy.ui</file>
|
||||
<file>panels/DlgToolEdit.ui</file>
|
||||
<file>panels/DlgTCChooser.ui</file>
|
||||
<file>panels/DogboneEdit.ui</file>
|
||||
<file>panels/DressupPathBoundary.ui</file>
|
||||
<file>panels/HoldingTagsEdit.ui</file>
|
||||
@@ -102,8 +104,10 @@
|
||||
<file>panels/PageOpHelixEdit.ui</file>
|
||||
<file>panels/PageOpPocketExtEdit.ui</file>
|
||||
<file>panels/PageOpPocketFullEdit.ui</file>
|
||||
<file>panels/PageOpProbeEdit.ui</file>
|
||||
<file>panels/PageOpProfileFullEdit.ui</file>
|
||||
<file>panels/PageOpSurfaceEdit.ui</file>
|
||||
<file>panels/PageOpWaterlineEdit.ui</file>
|
||||
<file>panels/PathEdit.ui</file>
|
||||
<file>panels/PointEdit.ui</file>
|
||||
<file>panels/SetupGlobal.ui</file>
|
||||
@@ -114,19 +118,29 @@
|
||||
<file>panels/ToolEditor.ui</file>
|
||||
<file>panels/ToolLibraryEditor.ui</file>
|
||||
<file>panels/TaskPathSimulator.ui</file>
|
||||
<file>panels/ZCorrectEdit.ui</file>
|
||||
<file>preferences/PathDressupHoldingTags.ui</file>
|
||||
<file>preferences/PathJob.ui</file>
|
||||
<file>translations/Path_af.qm</file>
|
||||
<file>translations/Path_ar.qm</file>
|
||||
<file>translations/Path_ca.qm</file>
|
||||
<file>translations/Path_cs.qm</file>
|
||||
<file>translations/Path_de.qm</file>
|
||||
<file>translations/Path_el.qm</file>
|
||||
<file>translations/Path_es-ES.qm</file>
|
||||
<file>translations/Path_eu.qm</file>
|
||||
<file>translations/Path_fi.qm</file>
|
||||
<file>translations/Path_fil.qm</file>
|
||||
<file>translations/Path_fr.qm</file>
|
||||
<file>translations/Path_gl.qm</file>
|
||||
<file>translations/Path_hr.qm</file>
|
||||
<file>translations/Path_hu.qm</file>
|
||||
<file>translations/Path_id.qm</file>
|
||||
<file>translations/Path_it.qm</file>
|
||||
<file>translations/Path_ja.qm</file>
|
||||
<file>translations/Path_kab.qm</file>
|
||||
<file>translations/Path_ko.qm</file>
|
||||
<file>translations/Path_lt.qm</file>
|
||||
<file>translations/Path_nl.qm</file>
|
||||
<file>translations/Path_no.qm</file>
|
||||
<file>translations/Path_pl.qm</file>
|
||||
@@ -140,18 +154,9 @@
|
||||
<file>translations/Path_sv-SE.qm</file>
|
||||
<file>translations/Path_tr.qm</file>
|
||||
<file>translations/Path_uk.qm</file>
|
||||
<file>translations/Path_val-ES.qm</file>
|
||||
<file>translations/Path_vi.qm</file>
|
||||
<file>translations/Path_zh-CN.qm</file>
|
||||
<file>translations/Path_zh-TW.qm</file>
|
||||
<file>translations/Path_eu.qm</file>
|
||||
<file>translations/Path_ca.qm</file>
|
||||
<file>translations/Path_gl.qm</file>
|
||||
<file>translations/Path_kab.qm</file>
|
||||
<file>translations/Path_ko.qm</file>
|
||||
<file>translations/Path_fil.qm</file>
|
||||
<file>translations/Path_id.qm</file>
|
||||
<file>translations/Path_lt.qm</file>
|
||||
<file>translations/Path_val-ES.qm</file>
|
||||
<file>translations/Path_ar.qm</file>
|
||||
<file>translations/Path_vi.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
666
src/Mod/Path/Gui/Resources/icons/Path-Probe.svg
Normal file
666
src/Mod/Path/Gui/Resources/icons/Path-Probe.svg
Normal file
@@ -0,0 +1,666 @@
|
||||
<?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-Probe.svg">
|
||||
<defs
|
||||
id="defs2818">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient4030">
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop4032" />
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4034" />
|
||||
</linearGradient>
|
||||
<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" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4031"
|
||||
id="linearGradient4055"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(71.494719,-3.1982556)"
|
||||
x1="30.000002"
|
||||
y1="7.9999995"
|
||||
x2="36"
|
||||
y2="54.227272" />
|
||||
<linearGradient
|
||||
id="linearGradient4031">
|
||||
<stop
|
||||
id="stop4033"
|
||||
offset="0"
|
||||
style="stop-color:#d3d7cf;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop4035"
|
||||
offset="1"
|
||||
style="stop-color:#888a85;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4030"
|
||||
id="linearGradient4036"
|
||||
x1="35"
|
||||
y1="60"
|
||||
x2="24"
|
||||
y2="24"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.0109162,0,0,0.46203172,-0.34931964,34.132636)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3898-8-9">
|
||||
<stop
|
||||
style="stop-color:#888a85;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3900-2-2" />
|
||||
<stop
|
||||
style="stop-color:#d3d7cf;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3902-4-7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3898-8-9"
|
||||
id="linearGradient3145"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="35.05999"
|
||||
y1="53.008698"
|
||||
x2="27.286415"
|
||||
y2="7.311924"
|
||||
gradientTransform="matrix(0.98188305,0,0,0.84420947,9.5797362,-5.207764)" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="9.57"
|
||||
inkscape:cx="35.419385"
|
||||
inkscape:cy="28.985505"
|
||||
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="1676"
|
||||
inkscape:window-height="1011"
|
||||
inkscape:window-x="1080"
|
||||
inkscape:window-y="18"
|
||||
inkscape:window-maximized="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3206"
|
||||
empspacing="2"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<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>
|
||||
<dc:title>Path-Drilling</dc:title>
|
||||
<dc:date>2015-07-04</dc:date>
|
||||
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Path/Gui/Resources/icons/Path-Drilling.svg</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g4316">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect3085"
|
||||
d="m 2.6834291,45.683429 0,16.633142 58.6331419,0 0,-16.633142 c 0,0 -3.143696,0 -58.6331419,0 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient4036);fill-opacity:1;fill-rule:nonzero;stroke:#0b1521;stroke-width:1.36685824;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="rect3085-7"
|
||||
d="m 4.0668882,47.121868 0,13.756264 55.8662238,0 0,-13.756264 z"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#729fcf;stroke-width:1.33377635;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#172a04;stroke-width:5.94895172;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 41,39.98955 41,13.945451"
|
||||
id="path3111"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#ffe300;stroke-width:2.97447586;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 41,40.044099 41,14"
|
||||
id="path3111-3"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<path
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffff00;stroke:#ffff00;stroke-width:1.48723793;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 40.256381,40.022049 0,-26.044099"
|
||||
id="path3111-3-6"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<circle
|
||||
style="fill:#ff0000;fill-opacity:1;stroke:#000000;stroke-width:1.3;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:1.20000005;stroke-opacity:1"
|
||||
id="path4263"
|
||||
cx="41"
|
||||
cy="41.044098"
|
||||
r="4" />
|
||||
<g
|
||||
id="g4311">
|
||||
<g
|
||||
transform="matrix(1.0125004,0,0,1.0096719,6.4745258,6.0042826)"
|
||||
id="g4251">
|
||||
<path
|
||||
style="fill:none;stroke:#d3d7cf;stroke-width:1.84549868;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="M 26.982514,0.44587399 27,9 41,9 41.102863,0.44587399 Z"
|
||||
id="path3906-7-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3085-5-3"
|
||||
d="m 31.999995,17 -0.07736,-12.0772507 18.154729,0 L 49.999995,17 Z"
|
||||
style="fill:url(#linearGradient3145);fill-opacity:1;stroke:#2e3436;stroke-width:1.84549868;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 23 KiB |
281
src/Mod/Path/Gui/Resources/icons/Path-Waterline.svg
Normal file
281
src/Mod/Path/Gui/Resources/icons/Path-Waterline.svg
Normal file
@@ -0,0 +1,281 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
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.92.4 (5da689c313, 2019-01-14)"
|
||||
sodipodi:docname="Path-Waterline.svg">
|
||||
<title
|
||||
id="title165">Path_Waterline</title>
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1304"
|
||||
inkscape:window-height="745"
|
||||
id="namedview32"
|
||||
showgrid="true"
|
||||
inkscape:snap-bbox="false"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:snap-global="false"
|
||||
inkscape:zoom="8.0000004"
|
||||
inkscape:cx="17.234266"
|
||||
inkscape:cy="29.588719"
|
||||
inkscape:window-x="54"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer1">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3009"
|
||||
empspacing="2"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs2818">
|
||||
<linearGradient
|
||||
id="linearGradient6899"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#074cff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6901" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient6887"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#074cff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6889" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4668"
|
||||
osb:paint="gradient">
|
||||
<stop
|
||||
style="stop-color:#009b00;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4670" />
|
||||
<stop
|
||||
style="stop-color:#009b00;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop4672" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4662"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#008000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4664" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4529"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#0047ff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4531" />
|
||||
</linearGradient>
|
||||
<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>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient4513"
|
||||
id="radialGradient3132"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.39497909,0,0,1.1841158,-76.294432,-34.372515)"
|
||||
cx="32.151962"
|
||||
cy="27.950663"
|
||||
fx="32.151962"
|
||||
fy="27.950663"
|
||||
r="23.634638" />
|
||||
<linearGradient
|
||||
id="linearGradient4031">
|
||||
<stop
|
||||
id="stop4033"
|
||||
offset="0"
|
||||
style="stop-color:#d3d7cf;stop-opacity:1" />
|
||||
<stop
|
||||
id="stop4035"
|
||||
offset="1"
|
||||
style="stop-color:#888a85;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3797">
|
||||
<stop
|
||||
style="stop-color:#729fcf;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3799" />
|
||||
<stop
|
||||
style="stop-color:#204a87;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3801" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient4513"
|
||||
id="radialGradient3132-4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.39497909,0,0,1.1841158,-76.294432,-34.372515)"
|
||||
cx="32.151962"
|
||||
cy="27.950663"
|
||||
fx="32.151962"
|
||||
fy="27.950663"
|
||||
r="23.634638" />
|
||||
<radialGradient
|
||||
xlink:href="#linearGradient3797"
|
||||
id="radialGradient3805"
|
||||
cx="16.46319"
|
||||
cy="23.895996"
|
||||
fx="16.46319"
|
||||
fy="23.895996"
|
||||
r="18.501005"
|
||||
gradientTransform="matrix(0.80330389,1.0328193,-1.4593803,1.1350735,42.108301,-16.627212)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
xlink:href="#linearGradient4031"
|
||||
id="linearGradient4055"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(71.494719,-3.1982556)"
|
||||
x1="30.000002"
|
||||
y1="10"
|
||||
x2="36"
|
||||
y2="54.227272" />
|
||||
</defs>
|
||||
<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>Path_Waterline</dc:title>
|
||||
<dc:title>Path-Waterline</dc:title>
|
||||
<dc:date>2019-05-19</dc:date>
|
||||
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Path/Gui/Resources/icons/Path-Waterline.svg</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[russ4262] Russell Johnson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[russ4262] Russell Johnson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
style="display:inline;opacity:1">
|
||||
<g
|
||||
style="display:inline;opacity:1"
|
||||
id="g4358"
|
||||
transform="matrix(0.58483815,0,0,0.51339436,78.144089,14.290628)" />
|
||||
<circle
|
||||
r="17.5"
|
||||
cy="37.5"
|
||||
cx="29.4599"
|
||||
id="path4493"
|
||||
style="display:inline;opacity:0.97000002;fill:url(#radialGradient3805);fill-opacity:1;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<circle
|
||||
r="15.5"
|
||||
cy="37.5"
|
||||
cx="29.4599"
|
||||
id="path4493-1"
|
||||
style="display:inline;opacity:0.97000002;fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<g
|
||||
transform="matrix(0.58483815,0,0,0.51339436,71.618929,23.569677)"
|
||||
id="g4358-4"
|
||||
style="display:inline;opacity:1" />
|
||||
<circle
|
||||
style="display:inline;opacity:0.97000002;fill:none;stroke:#729fcf;stroke-width:2;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="circle4822"
|
||||
cx="29.4599"
|
||||
cy="37.5"
|
||||
r="15.5" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="circle4734"
|
||||
d="m 43.012901,20.993607 a 17.5,17.5 0 0 1 -13.197266,6.03125 17.5,17.5 0 0 1 -13.048828,-5.900391 21.189749,21.189749 0 0 0 -4.238281,4.552735 23.697439,23.697439 0 0 0 17.46289,7.720703 23.697439,23.697439 0 0 0 17.435547,-7.720703 21.189749,21.189749 0 0 0 -4.414062,-4.683594 z"
|
||||
style="display:inline;opacity:1;fill:#1a1a1a;fill-opacity:1;stroke:#1a1a1a;stroke-width:2.70827866;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4737"
|
||||
d="m 8.731651,34.735794 a 21.189749,21.189749 0 0 0 -0.283203,3.294922 21.189749,21.189749 0 0 0 0.628906,5.039063 25.091324,11.279887 0 0 0 20.228515,4.626953 25.091324,11.279887 0 0 0 21.011719,-5.123047 21.189749,21.189749 0 0 0 0.509766,-4.542969 21.189749,21.189749 0 0 0 -0.191406,-2.634765 24.954107,14.861135 0 0 1 -20.623047,6.498046 24.954107,14.861135 0 0 1 -21.28125,-7.158203 z"
|
||||
style="opacity:1;fill:#1a1a1a;fill-opacity:1;stroke:#1a1a1a;stroke-width:1.89686728;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="circle4734-3"
|
||||
d="M 14.698516,22.688476 A 21.189749,21.189749 0 0 0 12.72,25.067383 24.982393,24.982393 0 0 0 29.452422,31.606445 24.982393,24.982393 0 0 0 46.862578,24.489258 21.189749,21.189749 0 0 0 45.337188,22.696289 21.8059,21.8059 0 0 1 30.026641,29.05957 21.8059,21.8059 0 0 1 14.698516,22.688476 Z"
|
||||
style="display:inline;opacity:1;fill:#73d216;fill-opacity:1;stroke:#1a1a1a;stroke-width:0;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4835"
|
||||
d="m 8.1302074,37.508398 a 21.189749,21.189749 0 0 0 -0.035156,0.962891 21.189749,21.189749 0 0 0 0.109374,2.058594 28.746413,17.1196 0 0 0 21.7109376,5.976562 28.746413,17.1196 0 0 0 20.310547,-5.021484 21.189749,21.189749 0 0 0 0.248047,-3.001953 28.904483,18.541831 0 0 1 -20.488282,5.484375 28.904483,18.541831 0 0 1 -21.8554676,-6.458985 z"
|
||||
style="opacity:1;fill:#73d216;fill-opacity:1;stroke:#00ff00;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="circle4734-3-9"
|
||||
d="m 15.509519,21.31383 a 21.189749,21.189749 0 0 0 -1.978516,2.378907 24.982393,24.982393 0 0 0 16.732422,6.539062 24.982393,24.982393 0 0 0 17.410156,-7.117187 21.189749,21.189749 0 0 0 -1.52539,-1.792969 21.8059,21.8059 0 0 1 -15.310547,6.363281 21.8059,21.8059 0 0 1 -15.328125,-6.371094 z"
|
||||
style="display:inline;opacity:1;fill:#8ae234;fill-opacity:1;stroke:#1a1a1a;stroke-width:0;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4835-0"
|
||||
d="m 8.1959236,36.208398 a 21.189749,21.189749 0 0 0 -0.03516,0.962891 21.189749,21.189749 0 0 0 0.109374,2.058594 28.746413,17.1196 0 0 0 21.7109374,5.976562 28.746413,17.1196 0 0 0 20.310548,-5.021484 21.189749,21.189749 0 0 0 0.248047,-3.001953 28.904483,18.541831 0 0 1 -20.488283,5.484375 28.904483,18.541831 0 0 1 -21.8554674,-6.458985 z"
|
||||
style="display:inline;opacity:1;fill:#8ae234;fill-opacity:1;stroke:#00ff00;stroke-width:0;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<g
|
||||
transform="matrix(0.66585367,0,0,0.65271967,-19.339925,4.6218574)"
|
||||
id="g4051">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient4055);fill-opacity:1;fill-rule:nonzero;stroke:#2e3436;stroke-width:3.03373241;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 94.494721,6.8017444 -0.01099,27.5961536 18.021979,-7.660256 -0.011,-19.9358976 z M 112.49472,29.801744 94.483731,37.462 l 0.01099,8.339744 17.999999,-8 z m 0.011,10.724359 -16.520148,7.660256 7.509158,4.615385 9,-5 z"
|
||||
id="rect4417-3" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#d3d7cf;stroke-width:3.03373241;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 97.487394,9.8850776 V 29.753867 l 11.991186,-5.098858 0.0235,-14.7699314 z m 12.014656,24.5647544 -11.989201,5.01406 v 1.711385 l 11.963741,-5.40113 z m 0.0452,10.829611 -7.19513,3.327881 1.20492,0.808046 5.9895,-3.408611 z"
|
||||
id="rect4417-1" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>572</width>
|
||||
<height>419</height>
|
||||
<width>454</width>
|
||||
<height>386</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -154,6 +154,37 @@
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="6">
|
||||
<widget class="QComboBox" name="enableRotation">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Off</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>A(x)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>B(y)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>A & B</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="4">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Enable Rotation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
186
src/Mod/Path/Gui/Resources/panels/PageOpProbeEdit.ui
Normal file
186
src/Mod/Path/Gui/Resources/panels/PageOpProbeEdit.ui
Normal file
@@ -0,0 +1,186 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>424</width>
|
||||
<height>376</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>ToolController</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="toolController">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The tool and its settings to be used for this operation.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Probe Grid Points</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="PointCountX">
|
||||
<property name="minimum">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="4">
|
||||
<widget class="QSpinBox" name="PointCountY">
|
||||
<property name="minimum">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Probe</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Y Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::InputField" name="Yoffset">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>X Offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::InputField" name="Xoffset">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Output</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>File Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="OutputFileName">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enter the filename where the probe points should be written.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>ProbePoints.txt</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="SetOutputFileName">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>357</width>
|
||||
<height>427</height>
|
||||
<width>350</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -24,7 +24,7 @@
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<widget class="QLabel" name="toolController_label">
|
||||
<property name="text">
|
||||
<string>ToolController</string>
|
||||
</property>
|
||||
@@ -38,7 +38,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<widget class="QLabel" name="coolantController_label">
|
||||
<property name="text">
|
||||
<string>Coolant Mode</string>
|
||||
</property>
|
||||
@@ -57,126 +57,35 @@
|
||||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Algorithm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="algorithmSelect">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>OCL Dropcutter</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>OCL Waterline</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>BoundBox</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="boundBoxSelect">
|
||||
<widget class="QComboBox" name="scanType">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stock</string>
|
||||
<string>Planar</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>BaseBoundBox</string>
|
||||
<string>Rotational</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>BoundBox extra offset X, Y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::InputField" name="boundBoxExtraOffsetX" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="Gui::InputField" name="boundBoxExtraOffsetY" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Drop Cutter Direction</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="dropCutterDirSelect">
|
||||
<item row="2" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="layerMode">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
<string>Single-pass</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Y</string>
|
||||
<string>Multi-pass</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Depth offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<widget class="Gui::InputField" name="depthOffset" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Sample interval</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<widget class="Gui::InputField" name="sampleInterval" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Step over</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<item row="8" column="1" colspan="2">
|
||||
<widget class="QSpinBox" name="stepOver">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The amount by which the tool is laterally displaced on each cycle of the pattern, specified in percent of the tool diameter.</p><p>A step over of 100% results in no overlap between two different cycles.</p></body></html></string>
|
||||
@@ -195,20 +104,180 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="stepOver_label">
|
||||
<property name="text">
|
||||
<string>Optimize output</string>
|
||||
<string>Step over</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="sampleInterval_label">
|
||||
<property name="text">
|
||||
<string>Sample interval</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="layerMode_label">
|
||||
<property name="text">
|
||||
<string>Layer Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QCheckBox" name="optimizeEnabled">
|
||||
<property name="text">
|
||||
<string>Optimize Linear Paths</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="dropCutterDirSelect_label">
|
||||
<property name="text">
|
||||
<string>Drop Cutter Direction</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="boundBoxExtraOffset_label">
|
||||
<property name="text">
|
||||
<string>BoundBox extra offset X, Y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QCheckBox" name="useStartPoint">
|
||||
<property name="text">
|
||||
<string>Use Start Point</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="scanType_label">
|
||||
<property name="text">
|
||||
<string>Scan Type</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="boundBoxSelect_label">
|
||||
<property name="text">
|
||||
<string>BoundBox</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1" colspan="2">
|
||||
<widget class="QCheckBox" name="optimizeEnabled">
|
||||
<property name="text">
|
||||
<string>Enabled</string>
|
||||
<widget class="Gui::InputField" name="depthOffset" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="Gui::InputField" name="boundBoxExtraOffsetX" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::InputField" name="boundBoxExtraOffsetY" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="10" column="1" colspan="2">
|
||||
<widget class="Gui::InputField" name="sampleInterval" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="depthOffset_label">
|
||||
<property name="text">
|
||||
<string>Depth offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="dropCutterDirSelect">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>X</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Y</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="boundBoxSelect">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stock</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>BaseBoundBox</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QCheckBox" name="optimizeStepOverTransitions">
|
||||
<property name="text">
|
||||
<string>Optimize StepOver Transitions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="cutPattern_label">
|
||||
<property name="text">
|
||||
<string>Cut Pattern</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="cutPattern">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Line</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ZigZag</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Circular</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CircularZigZag</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
269
src/Mod/Path/Gui/Resources/panels/PageOpWaterlineEdit.ui
Normal file
269
src/Mod/Path/Gui/Resources/panels/PageOpWaterlineEdit.ui
Normal file
@@ -0,0 +1,269 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>350</width>
|
||||
<height>400</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>ToolController</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="toolController">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The tool and its settings to be used for this operation.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="3">
|
||||
<widget class="QComboBox" name="boundBoxSelect">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Stock</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>BaseBoundBox</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QLineEdit" name="boundaryAdjustment">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QComboBox" name="layerMode">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Single-pass</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Multi-pass</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="algorithmSelect">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>OCL Dropcutter</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Experimental</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="3">
|
||||
<widget class="QCheckBox" name="optimizeEnabled">
|
||||
<property name="text">
|
||||
<string>Optimize Linear Paths</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="boundaryAdjustment_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Boundary Adjustment</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QComboBox" name="cutPattern">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>None</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Line</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>ZigZag</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Circular</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>CircularZigZag</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="3">
|
||||
<widget class="QSpinBox" name="stepOver">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>The amount by which the tool is laterally displaced on each cycle of the pattern, specified in percent of the tool diameter.</p><p>A step over of 100% results in no overlap between two different cycles.</p></body></html></string>
|
||||
</property>
|
||||
<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>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="layerMode_label">
|
||||
<property name="text">
|
||||
<string>Layer Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="boundBoxSelect_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>BoundBox</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="stepOver_label">
|
||||
<property name="text">
|
||||
<string>Step over</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="3">
|
||||
<widget class="Gui::InputField" name="sampleInterval" native="true">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="cutPattern_label">
|
||||
<property name="text">
|
||||
<string>Cut Pattern</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="sampleInterval_label">
|
||||
<property name="text">
|
||||
<string>Sample interval</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="algorithmSelect_label">
|
||||
<property name="text">
|
||||
<string>Algorithm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>QWidget</extends>
|
||||
<header>gui::inputfield.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
92
src/Mod/Path/Gui/Resources/panels/ZCorrectEdit.ui
Normal file
92
src/Mod/Path/Gui/Resources/panels/ZCorrectEdit.ui
Normal file
@@ -0,0 +1,92 @@
|
||||
<?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>376</width>
|
||||
<height>387</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Z Depth Correction</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="Dressup">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>358</width>
|
||||
<height>340</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Dressup</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Probe Points File</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="2">
|
||||
<widget class="QToolButton" name="SetProbePointFileName">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>File Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLineEdit" name="ProbePointFileName">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Enter the filename containing the probe data</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" 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>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -21,8 +21,9 @@
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
|
||||
class PathCommandGroup:
|
||||
def __init__(self, cmdlist, menu, tooltip = None):
|
||||
def __init__(self, cmdlist, menu, tooltip=None):
|
||||
self.cmdlist = cmdlist
|
||||
self.menu = menu
|
||||
if tooltip is None:
|
||||
@@ -34,7 +35,7 @@ class PathCommandGroup:
|
||||
return tuple(self.cmdlist)
|
||||
|
||||
def GetResources(self):
|
||||
return { 'MenuText': self.menu, 'ToolTip': self.tooltip }
|
||||
return {'MenuText': self.menu, 'ToolTip': self.tooltip}
|
||||
|
||||
def IsActive(self):
|
||||
if FreeCAD.ActiveDocument is not None:
|
||||
@@ -43,6 +44,7 @@ class PathCommandGroup:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class PathWorkbench (Workbench):
|
||||
"Path workbench"
|
||||
|
||||
@@ -87,15 +89,15 @@ class PathWorkbench (Workbench):
|
||||
# build commands list
|
||||
projcmdlist = ["Path_Job", "Path_Post"]
|
||||
toolcmdlist = ["Path_Inspect", "Path_Simulator", "Path_ToolLibraryEdit", "Path_SelectLoop", "Path_OpActiveToggle"]
|
||||
prepcmdlist = ["Path_Fixture", "Path_Comment", "Path_Stop", "Path_Custom"]
|
||||
twodopcmdlist = ["Path_Contour", "Path_Profile_Faces", "Path_Profile_Edges", "Path_Pocket_Shape", "Path_Drilling", "Path_MillFace", "Path_Helix", "Path_Adaptive" ]
|
||||
prepcmdlist = ["Path_Fixture", "Path_Comment", "Path_Stop", "Path_Custom", "Path_Probe"]
|
||||
twodopcmdlist = ["Path_Contour", "Path_Profile_Faces", "Path_Profile_Edges", "Path_Pocket_Shape", "Path_Drilling", "Path_MillFace", "Path_Helix", "Path_Adaptive"]
|
||||
threedopcmdlist = ["Path_Pocket_3D"]
|
||||
engravecmdlist = ["Path_Engrave", "Path_Deburr"]
|
||||
modcmdlist = ["Path_OperationCopy", "Path_Array", "Path_SimpleCopy" ]
|
||||
dressupcmdlist = ["Path_DressupAxisMap", "Path_DressupPathBoundary", "Path_DressupDogbone", "Path_DressupDragKnife", "Path_DressupLeadInOut", "Path_DressupRampEntry", "Path_DressupTag"]
|
||||
modcmdlist = ["Path_OperationCopy", "Path_Array", "Path_SimpleCopy"]
|
||||
dressupcmdlist = ["Path_DressupAxisMap", "Path_DressupPathBoundary", "Path_DressupDogbone", "Path_DressupDragKnife", "Path_DressupLeadInOut", "Path_DressupRampEntry", "Path_DressupTag", "Path_DressupZCorrect"]
|
||||
extracmdlist = []
|
||||
#modcmdmore = ["Path_Hop",]
|
||||
#remotecmdlist = ["Path_Remote"]
|
||||
# modcmdmore = ["Path_Hop",]
|
||||
# remotecmdlist = ["Path_Remote"]
|
||||
|
||||
engravecmdgroup = ['Path_EngraveTools']
|
||||
FreeCADGui.addCommand('Path_EngraveTools', PathCommandGroup(engravecmdlist, QtCore.QT_TRANSLATE_NOOP("Path", 'Engraving Operations')))
|
||||
@@ -107,11 +109,12 @@ class PathWorkbench (Workbench):
|
||||
extracmdlist.extend(["Path_Area", "Path_Area_Workplane"])
|
||||
|
||||
try:
|
||||
import ocl # pylint: disable=unused-variable
|
||||
import ocl # pylint: disable=unused-variable
|
||||
from PathScripts import PathSurfaceGui
|
||||
threedopcmdlist.append("Path_Surface")
|
||||
from PathScripts import PathWaterlineGui
|
||||
threedopcmdlist.extend(["Path_Surface", "Path_Waterline"])
|
||||
threedcmdgroup = ['Path_3dTools']
|
||||
FreeCADGui.addCommand('Path_3dTools', PathCommandGroup(threedopcmdlist, QtCore.QT_TRANSLATE_NOOP("Path",'3D Operations')))
|
||||
FreeCADGui.addCommand('Path_3dTools', PathCommandGroup(threedopcmdlist, QtCore.QT_TRANSLATE_NOOP("Path", '3D Operations')))
|
||||
except ImportError:
|
||||
FreeCAD.Console.PrintError("OpenCamLib is not working!\n")
|
||||
|
||||
@@ -122,7 +125,9 @@ class PathWorkbench (Workbench):
|
||||
if extracmdlist:
|
||||
self.appendToolbar(QtCore.QT_TRANSLATE_NOOP("Path", "Helpful Tools"), extracmdlist)
|
||||
|
||||
self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path")], projcmdlist +["Path_ExportTemplate", "Separator"] + toolbitcmdlist + toolcmdlist +["Separator"] + twodopcmdlist + engravecmdlist +["Separator"] +threedopcmdlist +["Separator"])
|
||||
self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path")], projcmdlist + ["Path_ExportTemplate", "Separator"] +
|
||||
toolbitcmdlist + toolcmdlist + ["Separator"] + twodopcmdlist + engravecmdlist + ["Separator"] +
|
||||
threedopcmdlist + ["Separator"])
|
||||
self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path"), QtCore.QT_TRANSLATE_NOOP(
|
||||
"Path", "Path Dressup")], dressupcmdlist)
|
||||
self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path"), QtCore.QT_TRANSLATE_NOOP(
|
||||
@@ -136,7 +141,7 @@ class PathWorkbench (Workbench):
|
||||
|
||||
curveAccuracy = PathPreferences.defaultLibAreaCurveAccuracy()
|
||||
if curveAccuracy:
|
||||
Path.Area.setDefaultParams(Accuracy = curveAccuracy)
|
||||
Path.Area.setDefaultParams(Accuracy=curveAccuracy)
|
||||
|
||||
Log('Loading Path workbench... done\n')
|
||||
|
||||
@@ -171,8 +176,8 @@ class PathWorkbench (Workbench):
|
||||
if obj.isDerivedFrom("Path::Feature"):
|
||||
if "Profile" in selectedName or "Contour" in selectedName or "Dressup" in selectedName:
|
||||
self.appendContextMenu("", "Separator")
|
||||
#self.appendContextMenu("", ["Set_StartPoint"])
|
||||
#self.appendContextMenu("", ["Set_EndPoint"])
|
||||
# self.appendContextMenu("", ["Set_StartPoint"])
|
||||
# self.appendContextMenu("", ["Set_EndPoint"])
|
||||
for cmd in self.dressupcmds:
|
||||
self.appendContextMenu("", [cmd])
|
||||
menuAppended = True
|
||||
@@ -182,10 +187,10 @@ class PathWorkbench (Workbench):
|
||||
if menuAppended:
|
||||
self.appendContextMenu("", "Separator")
|
||||
|
||||
|
||||
Gui.addWorkbench(PathWorkbench())
|
||||
|
||||
FreeCAD.addImportType(
|
||||
"GCode (*.nc *.gc *.ncc *.ngc *.cnc *.tap *.gcode)", "PathGui")
|
||||
# FreeCAD.addExportType(
|
||||
# "GCode (*.nc *.gc *.ncc *.ngc *.cnc *.tap *.gcode)", "PathGui")
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2017 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * Copyright (c) 2020 russ4262 (Russell Johnson) *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -49,6 +48,7 @@ PathLog.setLevel(LOGLEVEL, PathLog.thisModule())
|
||||
if LOGLEVEL is PathLog.Level.DEBUG:
|
||||
PathLog.trackModule()
|
||||
|
||||
|
||||
# Qt translation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
@@ -66,7 +66,6 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
'''opFeatures(obj) ... returns the base features supported by all Path.Area based operations.
|
||||
The standard feature list is OR'ed with the return value of areaOpFeatures().
|
||||
Do not overwrite, implement areaOpFeatures(obj) instead.'''
|
||||
# return PathOp.FeatureTool | PathOp.FeatureDepths | PathOp.FeatureStepDown | PathOp.FeatureHeights | PathOp.FeatureStartPoint | self.areaOpFeatures(obj) | PathOp.FeatureRotation
|
||||
return PathOp.FeatureTool | PathOp.FeatureDepths | PathOp.FeatureStepDown | PathOp.FeatureHeights | PathOp.FeatureStartPoint | self.areaOpFeatures(obj) | PathOp.FeatureCoolant
|
||||
|
||||
def areaOpFeatures(self, obj):
|
||||
@@ -304,8 +303,6 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
pathParams['return_end'] = True
|
||||
# Note that emitting preambles between moves breaks some dressups and prevents path optimization on some controllers
|
||||
pathParams['preamble'] = False
|
||||
#if not self.areaOpRetractTool(obj):
|
||||
# pathParams['threshold'] = 2.001 * self.radius
|
||||
|
||||
if self.endVector is None:
|
||||
V = hWire.Wires[0].Vertexes
|
||||
@@ -374,12 +371,6 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
obj.ClearanceHeight.Value = strDep + self.clrOfset
|
||||
obj.SafeHeight.Value = strDep + self.safOfst
|
||||
|
||||
#if self.initWithRotation is False:
|
||||
# if obj.FinalDepth.Value == obj.OpFinalDepth.Value:
|
||||
# obj.FinalDepth.Value = finDep
|
||||
# if obj.StartDepth.Value == obj.OpStartDepth.Value:
|
||||
# obj.StartDepth.Value = strDep
|
||||
|
||||
# Create visual axes when debugging.
|
||||
if PathLog.getLevel(PathLog.thisModule()) == 4:
|
||||
self.visualAxis()
|
||||
@@ -467,10 +458,14 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
# Rotate Model to correct angle
|
||||
ppCmds.insert(0, Path.Command('G0', {axisOfRot: angle, 'F': self.axialRapid}))
|
||||
|
||||
# Raise cutter to safe depth and return index to starting position
|
||||
ppCmds.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))
|
||||
if axis != nextAxis:
|
||||
ppCmds.append(Path.Command('G0', {axisOfRot: 0.0, 'F': self.axialRapid}))
|
||||
# Raise cutter to safe height
|
||||
ppCmds.insert(0, Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))
|
||||
|
||||
# Return index to starting position if axis of rotation changes.
|
||||
if numShapes > 1:
|
||||
if ns != numShapes - 1:
|
||||
if axis != nextAxis:
|
||||
ppCmds.append(Path.Command('G0', {axisOfRot: 0.0, 'F': self.axialRapid}))
|
||||
# Eif
|
||||
|
||||
# Save gcode commands to object command list
|
||||
@@ -483,9 +478,43 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
|
||||
# Raise cutter to safe height and rotate back to original orientation
|
||||
if self.rotateFlag is True:
|
||||
resetAxis = False
|
||||
lastJobOp = None
|
||||
nextJobOp = None
|
||||
opIdx = 0
|
||||
JOB = PathUtils.findParentJob(obj)
|
||||
jobOps = JOB.Operations.Group
|
||||
numJobOps = len(jobOps)
|
||||
|
||||
for joi in range(0, numJobOps):
|
||||
jo = jobOps[joi]
|
||||
if jo.Name == obj.Name:
|
||||
opIdx = joi
|
||||
lastOpIdx = opIdx - 1
|
||||
nextOpIdx = opIdx + 1
|
||||
if lastOpIdx > -1:
|
||||
lastJobOp = jobOps[lastOpIdx]
|
||||
if nextOpIdx < numJobOps:
|
||||
nextJobOp = jobOps[nextOpIdx]
|
||||
|
||||
if lastJobOp is not None:
|
||||
if hasattr(lastJobOp, 'EnableRotation'):
|
||||
PathLog.debug('Last Op, {}, has `EnableRotation` set to {}'.format(lastJobOp.Label, lastJobOp.EnableRotation))
|
||||
if lastJobOp.EnableRotation != obj.EnableRotation:
|
||||
resetAxis = True
|
||||
if ns == numShapes - 1: # If last shape, check next op EnableRotation setting
|
||||
if nextJobOp is not None:
|
||||
if hasattr(nextJobOp, 'EnableRotation'):
|
||||
PathLog.debug('Next Op, {}, has `EnableRotation` set to {}'.format(nextJobOp.Label, nextJobOp.EnableRotation))
|
||||
if nextJobOp.EnableRotation != obj.EnableRotation:
|
||||
resetAxis = True
|
||||
|
||||
# Raise to safe height if rotation activated
|
||||
self.commandlist.append(Path.Command('G0', {'Z': obj.SafeHeight.Value, 'F': self.vertRapid}))
|
||||
self.commandlist.append(Path.Command('G0', {'A': 0.0, 'F': self.axialRapid}))
|
||||
self.commandlist.append(Path.Command('G0', {'B': 0.0, 'F': self.axialRapid}))
|
||||
# reset rotational axises if necessary
|
||||
if resetAxis is True:
|
||||
self.commandlist.append(Path.Command('G0', {'A': 0.0, 'F': self.axialRapid}))
|
||||
self.commandlist.append(Path.Command('G0', {'B': 0.0, 'F': self.axialRapid}))
|
||||
|
||||
self.useTempJobClones('Delete') # Delete temp job clone group and contents
|
||||
self.guiMessage('title', None, show=True) # Process GUI messages to user
|
||||
@@ -531,10 +560,8 @@ class ObjectOp(PathOp.ObjectOp):
|
||||
Determine rotational radii for 4th-axis rotations, for clearance/safe heights '''
|
||||
|
||||
parentJob = PathUtils.findParentJob(obj)
|
||||
# bb = parentJob.Stock.Shape.BoundBox
|
||||
xlim = 0.0
|
||||
ylim = 0.0
|
||||
# zlim = 0.0
|
||||
|
||||
# Determine boundbox radius based upon xzy limits data
|
||||
if math.fabs(self.stockBB.ZMin) > math.fabs(self.stockBB.ZMax):
|
||||
|
||||
@@ -25,9 +25,12 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
import Path
|
||||
from PySide import QtCore
|
||||
from copy import copy
|
||||
|
||||
|
||||
__doc__ = """Path Custom object and FreeCAD command"""
|
||||
|
||||
movecommands = ['G0', 'G00', 'G1', 'G01', 'G2', 'G02', 'G3', 'G03']
|
||||
|
||||
# Qt translation handling
|
||||
def translate(context, text, disambig=None):
|
||||
@@ -35,10 +38,14 @@ def translate(context, text, disambig=None):
|
||||
|
||||
|
||||
class ObjectCustom:
|
||||
def __init__(self, obj):
|
||||
obj.addProperty("App::PropertyStringList", "Gcode", "Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathCustom", "The gcode to be inserted"))
|
||||
obj.addProperty("App::PropertyLink", "ToolController", "Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathCustom", "The tool controller that will be used to calculate the path"))
|
||||
obj.addProperty("App::PropertyPlacement", "Offset", "Path",
|
||||
"Placement Offset")
|
||||
|
||||
def __init__(self,obj):
|
||||
obj.addProperty("App::PropertyStringList", "Gcode", "Path", QtCore.QT_TRANSLATE_NOOP("PathCustom", "The gcode to be inserted"))
|
||||
obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("PathCustom", "The tool controller that will be used to calculate the path"))
|
||||
obj.Proxy = self
|
||||
|
||||
def __getstate__(self):
|
||||
@@ -48,13 +55,22 @@ class ObjectCustom:
|
||||
return None
|
||||
|
||||
def execute(self, obj):
|
||||
newpath = Path.Path()
|
||||
if obj.Gcode:
|
||||
s = ""
|
||||
for l in obj.Gcode:
|
||||
s += str(l)
|
||||
if s:
|
||||
path = Path.Path(s)
|
||||
obj.Path = path
|
||||
newcommand = Path.Command(str(l))
|
||||
if newcommand.Name in movecommands:
|
||||
if 'X' in newcommand.Parameters:
|
||||
newcommand.x += obj.Offset.Base.x
|
||||
if 'Y' in newcommand.Parameters:
|
||||
newcommand.y += obj.Offset.Base.y
|
||||
if 'Z' in newcommand.Parameters:
|
||||
newcommand.z += obj.Offset.Base.z
|
||||
|
||||
newpath.insertCommand(newcommand)
|
||||
|
||||
obj.Path=newpath
|
||||
|
||||
|
||||
|
||||
class CommandPathCustom:
|
||||
@@ -75,7 +91,7 @@ class CommandPathCustom:
|
||||
FreeCAD.ActiveDocument.openTransaction("Create Custom Path")
|
||||
FreeCADGui.addModule("PathScripts.PathCustom")
|
||||
FreeCADGui.addModule("PathScripts.PathUtils")
|
||||
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython","Custom")')
|
||||
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Custom")')
|
||||
FreeCADGui.doCommand('PathScripts.PathCustom.ObjectCustom(obj)')
|
||||
FreeCADGui.doCommand('obj.ViewObject.Proxy = 0')
|
||||
FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)')
|
||||
@@ -86,4 +102,4 @@ class CommandPathCustom:
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
# register the FreeCAD command
|
||||
FreeCADGui.addCommand('Path_Custom', CommandPathCustom())
|
||||
FreeCADGui.addCommand('Path_Custom', CommandPathCustom())
|
||||
343
src/Mod/Path/PathScripts/PathDressupZCorrect.py
Normal file
343
src/Mod/Path/PathScripts/PathDressupZCorrect.py
Normal file
@@ -0,0 +1,343 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2018 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 *
|
||||
# * *
|
||||
# * Bilinear interpolation code modified heavily from the interpolation *
|
||||
# * library https://github.com/pmav99/interpolation *
|
||||
# * Copyright (c) 2013 by Panagiotis Mavrogiorgos *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
import Part
|
||||
import Path
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
"""Z Depth Correction Dressup. This dressup takes a probe file as input and does bilinear interpolation of the Zdepths to correct for a surface which is not parallel to the milling table/bed. The probe file should conform to the format specified by the linuxcnc G38 probe logging: 9-number coordinate consisting of XYZABCUVW http://linuxcnc.org/docs/html/gcode/g-code.html#gcode:g38
|
||||
"""
|
||||
|
||||
LOG_MODULE = PathLog.thisModule()
|
||||
|
||||
if False:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE)
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE)
|
||||
else:
|
||||
PathLog.setLevel(PathLog.Level.NOTICE, LOG_MODULE)
|
||||
|
||||
|
||||
# Qt tanslation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
movecommands = ['G1', 'G01', 'G2', 'G02', 'G3', 'G03']
|
||||
rapidcommands = ['G0', 'G00']
|
||||
arccommands = ['G2', 'G3', 'G02', 'G03']
|
||||
|
||||
|
||||
class ObjectDressup:
|
||||
|
||||
def __init__(self, obj):
|
||||
obj.addProperty("App::PropertyLink", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("Path_DressupAxisMap", "The base path to modify"))
|
||||
obj.addProperty("App::PropertyFile", "probefile", "ProbeData", QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "The point file from the surface probing."))
|
||||
obj.Proxy = self
|
||||
obj.addProperty("Part::PropertyPartShape", "interpSurface", "Path")
|
||||
obj.setEditorMode('interpSurface', 2) # hide
|
||||
obj.addProperty("App::PropertyDistance", "ArcInterpolate", "Interpolate", QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "Deflection distance for arc interpolation"))
|
||||
obj.addProperty("App::PropertyDistance", "SegInterpolate", "Interpolate", QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrectp", "break segments into smaller segments of this length."))
|
||||
obj.ArcInterpolate = 0.1
|
||||
obj.SegInterpolate = 1.0
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
|
||||
def onChanged(self, fp, prop):
|
||||
if str(prop) == "probefile":
|
||||
self._loadFile(fp, fp.probefile)
|
||||
|
||||
def _bilinearInterpolate(self, surface, x, y):
|
||||
|
||||
p1 = FreeCAD.Vector(x, y, 100.0)
|
||||
p2 = FreeCAD.Vector(x, y, -100.0)
|
||||
|
||||
vertical_line = Part.Line(p1, p2)
|
||||
points, curves = vertical_line.intersectCS(surface)
|
||||
return points[0].Z
|
||||
|
||||
def _loadFile(self, obj, filename):
|
||||
if filename == "":
|
||||
return
|
||||
|
||||
f1 = open(filename, 'r')
|
||||
|
||||
try:
|
||||
pointlist = []
|
||||
for line in f1.readlines():
|
||||
w = line.split()
|
||||
xval = round(float(w[0]), 2)
|
||||
yval = round(float(w[1]), 2)
|
||||
zval = round(float(w[2]), 2)
|
||||
|
||||
pointlist.append([xval, yval, zval])
|
||||
PathLog.debug(pointlist)
|
||||
|
||||
cols = list(zip(*pointlist))
|
||||
PathLog.debug("cols: {}".format(cols))
|
||||
yindex = list(sorted(set(cols[1])))
|
||||
PathLog.debug("yindex: {}".format(yindex))
|
||||
|
||||
array = []
|
||||
for y in yindex:
|
||||
points = sorted([p for p in pointlist if p[1] == y])
|
||||
inner = []
|
||||
for p in points:
|
||||
inner.append(FreeCAD.Vector(p[0], p[1], p[2]))
|
||||
array.append(inner)
|
||||
|
||||
intSurf = Part.BSplineSurface()
|
||||
intSurf.interpolate(array)
|
||||
|
||||
obj.interpSurface = intSurf.toShape()
|
||||
except Exception:
|
||||
raise ValueError("File does not contain appropriate point data")
|
||||
|
||||
def execute(self, obj):
|
||||
|
||||
sampleD = obj.SegInterpolate.Value
|
||||
curveD = obj.ArcInterpolate.Value
|
||||
|
||||
if obj.interpSurface.isNull(): # No valid probe data. return unchanged path
|
||||
obj.Path = obj.Base.Path
|
||||
return
|
||||
|
||||
surface = obj.interpSurface.toNurbs().Faces[0].Surface
|
||||
|
||||
if obj.Base:
|
||||
if obj.Base.isDerivedFrom("Path::Feature"):
|
||||
if obj.Base.Path:
|
||||
if obj.Base.Path.Commands:
|
||||
pathlist = obj.Base.Path.Commands
|
||||
|
||||
newcommandlist = []
|
||||
currLocation = {'X': 0, 'Y': 0, 'Z': 0, 'F': 0}
|
||||
|
||||
for c in pathlist:
|
||||
PathLog.debug(c)
|
||||
PathLog.debug(" curLoc:{}".format(currLocation))
|
||||
newparams = dict(c.Parameters)
|
||||
zval = newparams.get("Z", currLocation['Z'])
|
||||
if c.Name in movecommands:
|
||||
curVec = FreeCAD.Vector(currLocation['X'], currLocation['Y'], currLocation['Z'])
|
||||
arcwire = PathGeom.edgeForCmd(c, curVec)
|
||||
if arcwire is None:
|
||||
continue
|
||||
if c.Name in arccommands:
|
||||
pointlist = arcwire.discretize(Deflection=curveD)
|
||||
else:
|
||||
disc_number = int(arcwire.Length / sampleD)
|
||||
if disc_number > 1:
|
||||
pointlist = arcwire.discretize(Number=int(arcwire.Length / sampleD))
|
||||
else:
|
||||
pointlist = [v.Point for v in arcwire.Vertexes]
|
||||
for point in pointlist:
|
||||
offset = self._bilinearInterpolate(surface, point.x, point.y)
|
||||
newcommand = Path.Command("G1", {'X': point.x, 'Y': point.y, 'Z': point.z + offset})
|
||||
newcommandlist.append(newcommand)
|
||||
currLocation.update(newcommand.Parameters)
|
||||
currLocation['Z'] = zval
|
||||
|
||||
else:
|
||||
# Non Feed Command
|
||||
newcommandlist.append(c)
|
||||
currLocation.update(c.Parameters)
|
||||
path = Path.Path(newcommandlist)
|
||||
obj.Path = path
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
|
||||
def __init__(self, obj):
|
||||
self.obj = obj
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ZCorrectEdit.ui")
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path_DressupZCorrect", "Edit Z Correction Dress-up"))
|
||||
self.interpshape = FreeCAD.ActiveDocument.addObject("Part::Feature", "InterpolationSurface")
|
||||
self.interpshape.Shape = obj.interpSurface
|
||||
self.interpshape.ViewObject.Transparency = 60
|
||||
self.interpshape.ViewObject.ShapeColor = (1.00000, 1.00000, 0.01961)
|
||||
self.interpshape.ViewObject.Selectable = False
|
||||
stock = PathUtils.findParentJob(obj).Stock
|
||||
self.interpshape.Placement.Base.z = stock.Shape.BoundBox.ZMax
|
||||
|
||||
def reject(self):
|
||||
FreeCAD.ActiveDocument.abortTransaction()
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def accept(self):
|
||||
self.getFields()
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.removeObject(self.interpshape.Name)
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def getFields(self):
|
||||
self.obj.Proxy.execute(self.obj)
|
||||
|
||||
def updateUI(self):
|
||||
|
||||
if PathLog.getLevel(LOG_MODULE) == PathLog.Level.DEBUG:
|
||||
for obj in FreeCAD.ActiveDocument.Objects:
|
||||
if obj.Name.startswith('Shape'):
|
||||
FreeCAD.ActiveDocument.removeObject(obj.Name)
|
||||
print('object name %s' % self.obj.Name)
|
||||
if hasattr(self.obj.Proxy, "shapes"):
|
||||
PathLog.info("showing shapes attribute")
|
||||
for shapes in self.obj.Proxy.shapes.itervalues():
|
||||
for shape in shapes:
|
||||
Part.show(shape)
|
||||
else:
|
||||
PathLog.info("no shapes attribute found")
|
||||
|
||||
def updateModel(self):
|
||||
self.getFields()
|
||||
self.updateUI()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def setFields(self):
|
||||
self.form.ProbePointFileName.setText(self.obj.probefile)
|
||||
|
||||
self.updateUI()
|
||||
|
||||
def open(self):
|
||||
pass
|
||||
|
||||
def setupUi(self):
|
||||
self.setFields()
|
||||
# now that the form is filled, setup the signal handlers
|
||||
self.form.ProbePointFileName.editingFinished.connect(self.updateModel)
|
||||
self.form.SetProbePointFileName.clicked.connect(self.SetProbePointFileName)
|
||||
|
||||
def SetProbePointFileName(self):
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self.form, translate("Path_Probe", "Select Probe Point File"), None, translate("Path_Probe", "All Files (*.*)"))
|
||||
if filename and filename[0]:
|
||||
self.obj.probefile = str(filename[0])
|
||||
self.setFields()
|
||||
|
||||
|
||||
class ViewProviderDressup:
|
||||
|
||||
def __init__(self, vobj):
|
||||
vobj.Proxy = self
|
||||
|
||||
def attach(self, vobj):
|
||||
self.obj = vobj.Object
|
||||
if self.obj and self.obj.Base:
|
||||
for i in self.obj.Base.InList:
|
||||
if hasattr(i, "Group"):
|
||||
group = i.Group
|
||||
for g in group:
|
||||
if g.Name == self.obj.Base.Name:
|
||||
group.remove(g)
|
||||
i.Group = group
|
||||
return
|
||||
|
||||
def claimChildren(self):
|
||||
return [self.obj.Base]
|
||||
|
||||
def setEdit(self, vobj, mode=0):
|
||||
FreeCADGui.Control.closeDialog()
|
||||
panel = TaskPanel(vobj.Object)
|
||||
FreeCADGui.Control.showDialog(panel)
|
||||
panel.setupUi()
|
||||
return True
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
|
||||
def onDelete(self, arg1=None, arg2=None):
|
||||
'''this makes sure that the base operation is added back to the project and visible'''
|
||||
FreeCADGui.ActiveDocument.getObject(arg1.Object.Base.Name).Visibility = True
|
||||
job = PathUtils.findParentJob(arg1.Object)
|
||||
job.Proxy.addOperation(arg1.Object.Base)
|
||||
arg1.Object.Base = None
|
||||
return True
|
||||
|
||||
|
||||
class CommandPathDressup:
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-Dressup',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "Z Depth Correction Dress-up"),
|
||||
'Accel': "",
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_DressupZCorrect", "Use Probe Map to correct Z depth")}
|
||||
|
||||
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):
|
||||
|
||||
# check that the selection contains exactly what we want
|
||||
selection = FreeCADGui.Selection.getSelection()
|
||||
if len(selection) != 1:
|
||||
FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select one path object\n"))
|
||||
return
|
||||
if not selection[0].isDerivedFrom("Path::Feature"):
|
||||
FreeCAD.Console.PrintError(translate("Path_Dressup", "The selected object is not a path\n"))
|
||||
return
|
||||
if selection[0].isDerivedFrom("Path::FeatureCompoundPython"):
|
||||
FreeCAD.Console.PrintError(translate("Path_Dressup", "Please select a Path object"))
|
||||
return
|
||||
|
||||
# everything ok!
|
||||
FreeCAD.ActiveDocument.openTransaction(translate("Path_DressupZCorrect", "Create Dress-up"))
|
||||
FreeCADGui.addModule("PathScripts.PathDressupZCorrect")
|
||||
FreeCADGui.addModule("PathScripts.PathUtils")
|
||||
FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "ZCorrectDressup")')
|
||||
FreeCADGui.doCommand('PathScripts.PathDressupZCorrect.ObjectDressup(obj)')
|
||||
FreeCADGui.doCommand('obj.Base = FreeCAD.ActiveDocument.' + selection[0].Name)
|
||||
FreeCADGui.doCommand('PathScripts.PathDressupZCorrect.ViewProviderDressup(obj.ViewObject)')
|
||||
FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)')
|
||||
FreeCADGui.doCommand('Gui.ActiveDocument.getObject(obj.Base.Name).Visibility = False')
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
# register the FreeCAD command
|
||||
FreeCADGui.addCommand('Path_DressupZCorrect', CommandPathDressup())
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathDressup... done\n")
|
||||
@@ -99,6 +99,8 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
obj.PeckEnabled = self.form.peckEnabled.isChecked()
|
||||
if obj.ExtraOffset != str(self.form.ExtraOffset.currentText()):
|
||||
obj.ExtraOffset = str(self.form.ExtraOffset.currentText())
|
||||
if obj.EnableRotation != str(self.form.enableRotation.currentText()):
|
||||
obj.EnableRotation = str(self.form.enableRotation.currentText())
|
||||
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
self.updateCoolant(obj, self.form.coolantController)
|
||||
@@ -122,6 +124,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
self.setupCoolant(obj, self.form.coolantController)
|
||||
self.selectInComboBox(obj.EnableRotation, self.form.enableRotation)
|
||||
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
@@ -137,6 +140,7 @@ class TaskPanelOpPage(PathCircularHoleBaseGui.TaskPanelOpPage):
|
||||
signals.append(self.form.coolantController.currentIndexChanged)
|
||||
signals.append(self.form.coolantController.currentIndexChanged)
|
||||
signals.append(self.form.ExtraOffset.currentIndexChanged)
|
||||
signals.append(self.form.enableRotation.currentIndexChanged)
|
||||
|
||||
return signals
|
||||
|
||||
|
||||
@@ -313,6 +313,9 @@ def edgeForCmd(cmd, startPoint):
|
||||
"""edgeForCmd(cmd, startPoint).
|
||||
Returns an Edge representing the given command, assuming a given startPoint."""
|
||||
|
||||
PathLog.debug("cmd: {}".format(cmd))
|
||||
PathLog.debug("startpoint {}".format(startPoint))
|
||||
|
||||
endPoint = commandEndPoint(cmd, startPoint)
|
||||
if (cmd.Name in CmdMoveStraight) or (cmd.Name in CmdMoveRapid):
|
||||
if pointsCoincide(startPoint, endPoint):
|
||||
@@ -343,6 +346,10 @@ def edgeForCmd(cmd, startPoint):
|
||||
if isRoughly(startPoint.z, endPoint.z):
|
||||
midPoint = center + Vector(math.cos(angle), math.sin(angle), 0) * R
|
||||
PathLog.debug("arc: (%.2f, %.2f) -> (%.2f, %.2f) -> (%.2f, %.2f)" % (startPoint.x, startPoint.y, midPoint.x, midPoint.y, endPoint.x, endPoint.y))
|
||||
PathLog.debug("StartPoint:{}".format(startPoint))
|
||||
PathLog.debug("MidPoint:{}".format(midPoint))
|
||||
PathLog.debug("EndPoint:{}".format(endPoint))
|
||||
|
||||
return Part.Edge(Part.Arc(startPoint, midPoint, endPoint))
|
||||
|
||||
# It's a Helix
|
||||
|
||||
@@ -35,6 +35,7 @@ else:
|
||||
|
||||
Processed = False
|
||||
|
||||
|
||||
def Startup():
|
||||
global Processed # pylint: disable=global-statement
|
||||
if not Processed:
|
||||
@@ -51,6 +52,7 @@ def Startup():
|
||||
from PathScripts import PathDressupPathBoundaryGui
|
||||
from PathScripts import PathDressupTagGui
|
||||
from PathScripts import PathDressupLeadInOut
|
||||
from PathScripts import PathDressupZCorrect
|
||||
from PathScripts import PathDrillingGui
|
||||
from PathScripts import PathEngraveGui
|
||||
from PathScripts import PathFixture
|
||||
@@ -61,6 +63,7 @@ def Startup():
|
||||
from PathScripts import PathPocketGui
|
||||
from PathScripts import PathPocketShapeGui
|
||||
from PathScripts import PathPost
|
||||
from PathScripts import PathProbeGui
|
||||
from PathScripts import PathProfileContourGui
|
||||
from PathScripts import PathProfileEdgesGui
|
||||
from PathScripts import PathProfileFacesGui
|
||||
@@ -69,12 +72,13 @@ def Startup():
|
||||
from PathScripts import PathSimpleCopy
|
||||
from PathScripts import PathSimulatorGui
|
||||
from PathScripts import PathStop
|
||||
# from PathScripts import PathSurfaceGui # Added in initGui.py due to OCL dependency
|
||||
from PathScripts import PathToolController
|
||||
from PathScripts import PathToolControllerGui
|
||||
from PathScripts import PathToolLibraryManager
|
||||
from PathScripts import PathToolLibraryEditor
|
||||
from PathScripts import PathUtilsGui
|
||||
# from PathScripts import PathWaterlineGui # Added in initGui.py due to OCL dependency
|
||||
Processed = True
|
||||
else:
|
||||
PathLog.debug('Skipping PathGui initialisation')
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ class ObjectFace(PathPocketBase.ObjectPocket):
|
||||
'''areaOpShapes(obj) ... return top face'''
|
||||
# Facing is done either against base objects
|
||||
holeShape = None
|
||||
|
||||
|
||||
if obj.Base:
|
||||
PathLog.debug("obj.Base: {}".format(obj.Base))
|
||||
faces = []
|
||||
@@ -147,17 +147,17 @@ class ObjectFace(PathPocketBase.ObjectPocket):
|
||||
# Find the correct shape depending on Boundary shape.
|
||||
PathLog.debug("Boundary Shape: {}".format(obj.BoundaryShape))
|
||||
bb = planeshape.BoundBox
|
||||
|
||||
|
||||
# Apply offset for clearing edges
|
||||
offset = 0;
|
||||
if obj.ClearEdges == True:
|
||||
offset = self.radius + 0.1
|
||||
|
||||
|
||||
bb.XMin = bb.XMin - offset
|
||||
bb.YMin = bb.YMin - offset
|
||||
bb.XMax = bb.XMax + offset
|
||||
bb.YMax = bb.YMax + offset
|
||||
|
||||
|
||||
if obj.BoundaryShape == 'Boundbox':
|
||||
bbperim = Part.makeBox(bb.XLength, bb.YLength, 1, FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin), FreeCAD.Vector(0, 0, 1))
|
||||
env = PathUtils.getEnvelope(partshape=bbperim, depthparams=self.depthparams)
|
||||
@@ -170,7 +170,7 @@ class ObjectFace(PathPocketBase.ObjectPocket):
|
||||
elif obj.BoundaryShape == 'Stock':
|
||||
stock = PathUtils.findParentJob(obj).Stock.Shape
|
||||
env = stock
|
||||
|
||||
|
||||
if obj.ExcludeRaisedAreas is True and oneBase[1] is True:
|
||||
includedFaces = self.getAllIncludedFaces(oneBase[0], stock, faceZ=minHeight)
|
||||
if len(includedFaces) > 0:
|
||||
@@ -269,7 +269,6 @@ def SetupProperties():
|
||||
setup.append("BoundaryShape")
|
||||
setup.append("ExcludeRaisedAreas")
|
||||
setup.append("ClearEdges")
|
||||
|
||||
return setup
|
||||
|
||||
|
||||
@@ -278,5 +277,4 @@ def Create(name, obj=None):
|
||||
if obj is None:
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
||||
obj.Proxy = ObjectFace(obj, name)
|
||||
|
||||
return obj
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2017 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * Copyright (c) 2020 russ4262 (Russell Johnson) *
|
||||
# * Copyright (c) 2020 Schildkroet *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
@@ -42,7 +41,7 @@ __author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Class and implementation of shape based Pocket operation."
|
||||
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
# PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
|
||||
@@ -435,7 +434,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
if obj.Base:
|
||||
PathLog.debug('Processing... obj.Base')
|
||||
self.removalshapes = [] # pylint: disable=attribute-defined-outside-init
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
if obj.EnableRotation == 'Off':
|
||||
stock = PathUtils.findParentJob(obj).Stock
|
||||
for (base, subList) in obj.Base:
|
||||
@@ -450,11 +449,11 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
(isLoop, norm, surf) = self.checkForFacesLoop(base, subsList)
|
||||
|
||||
if isLoop is True:
|
||||
PathLog.info("Common Surface.Axis or normalAt() value found for loop faces.")
|
||||
PathLog.debug("Common Surface.Axis or normalAt() value found for loop faces.")
|
||||
rtn = False
|
||||
subCount += 1
|
||||
(rtn, angle, axis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) # pylint: disable=unused-variable
|
||||
PathLog.info("angle: {}; axis: {}".format(angle, axis))
|
||||
PathLog.debug("angle: {}; axis: {}".format(angle, axis))
|
||||
|
||||
if rtn is True:
|
||||
faceNums = ""
|
||||
@@ -471,15 +470,17 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
rtn = False
|
||||
PathLog.warning(translate("PathPocketShape", "Face appears to NOT be horizontal AFTER rotation applied."))
|
||||
break
|
||||
|
||||
if rtn is False:
|
||||
PathLog.debug(translate("Path", "Face appears misaligned after initial rotation."))
|
||||
if obj.InverseAngle is False:
|
||||
if obj.AttemptInverseAngle is True:
|
||||
PathLog.debug("Applying the inverse angle.")
|
||||
(clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle)
|
||||
else:
|
||||
PathLog.warning(translate("Path", "Consider toggling the InverseAngle property and recomputing the operation."))
|
||||
msg = translate("Path", "Consider toggling the 'InverseAngle' property and recomputing.")
|
||||
PathLog.warning(msg)
|
||||
|
||||
if angle < -180.0:
|
||||
if angle < 0.0:
|
||||
angle += 360.0
|
||||
|
||||
tup = clnBase, subsList, angle, axis, clnStock
|
||||
@@ -518,6 +519,7 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
|
||||
(norm, surf) = self.getFaceNormAndSurf(face)
|
||||
(rtn, angle, axis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) # pylint: disable=unused-variable
|
||||
PathLog.debug("initial {}".format(praInfo))
|
||||
|
||||
if rtn is True:
|
||||
faceNum = sub.replace('Face', '')
|
||||
@@ -525,20 +527,31 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
# Verify faces are correctly oriented - InverseAngle might be necessary
|
||||
faceIA = clnBase.Shape.getElement(sub)
|
||||
(norm, surf) = self.getFaceNormAndSurf(faceIA)
|
||||
(rtn, praAngle, praAxis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) # pylint: disable=unused-variable
|
||||
(rtn, praAngle, praAxis, praInfo2) = self.faceRotationAnalysis(obj, norm, surf) # pylint: disable=unused-variable
|
||||
PathLog.debug("follow-up {}".format(praInfo2))
|
||||
|
||||
if abs(praAngle) == 180.0:
|
||||
rtn = False
|
||||
if self.isFaceUp(clnBase, faceIA) is False:
|
||||
PathLog.debug('isFaceUp is False')
|
||||
angle -= 180.0
|
||||
|
||||
if rtn is True:
|
||||
PathLog.debug("Face not aligned after initial rotation.")
|
||||
PathLog.debug(translate("Path", "Face appears misaligned after initial rotation."))
|
||||
if obj.InverseAngle is False:
|
||||
if obj.AttemptInverseAngle is True:
|
||||
PathLog.debug("Applying the inverse angle.")
|
||||
(clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle)
|
||||
else:
|
||||
PathLog.warning(translate("Path", "Consider toggling the InverseAngle property and recomputing the operation."))
|
||||
msg = translate("Path", "Consider toggling the 'InverseAngle' property and recomputing.")
|
||||
PathLog.warning(msg)
|
||||
|
||||
if self.isFaceUp(clnBase, faceIA) is False:
|
||||
PathLog.debug('isFaceUp is False')
|
||||
angle += 180.0
|
||||
else:
|
||||
PathLog.debug("Face appears to be oriented correctly.")
|
||||
|
||||
if angle < -180.0:
|
||||
if angle < 0.0:
|
||||
angle += 360.0
|
||||
|
||||
tup = clnBase, [sub], angle, axis, clnStock
|
||||
@@ -650,8 +663,9 @@ class ObjectPocket(PathPocketBase.ObjectPocket):
|
||||
if shpZMin > obj.FinalDepth.Value:
|
||||
afD = shpZMin
|
||||
if sD <= afD:
|
||||
PathLog.error('Start Depth is lower than face depth.')
|
||||
sD = afD + 1.0
|
||||
msg = translate('PathPocketShape', 'Start Depth is lower than face depth. Setting to ')
|
||||
PathLog.warning(msg + ' {} mm.'.format(sD))
|
||||
else:
|
||||
face.translate(FreeCAD.Vector(0, 0, obj.FinalDepth.Value - shpZMin))
|
||||
|
||||
|
||||
107
src/Mod/Path/PathScripts/PathProbe.py
Normal file
107
src/Mod/Path/PathScripts/PathProbe.py
Normal file
@@ -0,0 +1,107 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2018 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 *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import FreeCAD
|
||||
import Path
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Probing Operation"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Path Probing operation."
|
||||
|
||||
if False:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
else:
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
|
||||
|
||||
# Qt tanslation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
class ObjectProbing(PathOp.ObjectOp):
|
||||
'''Proxy object for Probing operation.'''
|
||||
|
||||
def opFeatures(self, obj):
|
||||
'''opFeatures(obj) ... Probing works on the stock object.'''
|
||||
return PathOp.FeatureDepths | PathOp.FeatureHeights | PathOp.FeatureTool
|
||||
|
||||
def initOperation(self, obj):
|
||||
obj.addProperty("App::PropertyLength", "Xoffset", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "X offset between tool and probe"))
|
||||
obj.addProperty("App::PropertyLength", "Yoffset", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "Y offset between tool and probe"))
|
||||
obj.addProperty("App::PropertyInteger", "PointCountX", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "Number of points to probe in X direction"))
|
||||
obj.addProperty("App::PropertyInteger", "PointCountY", "Probe", QtCore.QT_TRANSLATE_NOOP("App::Property", "Number of points to probe in Y direction"))
|
||||
obj.addProperty("App::PropertyFile", "OutputFileName", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The output location for the probe data to be written"))
|
||||
|
||||
def nextpoint(self, startpoint=0.0, endpoint=0.0, count=3):
|
||||
curstep = 0
|
||||
dist = (endpoint - startpoint) / (count - 1)
|
||||
while curstep <= count-1:
|
||||
yield startpoint + (curstep * dist)
|
||||
curstep += 1
|
||||
|
||||
def opExecute(self, obj):
|
||||
'''opExecute(obj) ... generate probe locations.'''
|
||||
PathLog.track()
|
||||
self.commandlist.append(Path.Command("(Begin Probing)"))
|
||||
|
||||
stock = PathUtils.findParentJob(obj).Stock
|
||||
bb = stock.Shape.BoundBox
|
||||
|
||||
openstring = '(PROBEOPEN {})'.format(obj.OutputFileName)
|
||||
self.commandlist.append(Path.Command(openstring))
|
||||
self.commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
|
||||
|
||||
for y in self.nextpoint(bb.YMin, bb.YMax, obj.PointCountY):
|
||||
for x in self.nextpoint(bb.XMin, bb.XMax, obj.PointCountX):
|
||||
self.commandlist.append(Path.Command("G0", {"X": x + obj.Xoffset.Value, "Y": y + obj.Yoffset.Value, "Z": obj.SafeHeight.Value}))
|
||||
self.commandlist.append(Path.Command("G38.2", {"Z": obj.FinalDepth.Value, "F": obj.ToolController.VertFeed.Value}))
|
||||
self.commandlist.append(Path.Command("G0", {"Z": obj.SafeHeight.Value}))
|
||||
|
||||
self.commandlist.append(Path.Command("(PROBECLOSE)"))
|
||||
|
||||
def opSetDefaultValues(self, obj, job):
|
||||
'''opSetDefaultValues(obj, job) ... set default value for RetractHeight'''
|
||||
|
||||
|
||||
def SetupProperties():
|
||||
setup = ['Xoffset', 'Yoffset', 'PointCountX', 'PointCountY', 'OutputFileName']
|
||||
return setup
|
||||
|
||||
|
||||
def Create(name, obj=None):
|
||||
'''Create(name) ... Creates and returns a Probing operation.'''
|
||||
if obj is None:
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
||||
proxy = ObjectProbing(obj, name)
|
||||
return obj
|
||||
94
src/Mod/Path/PathScripts/PathProbeGui.py
Normal file
94
src/Mod/Path/PathScripts/PathProbeGui.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2017 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 FreeCADGui
|
||||
import PathScripts.PathProbe as PathProbe
|
||||
import PathScripts.PathOpGui as PathOpGui
|
||||
import PathScripts.PathGui as PathGui
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
__title__ = "Path Probing Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Probing operation page controller and command implementation."
|
||||
|
||||
|
||||
# Qt tanslation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
'''Page controller class for the Probing operation.'''
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... returns UI'''
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageOpProbeEdit.ui")
|
||||
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... transfers values from UI to obj's proprties'''
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
PathGui.updateInputField(obj, 'Xoffset', self.form.Xoffset)
|
||||
PathGui.updateInputField(obj, 'Yoffset', self.form.Yoffset)
|
||||
obj.PointCountX = self.form.PointCountX.value()
|
||||
obj.PointCountY = self.form.PointCountY.value()
|
||||
obj.OutputFileName = str(self.form.OutputFileName.text())
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... transfers obj's property values to UI'''
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
self.form.Xoffset.setText(FreeCAD.Units.Quantity(obj.Xoffset.Value, FreeCAD.Units.Length).UserString)
|
||||
self.form.Yoffset.setText(FreeCAD.Units.Quantity(obj.Yoffset.Value, FreeCAD.Units.Length).UserString)
|
||||
self.form.OutputFileName.setText(obj.OutputFileName)
|
||||
self.form.PointCountX.setValue(obj.PointCountX)
|
||||
self.form.PointCountY.setValue(obj.PointCountY)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
|
||||
signals = []
|
||||
signals.append(self.form.toolController.currentIndexChanged)
|
||||
signals.append(self.form.PointCountX.valueChanged)
|
||||
signals.append(self.form.PointCountY.valueChanged)
|
||||
signals.append(self.form.OutputFileName.editingFinished)
|
||||
signals.append(self.form.Xoffset.valueChanged)
|
||||
signals.append(self.form.Yoffset.valueChanged)
|
||||
self.form.SetOutputFileName.clicked.connect(self.SetOutputFileName)
|
||||
return signals
|
||||
|
||||
def SetOutputFileName(self):
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self.form, translate("Path_Probe", "Select Output File"), None, translate("Path_Probe", "All Files (*.*)"))
|
||||
if filename and filename[0]:
|
||||
self.obj.OutputFileName = str(filename[0])
|
||||
self.setFields(self.obj)
|
||||
|
||||
|
||||
Command = PathOpGui.SetupOperation('Probe', PathProbe.Create, TaskPanelOpPage,
|
||||
'Path-Probe',
|
||||
QtCore.QT_TRANSLATE_NOOP("Probe", "Probe"),
|
||||
QtCore.QT_TRANSLATE_NOOP("Probe", "Create a Probing Grid from a job stock"),
|
||||
PathProbe.SetupProperties)
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathProbeGui... done\n")
|
||||
@@ -112,18 +112,23 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
else:
|
||||
PathLog.error(translate('PathProfileEdges', 'The selected edge(s) are inaccessible.'))
|
||||
else:
|
||||
cutWireObjs = False
|
||||
(origWire, flatWire) = self._flattenWire(obj, wire, obj.FinalDepth.Value)
|
||||
cutShp = self._getCutAreaCrossSection(obj, base, origWire, flatWire)
|
||||
if cutShp is not False:
|
||||
cutWireObjs = self._extractPathWire(obj, base, flatWire, cutShp)
|
||||
|
||||
if cutWireObjs is not False:
|
||||
for cW in cutWireObjs:
|
||||
shapes.append((cW, False))
|
||||
self.profileEdgesIsOpen = True
|
||||
if self.JOB.GeometryTolerance.Value == 0.0:
|
||||
msg = self.JOB.Label + '.GeometryTolerance = 0.0.'
|
||||
msg += translate('PathProfileEdges', 'Please set to an acceptable value greater than zero.')
|
||||
PathLog.error(msg)
|
||||
else:
|
||||
PathLog.error(translate('PathProfileEdges', 'The selected edge(s) are inaccessible.'))
|
||||
cutWireObjs = False
|
||||
(origWire, flatWire) = self._flattenWire(obj, wire, obj.FinalDepth.Value)
|
||||
cutShp = self._getCutAreaCrossSection(obj, base, origWire, flatWire)
|
||||
if cutShp is not False:
|
||||
cutWireObjs = self._extractPathWire(obj, base, flatWire, cutShp)
|
||||
|
||||
if cutWireObjs is not False:
|
||||
for cW in cutWireObjs:
|
||||
shapes.append((cW, False))
|
||||
self.profileEdgesIsOpen = True
|
||||
else:
|
||||
PathLog.error(translate('PathProfileEdges', 'The selected edge(s) are inaccessible.'))
|
||||
|
||||
# Delete the temporary objects
|
||||
if PathLog.getLevel(PathLog.thisModule()) != 4:
|
||||
@@ -179,13 +184,13 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
|
||||
return (OW, FW)
|
||||
|
||||
# Open-edges methods
|
||||
def _getCutAreaCrossSection(self, obj, base, origWire, flatWireObj):
|
||||
PathLog.debug('_getCutAreaCrossSection()')
|
||||
tmpGrp = self.tmpGrp
|
||||
FCAD = FreeCAD.ActiveDocument
|
||||
tolerance = self.JOB.GeometryTolerance.Value
|
||||
# toolDiam = float(obj.ToolController.Tool.Diameter)
|
||||
toolDiam = 2 * self.radius # self.radius defined in PathAreaOp or PathprofileBase modules
|
||||
toolDiam = 2 * self.radius # self.radius defined in PathAreaOp or PathProfileBase modules
|
||||
minBfr = toolDiam * 1.25
|
||||
bbBfr = (self.ofstRadius * 2) * 1.25
|
||||
if bbBfr < minBfr:
|
||||
@@ -243,34 +248,33 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
|
||||
# Cut model(selected edges) from extended edges boundbox
|
||||
cutArea = extBndboxEXT.Shape.cut(base.Shape)
|
||||
CA = FCAD.addObject('Part::Feature', 'tmpBndboxCutByBase')
|
||||
CA.Shape = cutArea
|
||||
CA.purgeTouched()
|
||||
tmpGrp.addObject(CA)
|
||||
|
||||
# Get top and bottom faces of cut area (CA), and combine faces when necessary
|
||||
topFc = list()
|
||||
botFc = list()
|
||||
bbZMax = CA.Shape.BoundBox.ZMax
|
||||
bbZMin = CA.Shape.BoundBox.ZMin
|
||||
for f in range(0, len(CA.Shape.Faces)):
|
||||
Fc = CA.Shape.Faces[f]
|
||||
if abs(Fc.BoundBox.ZMax - bbZMax) < tolerance and abs(Fc.BoundBox.ZMin - bbZMax) < tolerance:
|
||||
bbZMax = cutArea.BoundBox.ZMax
|
||||
bbZMin = cutArea.BoundBox.ZMin
|
||||
for f in range(0, len(cutArea.Faces)):
|
||||
FcBB = cutArea.Faces[f].BoundBox
|
||||
if abs(FcBB.ZMax - bbZMax) < tolerance and abs(FcBB.ZMin - bbZMax) < tolerance:
|
||||
topFc.append(f)
|
||||
if abs(Fc.BoundBox.ZMax - bbZMin) < tolerance and abs(Fc.BoundBox.ZMin - bbZMin) < tolerance:
|
||||
if abs(FcBB.ZMax - bbZMin) < tolerance and abs(FcBB.ZMin - bbZMin) < tolerance:
|
||||
botFc.append(f)
|
||||
topComp = Part.makeCompound([CA.Shape.Faces[f] for f in topFc])
|
||||
if len(topFc) == 0:
|
||||
PathLog.error('Failed to identify top faces of cut area.')
|
||||
return False
|
||||
topComp = Part.makeCompound([cutArea.Faces[f] for f in topFc])
|
||||
topComp.translate(FreeCAD.Vector(0, 0, fdv - topComp.BoundBox.ZMin)) # Translate face to final depth
|
||||
if len(botFc) > 1:
|
||||
PathLog.debug('len(botFc) > 1')
|
||||
bndboxFace = Part.Face(extBndbox.Shape.Wires[0])
|
||||
tmpFace = Part.Face(extBndbox.Shape.Wires[0])
|
||||
for f in botFc:
|
||||
Q = tmpFace.cut(CA.Shape.Faces[f])
|
||||
Q = tmpFace.cut(cutArea.Faces[f])
|
||||
tmpFace = Q
|
||||
botComp = bndboxFace.cut(tmpFace)
|
||||
else:
|
||||
botComp = Part.makeCompound([CA.Shape.Faces[f] for f in botFc])
|
||||
botComp = Part.makeCompound([cutArea.Faces[f] for f in botFc]) # Part.makeCompound([CA.Shape.Faces[f] for f in botFc])
|
||||
botComp.translate(FreeCAD.Vector(0, 0, fdv - botComp.BoundBox.ZMin)) # Translate face to final depth
|
||||
|
||||
# Convert compound shapes to FC objects for use in multicommon operation
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * Copyright (c) 2020 russ4262 (Russell Johnson) *
|
||||
# * Copyright (c) 2020 Schildkroet *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
@@ -43,6 +42,7 @@ __doc__ = "Path Profile operation based on faces."
|
||||
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
|
||||
|
||||
# Qt translation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
@@ -132,22 +132,42 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
rtn = False
|
||||
(norm, surf) = self.getFaceNormAndSurf(shape)
|
||||
(rtn, angle, axis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) # pylint: disable=unused-variable
|
||||
PathLog.debug("initial faceRotationAnalysis: {}".format(praInfo))
|
||||
if rtn is True:
|
||||
(clnBase, angle, clnStock, tag) = self.applyRotationalAnalysis(obj, base, angle, axis, subCount)
|
||||
# Verify faces are correctly oriented - InverseAngle might be necessary
|
||||
faceIA = getattr(clnBase.Shape, sub)
|
||||
(norm, surf) = self.getFaceNormAndSurf(faceIA)
|
||||
(rtn, praAngle, praAxis, praInfo) = self.faceRotationAnalysis(obj, norm, surf) # pylint: disable=unused-variable
|
||||
(rtn, praAngle, praAxis, praInfo2) = self.faceRotationAnalysis(obj, norm, surf) # pylint: disable=unused-variable
|
||||
PathLog.debug("follow-up faceRotationAnalysis: {}".format(praInfo2))
|
||||
|
||||
if abs(praAngle) == 180.0:
|
||||
rtn = False
|
||||
if self.isFaceUp(clnBase, faceIA) is False:
|
||||
PathLog.debug('isFaceUp 1 is False')
|
||||
angle -= 180.0
|
||||
|
||||
if rtn is True:
|
||||
PathLog.error(translate("Path", "Face appears misaligned after initial rotation."))
|
||||
if obj.AttemptInverseAngle is True and obj.InverseAngle is False:
|
||||
(clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle)
|
||||
PathLog.debug(translate("Path", "Face appears misaligned after initial rotation."))
|
||||
if obj.InverseAngle is False:
|
||||
if obj.AttemptInverseAngle is True:
|
||||
(clnBase, clnStock, angle) = self.applyInverseAngle(obj, clnBase, clnStock, axis, angle)
|
||||
else:
|
||||
msg = translate("Path", "Consider toggling the 'InverseAngle' property and recomputing.")
|
||||
PathLog.warning(msg)
|
||||
|
||||
if self.isFaceUp(clnBase, faceIA) is False:
|
||||
PathLog.debug('isFaceUp 2 is False')
|
||||
angle += 180.0
|
||||
else:
|
||||
msg = translate("Path", "Consider toggling the 'InverseAngle' property and recomputing.")
|
||||
PathLog.error(msg)
|
||||
PathLog.debug(' isFaceUp')
|
||||
|
||||
else:
|
||||
PathLog.debug("Face appears to be oriented correctly.")
|
||||
|
||||
if angle < 0.0:
|
||||
angle += 360.0
|
||||
|
||||
tup = clnBase, sub, tag, angle, axis, clnStock
|
||||
else:
|
||||
if self.warnDisabledAxis(obj, axis) is False:
|
||||
@@ -157,21 +177,21 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
tag = base.Name + '_' + axis + str(angle).replace('.', '_')
|
||||
stock = PathUtils.findParentJob(obj).Stock
|
||||
tup = base, sub, tag, angle, axis, stock
|
||||
|
||||
|
||||
allTuples.append(tup)
|
||||
|
||||
|
||||
if subCount > 1:
|
||||
msg = translate('Path', "Multiple faces in Base Geometry.") + " "
|
||||
msg += translate('Path', "Depth settings will be applied to all faces.")
|
||||
PathLog.warning(msg)
|
||||
|
||||
|
||||
(Tags, Grps) = self.sortTuplesByIndex(allTuples, 2) # return (TagList, GroupList)
|
||||
subList = []
|
||||
for o in range(0, len(Tags)):
|
||||
subList = []
|
||||
for (base, sub, tag, angle, axis, stock) in Grps[o]:
|
||||
subList.append(sub)
|
||||
|
||||
|
||||
pair = base, subList, angle, axis, stock
|
||||
baseSubsTuples.append(pair)
|
||||
# Efor
|
||||
@@ -196,7 +216,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
if numpy.isclose(abs(shape.normalAt(0, 0).z), 1): # horizontal face
|
||||
for wire in shape.Wires[1:]:
|
||||
holes.append((base.Shape, wire))
|
||||
|
||||
|
||||
# Add face depth to list
|
||||
faceDepths.append(shape.BoundBox.ZMin)
|
||||
else:
|
||||
@@ -205,13 +225,12 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
PathLog.error(msg)
|
||||
FreeCAD.Console.PrintWarning(msg)
|
||||
|
||||
|
||||
# Set initial Start and Final Depths and recalculate depthparams
|
||||
finDep = obj.FinalDepth.Value
|
||||
strDep = obj.StartDepth.Value
|
||||
if strDep > stock.Shape.BoundBox.ZMax:
|
||||
strDep = stock.Shape.BoundBox.ZMax
|
||||
|
||||
|
||||
startDepths.append(strDep)
|
||||
self.depthparams = self._customDepthParams(obj, strDep, finDep)
|
||||
|
||||
@@ -230,31 +249,34 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
if obj.processPerimeter:
|
||||
if obj.HandleMultipleFeatures == 'Collectively':
|
||||
custDepthparams = self.depthparams
|
||||
|
||||
if obj.LimitDepthToFace is True and obj.EnableRotation != 'Off':
|
||||
if profileshape.BoundBox.ZMin > obj.FinalDepth.Value:
|
||||
finDep = profileshape.BoundBox.ZMin
|
||||
custDepthparams = self._customDepthParams(obj, strDep, finDep - 0.5) # only an envelope
|
||||
envDepthparams = self._customDepthParams(obj, strDep + 0.5, finDep) # only an envelope
|
||||
try:
|
||||
env = PathUtils.getEnvelope(base.Shape, subshape=profileshape, depthparams=custDepthparams)
|
||||
# env = PathUtils.getEnvelope(base.Shape, subshape=profileshape, depthparams=envDepthparams)
|
||||
env = PathUtils.getEnvelope(profileshape, depthparams=envDepthparams)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
# PathUtils.getEnvelope() failed to return an object.
|
||||
PathLog.error(translate('Path', 'Unable to create path for face(s).'))
|
||||
else:
|
||||
tup = env, False, 'pathProfileFaces', angle, axis, strDep, finDep
|
||||
shapes.append(tup)
|
||||
|
||||
|
||||
elif obj.HandleMultipleFeatures == 'Individually':
|
||||
for shape in faces:
|
||||
profShape = Part.makeCompound([shape])
|
||||
# profShape = Part.makeCompound([shape])
|
||||
finalDep = obj.FinalDepth.Value
|
||||
custDepthparams = self.depthparams
|
||||
if obj.Side == 'Inside':
|
||||
if finalDep < shape.BoundBox.ZMin:
|
||||
# Recalculate depthparams
|
||||
finalDep = shape.BoundBox.ZMin
|
||||
custDepthparams = self._customDepthParams(obj, strDep, finalDep - 0.5)
|
||||
|
||||
env = PathUtils.getEnvelope(base.Shape, subshape=profShape, depthparams=custDepthparams)
|
||||
custDepthparams = self._customDepthParams(obj, strDep + 0.5, finalDep)
|
||||
|
||||
# env = PathUtils.getEnvelope(base.Shape, subshape=profShape, depthparams=custDepthparams)
|
||||
env = PathUtils.getEnvelope(shape, depthparams=custDepthparams)
|
||||
tup = env, False, 'pathProfileFaces', angle, axis, strDep, finalDep
|
||||
shapes.append(tup)
|
||||
|
||||
@@ -262,11 +284,11 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
startDepth = max(startDepths)
|
||||
if obj.StartDepth.Value > startDepth:
|
||||
obj.StartDepth.Value = startDepth
|
||||
|
||||
|
||||
else: # Try to build targets from the job base
|
||||
if 1 == len(self.model):
|
||||
if hasattr(self.model[0], "Proxy"):
|
||||
PathLog.info("hasattr() Proxy")
|
||||
PathLog.debug("hasattr() Proxy")
|
||||
if isinstance(self.model[0].Proxy, ArchPanel.PanelSheet): # process the sheet
|
||||
if obj.processCircles or obj.processHoles:
|
||||
for shape in self.model[0].Proxy.getHoles(self.model[0], transform=True):
|
||||
@@ -302,7 +324,7 @@ class ObjectProfile(PathProfileBase.ObjectProfile):
|
||||
obj.InverseAngle = False
|
||||
obj.AttemptInverseAngle = True
|
||||
obj.LimitDepthToFace = True
|
||||
obj.HandleMultipleFeatures = 'Collectively'
|
||||
obj.HandleMultipleFeatures = 'Individually'
|
||||
|
||||
|
||||
def SetupProperties():
|
||||
@@ -321,6 +343,5 @@ def Create(name, obj=None):
|
||||
'''Create(name) ... Creates and returns a Profile based on faces operation.'''
|
||||
if obj is None:
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
||||
|
||||
obj.Proxy = ObjectProfile(obj, name)
|
||||
return obj
|
||||
|
||||
@@ -30,12 +30,14 @@ import PathScripts.PathUtils as PathUtils
|
||||
import math
|
||||
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
#PathLog.trackModule(PathLog.thisModule())
|
||||
# PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
|
||||
class PathBaseGate(object):
|
||||
# pylint: disable=no-init
|
||||
pass
|
||||
|
||||
|
||||
class EGate(PathBaseGate):
|
||||
def allow(self, doc, obj, sub): # pylint: disable=unused-argument
|
||||
return sub and sub[0:4] == 'Edge'
|
||||
@@ -66,6 +68,7 @@ class ENGRAVEGate(PathBaseGate):
|
||||
|
||||
return False
|
||||
|
||||
|
||||
class CHAMFERGate(PathBaseGate):
|
||||
def allow(self, doc, obj, sub): # pylint: disable=unused-argument
|
||||
try:
|
||||
@@ -94,7 +97,7 @@ class DRILLGate(PathBaseGate):
|
||||
if hasattr(obj, "Shape") and sub:
|
||||
shape = obj.Shape
|
||||
subobj = shape.getElement(sub)
|
||||
return PathUtils.isDrillable(shape, subobj, includePartials = True)
|
||||
return PathUtils.isDrillable(shape, subobj, includePartials=True)
|
||||
else:
|
||||
return False
|
||||
|
||||
@@ -159,6 +162,7 @@ class POCKETGate(PathBaseGate):
|
||||
|
||||
return pocketable
|
||||
|
||||
|
||||
class ADAPTIVEGate(PathBaseGate):
|
||||
def allow(self, doc, obj, sub): # pylint: disable=unused-argument
|
||||
|
||||
@@ -167,45 +171,58 @@ class ADAPTIVEGate(PathBaseGate):
|
||||
obj = obj.Shape
|
||||
except Exception: # pylint: disable=broad-except
|
||||
return False
|
||||
|
||||
|
||||
return adaptive
|
||||
|
||||
|
||||
class CONTOURGate(PathBaseGate):
|
||||
def allow(self, doc, obj, sub): # pylint: disable=unused-argument
|
||||
pass
|
||||
|
||||
class PROBEGate:
|
||||
def allow(self, doc, obj, sub):
|
||||
pass
|
||||
|
||||
def contourselect():
|
||||
FreeCADGui.Selection.addSelectionGate(CONTOURGate())
|
||||
FreeCAD.Console.PrintWarning("Contour Select Mode\n")
|
||||
|
||||
|
||||
def eselect():
|
||||
FreeCADGui.Selection.addSelectionGate(EGate())
|
||||
FreeCAD.Console.PrintWarning("Edge Select Mode\n")
|
||||
|
||||
|
||||
def drillselect():
|
||||
FreeCADGui.Selection.addSelectionGate(DRILLGate())
|
||||
FreeCAD.Console.PrintWarning("Drilling Select Mode\n")
|
||||
|
||||
|
||||
def engraveselect():
|
||||
FreeCADGui.Selection.addSelectionGate(ENGRAVEGate())
|
||||
FreeCAD.Console.PrintWarning("Engraving Select Mode\n")
|
||||
|
||||
|
||||
def chamferselect():
|
||||
FreeCADGui.Selection.addSelectionGate(CHAMFERGate())
|
||||
FreeCAD.Console.PrintWarning("Deburr Select Mode\n")
|
||||
|
||||
|
||||
def profileselect():
|
||||
FreeCADGui.Selection.addSelectionGate(PROFILEGate())
|
||||
FreeCAD.Console.PrintWarning("Profiling Select Mode\n")
|
||||
|
||||
|
||||
def pocketselect():
|
||||
FreeCADGui.Selection.addSelectionGate(POCKETGate())
|
||||
FreeCAD.Console.PrintWarning("Pocketing Select Mode\n")
|
||||
|
||||
|
||||
def adaptiveselect():
|
||||
FreeCADGui.Selection.addSelectionGate(ADAPTIVEGate())
|
||||
FreeCAD.Console.PrintWarning("Adaptive Select Mode\n")
|
||||
|
||||
|
||||
def surfaceselect():
|
||||
if(MESHGate() is True or PROFILEGate() is True):
|
||||
FreeCADGui.Selection.addSelectionGate(True)
|
||||
@@ -215,6 +232,10 @@ def surfaceselect():
|
||||
# FreeCADGui.Selection.addSelectionGate(PROFILEGate()) # Added for face selection
|
||||
FreeCAD.Console.PrintWarning("Surfacing Select Mode\n")
|
||||
|
||||
def probeselect():
|
||||
FreeCADGui.Selection.addSelectionGate(PROBEGate())
|
||||
FreeCAD.Console.PrintWarning("Probe Select Mode\n")
|
||||
|
||||
def select(op):
|
||||
opsel = {}
|
||||
opsel['Contour'] = contourselect
|
||||
@@ -229,9 +250,12 @@ def select(op):
|
||||
opsel['Profile Edges'] = eselect
|
||||
opsel['Profile Faces'] = profileselect
|
||||
opsel['Surface'] = surfaceselect
|
||||
opsel['Waterline'] = surfaceselect
|
||||
opsel['Adaptive'] = adaptiveselect
|
||||
opsel['Probe'] = probeselect
|
||||
return opsel[op]
|
||||
|
||||
|
||||
def clear():
|
||||
FreeCADGui.Selection.removeSelectionGate()
|
||||
FreeCAD.Console.PrintWarning("Free Select\n")
|
||||
|
||||
@@ -149,6 +149,7 @@ class OpPrototype(object):
|
||||
'App::PropertyBool': PropertyBool,
|
||||
'App::PropertyDistance': PropertyDistance,
|
||||
'App::PropertyEnumeration': PropertyEnumeration,
|
||||
'App::PropertyFile': PropertyString,
|
||||
'App::PropertyFloat': PropertyFloat,
|
||||
'App::PropertyFloatConstraint': Property,
|
||||
'App::PropertyFloatList': Property,
|
||||
|
||||
@@ -188,6 +188,18 @@ class _PropertyFloatEditor(_PropertyEditor):
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.value())
|
||||
|
||||
class _PropertyFileEditor(_PropertyEditor):
|
||||
|
||||
def widget(self, parent):
|
||||
return QtGui.QLineEdit(parent)
|
||||
|
||||
def setEditorData(self, widget):
|
||||
text = '' if self.prop.getValue() is None else self.prop.getValue()
|
||||
widget.setText(text)
|
||||
|
||||
def setModelData(self, widget):
|
||||
self.prop.setValue(widget.text())
|
||||
|
||||
_EditorFactory = {
|
||||
PathSetupSheetOpPrototype.Property: None,
|
||||
PathSetupSheetOpPrototype.PropertyAngle: _PropertyAngleEditor,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,89 +39,120 @@ __doc__ = "Surface operation page controller and command implementation."
|
||||
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
'''Page controller class for the Surface operation.'''
|
||||
|
||||
def initPage(self, obj):
|
||||
self.setTitle("3D Surface")
|
||||
self.updateVisibility()
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... returns UI'''
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageOpSurfaceEdit.ui")
|
||||
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... transfers values from UI to obj's proprties'''
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
self.updateCoolant(obj, self.form.coolantController)
|
||||
|
||||
PathGui.updateInputField(obj, 'DepthOffset', self.form.depthOffset)
|
||||
PathGui.updateInputField(obj, 'SampleInterval', self.form.sampleInterval)
|
||||
|
||||
if obj.StepOver != self.form.stepOver.value():
|
||||
obj.StepOver = self.form.stepOver.value()
|
||||
|
||||
if obj.Algorithm != str(self.form.algorithmSelect.currentText()):
|
||||
obj.Algorithm = str(self.form.algorithmSelect.currentText())
|
||||
|
||||
if obj.BoundBox != str(self.form.boundBoxSelect.currentText()):
|
||||
obj.BoundBox = str(self.form.boundBoxSelect.currentText())
|
||||
|
||||
if obj.DropCutterDir != str(self.form.dropCutterDirSelect.currentText()):
|
||||
obj.DropCutterDir = str(self.form.dropCutterDirSelect.currentText())
|
||||
if obj.ScanType != str(self.form.scanType.currentText()):
|
||||
obj.ScanType = str(self.form.scanType.currentText())
|
||||
|
||||
if obj.StepOver != self.form.stepOver.value():
|
||||
obj.StepOver = self.form.stepOver.value()
|
||||
|
||||
if obj.LayerMode != str(self.form.layerMode.currentText()):
|
||||
obj.LayerMode = str(self.form.layerMode.currentText())
|
||||
|
||||
if obj.CutPattern != str(self.form.cutPattern.currentText()):
|
||||
obj.CutPattern = str(self.form.cutPattern.currentText())
|
||||
|
||||
obj.DropCutterExtraOffset.x = FreeCAD.Units.Quantity(self.form.boundBoxExtraOffsetX.text()).Value
|
||||
obj.DropCutterExtraOffset.y = FreeCAD.Units.Quantity(self.form.boundBoxExtraOffsetY.text()).Value
|
||||
|
||||
if obj.DropCutterDir != str(self.form.dropCutterDirSelect.currentText()):
|
||||
obj.DropCutterDir = str(self.form.dropCutterDirSelect.currentText())
|
||||
|
||||
PathGui.updateInputField(obj, 'DepthOffset', self.form.depthOffset)
|
||||
PathGui.updateInputField(obj, 'SampleInterval', self.form.sampleInterval)
|
||||
|
||||
if obj.UseStartPoint != self.form.useStartPoint.isChecked():
|
||||
obj.UseStartPoint = self.form.useStartPoint.isChecked()
|
||||
|
||||
if obj.OptimizeLinearPaths != self.form.optimizeEnabled.isChecked():
|
||||
obj.OptimizeLinearPaths = self.form.optimizeEnabled.isChecked()
|
||||
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
self.updateCoolant(obj, self.form.coolantController)
|
||||
if obj.OptimizeStepOverTransitions != self.form.optimizeStepOverTransitions.isChecked():
|
||||
obj.OptimizeStepOverTransitions = self.form.optimizeStepOverTransitions.isChecked()
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... transfers obj's property values to UI'''
|
||||
self.selectInComboBox(obj.Algorithm, self.form.algorithmSelect)
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
self.setupCoolant(obj, self.form.coolantController)
|
||||
self.selectInComboBox(obj.BoundBox, self.form.boundBoxSelect)
|
||||
self.selectInComboBox(obj.ScanType, self.form.scanType)
|
||||
self.selectInComboBox(obj.LayerMode, self.form.layerMode)
|
||||
self.selectInComboBox(obj.CutPattern, self.form.cutPattern)
|
||||
self.form.boundBoxExtraOffsetX.setText(FreeCAD.Units.Quantity(obj.DropCutterExtraOffset.x, FreeCAD.Units.Length).UserString)
|
||||
self.form.boundBoxExtraOffsetY.setText(FreeCAD.Units.Quantity(obj.DropCutterExtraOffset.y, FreeCAD.Units.Length).UserString)
|
||||
self.selectInComboBox(obj.DropCutterDir, self.form.dropCutterDirSelect)
|
||||
|
||||
self.form.boundBoxExtraOffsetX.setText(str(obj.DropCutterExtraOffset.x))
|
||||
self.form.boundBoxExtraOffsetY.setText(str(obj.DropCutterExtraOffset.y))
|
||||
self.form.depthOffset.setText(FreeCAD.Units.Quantity(obj.DepthOffset.Value, FreeCAD.Units.Length).UserString)
|
||||
self.form.sampleInterval.setText(str(obj.SampleInterval))
|
||||
self.form.stepOver.setValue(obj.StepOver)
|
||||
self.form.sampleInterval.setText(FreeCAD.Units.Quantity(obj.SampleInterval.Value, FreeCAD.Units.Length).UserString)
|
||||
|
||||
if obj.UseStartPoint:
|
||||
self.form.useStartPoint.setCheckState(QtCore.Qt.Checked)
|
||||
else:
|
||||
self.form.useStartPoint.setCheckState(QtCore.Qt.Unchecked)
|
||||
|
||||
if obj.OptimizeLinearPaths:
|
||||
self.form.optimizeEnabled.setCheckState(QtCore.Qt.Checked)
|
||||
else:
|
||||
self.form.optimizeEnabled.setCheckState(QtCore.Qt.Unchecked)
|
||||
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
self.setupCoolant(obj, self.form.coolantController)
|
||||
if obj.OptimizeStepOverTransitions:
|
||||
self.form.optimizeStepOverTransitions.setCheckState(QtCore.Qt.Checked)
|
||||
else:
|
||||
self.form.optimizeStepOverTransitions.setCheckState(QtCore.Qt.Unchecked)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
|
||||
signals = []
|
||||
signals.append(self.form.toolController.currentIndexChanged)
|
||||
signals.append(self.form.algorithmSelect.currentIndexChanged)
|
||||
signals.append(self.form.coolantController.currentIndexChanged)
|
||||
signals.append(self.form.boundBoxSelect.currentIndexChanged)
|
||||
signals.append(self.form.dropCutterDirSelect.currentIndexChanged)
|
||||
signals.append(self.form.scanType.currentIndexChanged)
|
||||
signals.append(self.form.layerMode.currentIndexChanged)
|
||||
signals.append(self.form.cutPattern.currentIndexChanged)
|
||||
signals.append(self.form.boundBoxExtraOffsetX.editingFinished)
|
||||
signals.append(self.form.boundBoxExtraOffsetY.editingFinished)
|
||||
signals.append(self.form.sampleInterval.editingFinished)
|
||||
signals.append(self.form.stepOver.editingFinished)
|
||||
signals.append(self.form.dropCutterDirSelect.currentIndexChanged)
|
||||
signals.append(self.form.depthOffset.editingFinished)
|
||||
signals.append(self.form.stepOver.editingFinished)
|
||||
signals.append(self.form.sampleInterval.editingFinished)
|
||||
signals.append(self.form.useStartPoint.stateChanged)
|
||||
signals.append(self.form.optimizeEnabled.stateChanged)
|
||||
signals.append(self.form.coolantController.currentIndexChanged)
|
||||
signals.append(self.form.optimizeStepOverTransitions.stateChanged)
|
||||
|
||||
return signals
|
||||
|
||||
def updateVisibility(self):
|
||||
if self.form.algorithmSelect.currentText() == "OCL Dropcutter":
|
||||
self.form.boundBoxExtraOffsetX.setEnabled(True)
|
||||
self.form.boundBoxExtraOffsetY.setEnabled(True)
|
||||
self.form.boundBoxSelect.setEnabled(True)
|
||||
self.form.dropCutterDirSelect.setEnabled(True)
|
||||
self.form.stepOver.setEnabled(True)
|
||||
else:
|
||||
if self.form.scanType.currentText() == "Planar":
|
||||
self.form.cutPattern.setEnabled(True)
|
||||
self.form.boundBoxExtraOffsetX.setEnabled(False)
|
||||
self.form.boundBoxExtraOffsetY.setEnabled(False)
|
||||
self.form.boundBoxSelect.setEnabled(False)
|
||||
self.form.dropCutterDirSelect.setEnabled(False)
|
||||
self.form.stepOver.setEnabled(False)
|
||||
else:
|
||||
self.form.cutPattern.setEnabled(False)
|
||||
self.form.boundBoxExtraOffsetX.setEnabled(True)
|
||||
self.form.boundBoxExtraOffsetY.setEnabled(True)
|
||||
self.form.dropCutterDirSelect.setEnabled(True)
|
||||
|
||||
def registerSignalHandlers(self, obj):
|
||||
self.form.algorithmSelect.currentIndexChanged.connect(self.updateVisibility)
|
||||
self.form.scanType.currentIndexChanged.connect(self.updateVisibility)
|
||||
|
||||
|
||||
Command = PathOpGui.SetupOperation('Surface',
|
||||
|
||||
3518
src/Mod/Path/PathScripts/PathWaterline.py
Normal file
3518
src/Mod/Path/PathScripts/PathWaterline.py
Normal file
File diff suppressed because it is too large
Load Diff
138
src/Mod/Path/PathScripts/PathWaterlineGui.py
Normal file
138
src/Mod/Path/PathScripts/PathWaterlineGui.py
Normal file
@@ -0,0 +1,138 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2020 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * Copyright (c) 2020 russ4262 <russ4262@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 FreeCADGui
|
||||
import PathScripts.PathWaterline as PathWaterline
|
||||
import PathScripts.PathGui as PathGui
|
||||
import PathScripts.PathOpGui as PathOpGui
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
__title__ = "Path Waterline Operation UI"
|
||||
__author__ = "sliptonic (Brad Collette), russ4262 (Russell Johnson)"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
__doc__ = "Waterline operation page controller and command implementation."
|
||||
|
||||
|
||||
class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
'''Page controller class for the Waterline operation.'''
|
||||
|
||||
def initPage(self, obj):
|
||||
# self.setTitle("Waterline")
|
||||
self.updateVisibility()
|
||||
|
||||
def getForm(self):
|
||||
'''getForm() ... returns UI'''
|
||||
return FreeCADGui.PySideUic.loadUi(":/panels/PageOpWaterlineEdit.ui")
|
||||
|
||||
def getFields(self, obj):
|
||||
'''getFields(obj) ... transfers values from UI to obj's proprties'''
|
||||
self.updateToolController(obj, self.form.toolController)
|
||||
|
||||
if obj.Algorithm != str(self.form.algorithmSelect.currentText()):
|
||||
obj.Algorithm = str(self.form.algorithmSelect.currentText())
|
||||
|
||||
if obj.BoundBox != str(self.form.boundBoxSelect.currentText()):
|
||||
obj.BoundBox = str(self.form.boundBoxSelect.currentText())
|
||||
|
||||
if obj.LayerMode != str(self.form.layerMode.currentText()):
|
||||
obj.LayerMode = str(self.form.layerMode.currentText())
|
||||
|
||||
if obj.CutPattern != str(self.form.cutPattern.currentText()):
|
||||
obj.CutPattern = str(self.form.cutPattern.currentText())
|
||||
|
||||
PathGui.updateInputField(obj, 'BoundaryAdjustment', self.form.boundaryAdjustment)
|
||||
|
||||
if obj.StepOver != self.form.stepOver.value():
|
||||
obj.StepOver = self.form.stepOver.value()
|
||||
|
||||
PathGui.updateInputField(obj, 'SampleInterval', self.form.sampleInterval)
|
||||
|
||||
if obj.OptimizeLinearPaths != self.form.optimizeEnabled.isChecked():
|
||||
obj.OptimizeLinearPaths = self.form.optimizeEnabled.isChecked()
|
||||
|
||||
def setFields(self, obj):
|
||||
'''setFields(obj) ... transfers obj's property values to UI'''
|
||||
self.setupToolController(obj, self.form.toolController)
|
||||
self.selectInComboBox(obj.Algorithm, self.form.algorithmSelect)
|
||||
self.selectInComboBox(obj.BoundBox, self.form.boundBoxSelect)
|
||||
self.selectInComboBox(obj.LayerMode, self.form.layerMode)
|
||||
self.selectInComboBox(obj.CutPattern, self.form.cutPattern)
|
||||
self.form.boundaryAdjustment.setText(FreeCAD.Units.Quantity(obj.BoundaryAdjustment.Value, FreeCAD.Units.Length).UserString)
|
||||
self.form.stepOver.setValue(obj.StepOver)
|
||||
self.form.sampleInterval.setText(FreeCAD.Units.Quantity(obj.SampleInterval.Value, FreeCAD.Units.Length).UserString)
|
||||
|
||||
if obj.OptimizeLinearPaths:
|
||||
self.form.optimizeEnabled.setCheckState(QtCore.Qt.Checked)
|
||||
else:
|
||||
self.form.optimizeEnabled.setCheckState(QtCore.Qt.Unchecked)
|
||||
|
||||
def getSignalsForUpdate(self, obj):
|
||||
'''getSignalsForUpdate(obj) ... return list of signals for updating obj'''
|
||||
signals = []
|
||||
signals.append(self.form.toolController.currentIndexChanged)
|
||||
signals.append(self.form.algorithmSelect.currentIndexChanged)
|
||||
signals.append(self.form.boundBoxSelect.currentIndexChanged)
|
||||
signals.append(self.form.layerMode.currentIndexChanged)
|
||||
signals.append(self.form.cutPattern.currentIndexChanged)
|
||||
signals.append(self.form.boundaryAdjustment.editingFinished)
|
||||
signals.append(self.form.stepOver.editingFinished)
|
||||
signals.append(self.form.sampleInterval.editingFinished)
|
||||
signals.append(self.form.optimizeEnabled.stateChanged)
|
||||
|
||||
return signals
|
||||
|
||||
def updateVisibility(self):
|
||||
if self.form.algorithmSelect.currentText() == 'OCL Dropcutter':
|
||||
self.form.cutPattern.setEnabled(False)
|
||||
self.form.boundaryAdjustment.setEnabled(False)
|
||||
self.form.stepOver.setEnabled(False)
|
||||
self.form.sampleInterval.setEnabled(True)
|
||||
self.form.optimizeEnabled.setEnabled(True)
|
||||
else:
|
||||
self.form.cutPattern.setEnabled(True)
|
||||
self.form.boundaryAdjustment.setEnabled(True)
|
||||
if self.form.cutPattern.currentText() == 'None':
|
||||
self.form.stepOver.setEnabled(False)
|
||||
else:
|
||||
self.form.stepOver.setEnabled(True)
|
||||
self.form.sampleInterval.setEnabled(False)
|
||||
self.form.optimizeEnabled.setEnabled(False)
|
||||
|
||||
def registerSignalHandlers(self, obj):
|
||||
self.form.algorithmSelect.currentIndexChanged.connect(self.updateVisibility)
|
||||
self.form.cutPattern.currentIndexChanged.connect(self.updateVisibility)
|
||||
|
||||
|
||||
Command = PathOpGui.SetupOperation('Waterline',
|
||||
PathWaterline.Create,
|
||||
TaskPanelOpPage,
|
||||
'Path-Waterline',
|
||||
QtCore.QT_TRANSLATE_NOOP("Waterline", "Waterline"),
|
||||
QtCore.QT_TRANSLATE_NOOP("Waterline", "Create a Waterline Operation from a model"),
|
||||
PathWaterline.SetupProperties)
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathWaterlineGui... done\n")
|
||||
@@ -73,13 +73,11 @@ def insert(filename, docname):
|
||||
def parse(inputstring):
|
||||
"parse(inputstring): returns a parsed output string"
|
||||
print("preprocessing...")
|
||||
print(inputstring)
|
||||
PathLog.track(inputstring)
|
||||
# split the input by line
|
||||
lines = inputstring.split("\n")
|
||||
output = ""
|
||||
lastcommand = None
|
||||
print(lines)
|
||||
output = [] #""
|
||||
lastcommand = None
|
||||
|
||||
for lin in lines:
|
||||
# remove any leftover trailing and preceding spaces
|
||||
@@ -91,7 +89,7 @@ def parse(inputstring):
|
||||
# remove line numbers
|
||||
lin = lin.split(" ", 1)
|
||||
if len(lin) >= 1:
|
||||
lin = lin[1]
|
||||
lin = lin[1].strip()
|
||||
else:
|
||||
continue
|
||||
|
||||
@@ -100,7 +98,8 @@ def parse(inputstring):
|
||||
continue
|
||||
if lin[0].upper() in ["G", "M"]:
|
||||
# found a G or M command: we store it
|
||||
output += lin + "\n"
|
||||
#output += lin + "\n"
|
||||
output.append(Path.Command(str(lin))) # + "\n"
|
||||
last = lin[0].upper()
|
||||
for c in lin[1:]:
|
||||
if not c.isdigit():
|
||||
@@ -110,7 +109,7 @@ def parse(inputstring):
|
||||
lastcommand = last
|
||||
elif lastcommand:
|
||||
# no G or M command: we repeat the last one
|
||||
output += lastcommand + " " + lin + "\n"
|
||||
output.append(Path.Command(str(lastcommand + " " + lin))) # + "\n"
|
||||
|
||||
print("done preprocessing.")
|
||||
return output
|
||||
|
||||
129
src/Mod/Path/PathScripts/post/gcode_pre.py
Normal file
129
src/Mod/Path/PathScripts/post/gcode_pre.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# ***************************************************************************
|
||||
# * (c) Yorik van Havre (yorik@uncreated.net) 2014 *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * 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. *
|
||||
# * *
|
||||
# * FreeCAD 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 Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with FreeCAD; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
|
||||
'''
|
||||
This is an example preprocessor file for the Path workbench. Its aim is to
|
||||
open a gcode file, parse its contents, and create the appropriate objects
|
||||
in FreeCAD.
|
||||
|
||||
Read the Path Workbench documentation to know how to create Path objects
|
||||
from GCode.
|
||||
'''
|
||||
|
||||
import os
|
||||
import Path
|
||||
import FreeCAD
|
||||
import PathScripts.PathUtils
|
||||
import PathScripts.PathLog as PathLog
|
||||
import re
|
||||
|
||||
# LEVEL = PathLog.Level.DEBUG
|
||||
LEVEL = PathLog.Level.INFO
|
||||
PathLog.setLevel(LEVEL, PathLog.thisModule())
|
||||
|
||||
if LEVEL == PathLog.Level.DEBUG:
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
|
||||
# to distinguish python built-in open function from the one declared below
|
||||
if open.__module__ in ['__builtin__', 'io']:
|
||||
pythonopen = open
|
||||
|
||||
|
||||
def open(filename):
|
||||
"called when freecad opens a file."
|
||||
PathLog.track(filename)
|
||||
docname = os.path.splitext(os.path.basename(filename))[0]
|
||||
doc = FreeCAD.newDocument(docname)
|
||||
insert(filename, doc.Name)
|
||||
|
||||
|
||||
def insert(filename, docname):
|
||||
"called when freecad imports a file"
|
||||
PathLog.track(filename)
|
||||
gfile = pythonopen(filename)
|
||||
gcode = gfile.read()
|
||||
gfile.close()
|
||||
# split on tool changes
|
||||
paths = re.split('(?=[mM]+\s?0?6)', gcode)
|
||||
# if there are any tool changes combine the preamble with the default tool
|
||||
if len(paths) > 1:
|
||||
paths = ["\n".join(paths[0:2])] + paths[2:]
|
||||
for path in paths:
|
||||
gcode = parse(path)
|
||||
doc = FreeCAD.getDocument(docname)
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Custom")
|
||||
PathScripts.PathCustom.ObjectCustom(obj)
|
||||
obj.ViewObject.Proxy = 0
|
||||
obj.Gcode = gcode
|
||||
PathScripts.PathUtils.addToJob(obj)
|
||||
obj.ToolController = PathScripts.PathUtils.findToolController(obj)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
|
||||
def parse(inputstring):
|
||||
"parse(inputstring): returns a parsed output string"
|
||||
print("preprocessing...")
|
||||
PathLog.track(inputstring)
|
||||
# split the input by line
|
||||
lines = inputstring.split("\n")
|
||||
output = [] #""
|
||||
lastcommand = None
|
||||
|
||||
for lin in lines:
|
||||
# remove any leftover trailing and preceding spaces
|
||||
lin = lin.strip()
|
||||
if not lin:
|
||||
# discard empty lines
|
||||
continue
|
||||
if lin[0].upper() in ["N"]:
|
||||
# remove line numbers
|
||||
lin = lin.split(" ", 1)
|
||||
if len(lin) >= 1:
|
||||
lin = lin[1].strip()
|
||||
else:
|
||||
continue
|
||||
|
||||
if lin[0] in ["(", "%", "#", ";"]:
|
||||
# discard comment and other non strictly gcode lines
|
||||
continue
|
||||
if lin[0].upper() in ["G", "M"]:
|
||||
# found a G or M command: we store it
|
||||
#output += lin + "\n"
|
||||
output.append(lin) # + "\n"
|
||||
last = lin[0].upper()
|
||||
for c in lin[1:]:
|
||||
if not c.isdigit():
|
||||
break
|
||||
else:
|
||||
last += c
|
||||
lastcommand = last
|
||||
elif lastcommand:
|
||||
# no G or M command: we repeat the last one
|
||||
output.append(lastcommand + " " + lin) # + "\n"
|
||||
|
||||
print("done preprocessing.")
|
||||
return output
|
||||
|
||||
print(__name__ + " gcode preprocessor loaded.")
|
||||
@@ -261,7 +261,7 @@ def export(objectslist, filename, argstring):
|
||||
return
|
||||
|
||||
# Skip inactive operations
|
||||
if not PathUtil.opProperty(obj, 'Active'):
|
||||
if PathUtil.opProperty(obj, 'Active') is False:
|
||||
continue
|
||||
|
||||
# do the pre_op
|
||||
|
||||
Reference in New Issue
Block a user