Merge pull request #432 from mlampert/HoldingTags
Path: Holding tags dressup, fixes tracker #2751
This commit is contained in:
commit
f2c884a859
|
@ -45,6 +45,7 @@ SET(PathScripts_SRCS
|
|||
PathScripts/PathPost.py
|
||||
PathScripts/PathPostProcessor.py
|
||||
PathScripts/PathPreferences.py
|
||||
PathScripts/PathPreferencesPathDressup.py
|
||||
PathScripts/PathPreferencesPathJob.py
|
||||
PathScripts/PathProfile.py
|
||||
PathScripts/PathProfileEdges.py
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<file>panels/JobEdit.ui</file>
|
||||
<file>panels/MillFaceEdit.ui</file>
|
||||
<file>panels/PocketEdit.ui</file>
|
||||
<file>panels/PointEdit.ui</file>
|
||||
<file>panels/ProfileEdgesEdit.ui</file>
|
||||
<file>panels/ProfileEdit.ui</file>
|
||||
<file>panels/RemoteEdit.ui</file>
|
||||
|
@ -65,6 +66,7 @@
|
|||
<file>panels/ToolControl.ui</file>
|
||||
<file>panels/ToolEdit.ui</file>
|
||||
<file>panels/ToolLibraryEditor.ui</file>
|
||||
<file>preferences/PathDressupHoldingTags.ui</file>
|
||||
<file>preferences/PathJob.ui</file>
|
||||
<file>translations/Path_af.qm</file>
|
||||
<file>translations/Path_cs.qm</file>
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>363</width>
|
||||
<height>530</height>
|
||||
<width>399</width>
|
||||
<height>564</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -16,6 +16,12 @@
|
|||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="2" column="0">
|
||||
<widget class="QToolBox" name="toolBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
|
@ -27,8 +33,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>345</width>
|
||||
<height>476</height>
|
||||
<width>381</width>
|
||||
<height>510</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
|
@ -48,13 +54,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbWidth">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Specify the resulting width of tags at the base.</p><p>The initial default width is based on the longest edge found in the base path.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
|
@ -62,13 +61,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbHeight">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Height of holding tags.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
|
@ -76,10 +68,50 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::InputField" name="ifWidth">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Width of the resulting holding tag.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::InputField" name="ifHeight">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Height of holding tag.</p><p>Note that resulting tag might be smaller if the tag's width and angle result in a triangular shape.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbAngle">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Angle of ascend and descend of the tool for the holding tag cutout.</p><p><br/></p><p>If the angle is too flat for the given width to reach the specified height the resulting tag will have a triangular shape and not as high as specified.</p></body></html></string>
|
||||
<string><html><head/><body><p>Plunge angle for ascent and descent of holding tag.</p></body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>15.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>45.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Radius</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::InputField" name="ifRadius">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Radius of the fillet at the top.</p><p>If the radius is too big for the tag shape it gets reduced to the maximum possible radius - resulting in a spherical shape.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -89,14 +121,14 @@
|
|||
<item>
|
||||
<widget class="QListWidget" name="lwTags">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>List of current tags.</p><p>Edit coordinates to move tag or invoker snapper tool.</p></body></html></string>
|
||||
<string><html><head/><body><p>List of current tags. Edit coordinates by double click or Edit button.</p><p>Tags are automatically disabled if they overlap with the previous tag, or don't lie on the base wire.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="pbDelete">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
|
@ -106,13 +138,23 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<item row="1" column="2">
|
||||
<widget class="QPushButton" name="pbAdd">
|
||||
<property name="text">
|
||||
<string>Add...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="pbEdit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Edit...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -123,7 +165,11 @@
|
|||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="sbCount"/>
|
||||
<widget class="QSpinBox" name="sbCount">
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="pbGenerate">
|
||||
|
@ -154,6 +200,13 @@
|
|||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::InputField</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Gui/InputField.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
|
78
src/Mod/Path/Gui/Resources/panels/PointEdit.ui
Normal file
78
src/Mod/Path/Gui/Resources/panels/PointEdit.ui
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?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>362</width>
|
||||
<height>182</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Point Edit</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="wPoint" native="true">
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lValueX">
|
||||
<property name="text">
|
||||
<string>Global X</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::InputField" name="ifValueX"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lValueY">
|
||||
<property name="text">
|
||||
<string>Global Y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::InputField" name="ifValueY"/>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lValueZ">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Global Z</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::InputField" name="ifValueZ">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignHCenter">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::InputField</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Gui/InputField.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
147
src/Mod/Path/Gui/Resources/preferences/PathDressupHoldingTags.ui
Normal file
147
src/Mod/Path/Gui/Resources/preferences/PathDressupHoldingTags.ui
Normal file
|
@ -0,0 +1,147 @@
|
|||
<?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>477</width>
|
||||
<height>478</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Tag Parameters</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::InputField" name="ifWidth">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Set the default width of holding tags.</p><p>If the width is set to 0 the dressup will try to guess a reasonable value based on the path itself.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Default Width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QDoubleSpinBox" name="dsbAngle">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Plunge angle for the holding tags ascent and descent.</p></body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>5.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>90.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>15.000000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>45.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::InputField" name="ifHeight">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Default height of holding tags.</p><p>If the specified height is 0 the dressup will use half the height of the part. Should the height be bigger than the height of the part the dressup will reduce the height to the height of the part.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Default Angle</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Default Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::InputField" name="ifRadius">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Radius of the fillet on the tag's top edge.</p><p>If the radius is bigger than than the tag shape itself supports the resulting shape will be that of a dome.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Default Radius</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Tag Generation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Initial # Tags </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSpinBox" name="sbCount">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Specify the number of tags generated when a new dressup is created.</p></body></html></string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>4</number>
|
||||
</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>
|
|
@ -31,8 +31,9 @@ class PathWorkbench (Workbench):
|
|||
|
||||
def Initialize(self):
|
||||
# Add preferences pages - before loading PathGui to properly order pages of Path group
|
||||
from PathScripts import PathPreferencesPathJob
|
||||
FreeCADGui.addPreferencePage(PathPreferencesPathJob.Page, "Path")
|
||||
from PathScripts import PathPreferencesPathJob, PathPreferencesPathDressup
|
||||
FreeCADGui.addPreferencePage(PathPreferencesPathJob.JobPreferencesPage, "Path")
|
||||
FreeCADGui.addPreferencePage(PathPreferencesPathDressup.DressupPreferencesPage, "Path")
|
||||
|
||||
# load the builtin modules
|
||||
import Path
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,6 +29,8 @@ import Path
|
|||
|
||||
from FreeCAD import Vector
|
||||
|
||||
PathGeomTolerance = 0.000001
|
||||
|
||||
class Side:
|
||||
"""Class to determine and define the side a Path is on, or Vectors are in relation to each other."""
|
||||
Left = +1
|
||||
|
@ -70,22 +72,24 @@ class PathGeom:
|
|||
CmdMoveArc = CmdMoveCW + CmdMoveCCW
|
||||
CmdMove = CmdMoveStraight + CmdMoveArc
|
||||
|
||||
Tolerance = PathGeomTolerance
|
||||
|
||||
@classmethod
|
||||
def isRoughly(cls, float1, float2, error=0.0000001):
|
||||
"""(float1, float2, [error=0.0000001])
|
||||
Returns true if the two values are the same within a given error."""
|
||||
def isRoughly(cls, float1, float2, error=PathGeomTolerance):
|
||||
"""(float1, float2, [error=%s])
|
||||
Returns true if the two values are the same within a given error.""" % PathGeomTolerance
|
||||
return math.fabs(float1 - float2) <= error
|
||||
|
||||
@classmethod
|
||||
def pointsCoincide(cls, p1, p2, error=0.0000001):
|
||||
"""(p1, p2, [error=0.0000001])
|
||||
Return True if two points are roughly identical (see also isRoughly)."""
|
||||
def pointsCoincide(cls, p1, p2, error=PathGeomTolerance):
|
||||
"""(p1, p2, [error=%s])
|
||||
Return True if two points are roughly identical (see also isRoughly).""" % PathGeomTolerance
|
||||
return cls.isRoughly(p1.x, p2.x, error) and cls.isRoughly(p1.y, p2.y, error) and cls.isRoughly(p1.z, p2.z, error)
|
||||
|
||||
@classmethod
|
||||
def edgesMatch(cls, e0, e1, error=0.0000001):
|
||||
"""(e0, e1, [error=0.0000001]
|
||||
Return true if the edges start and end at the same point and have the same type of curve."""
|
||||
def edgesMatch(cls, e0, e1, error=PathGeomTolerance):
|
||||
"""(e0, e1, [error=%s]
|
||||
Return true if the edges start and end at the same point and have the same type of curve.""" % PathGeomTolerance
|
||||
if type(e0.Curve) != type(e1.Curve):
|
||||
return False
|
||||
if not cls.pointsCoincide(e0.valueAt(e0.FirstParameter), e1.valueAt(e1.FirstParameter)):
|
||||
|
@ -95,9 +99,9 @@ class PathGeom:
|
|||
return True
|
||||
|
||||
@classmethod
|
||||
def edgeConnectsTo(cls, edge, vector):
|
||||
"""(edge, vector)
|
||||
Returns True if edge connects to given vector."""
|
||||
def edgeConnectsTo(cls, edge, vector, error=PathGeomTolerance):
|
||||
"""(edge, vector, error=%f)
|
||||
Returns True if edge connects to given vector.""" % PathGeomTolerance
|
||||
return cls.pointsCoincide(edge.valueAt(edge.FirstParameter), vector) or cls.pointsCoincide(edge.valueAt(edge.LastParameter), vector)
|
||||
|
||||
@classmethod
|
||||
|
@ -106,7 +110,7 @@ class PathGeom:
|
|||
Returns the angle [-pi,pi] of a vector using the X-axis as the reference.
|
||||
Positive angles for vertexes in the upper hemishpere (positive y values)
|
||||
and negative angles for the lower hemishpere."""
|
||||
a = vector.getAngle(FreeCAD.Vector(1,0,0))
|
||||
a = vector.getAngle(Vector(1,0,0))
|
||||
if vector.y < 0:
|
||||
return -a
|
||||
return a
|
||||
|
@ -132,7 +136,7 @@ class PathGeom:
|
|||
x = cmd.Parameters.get(X, defaultPoint.x)
|
||||
y = cmd.Parameters.get(Y, defaultPoint.y)
|
||||
z = cmd.Parameters.get(Z, defaultPoint.z)
|
||||
return FreeCAD.Vector(x, y, z)
|
||||
return Vector(x, y, z)
|
||||
|
||||
@classmethod
|
||||
def xy(cls, point):
|
||||
|
@ -162,12 +166,12 @@ class PathGeom:
|
|||
p1 = pt
|
||||
p3 = edge.valueAt(edge.LastParameter)
|
||||
p2 = edge.valueAt((edge.FirstParameter + edge.LastParameter)/2)
|
||||
if type(edge.Curve) == Part.Circle or (useHelixForBSpline and type(edge.Curve) == Part.BSplineCurve):
|
||||
if (type(edge.Curve) == Part.Circle and cls.pointsCoincide(edge.Curve.Axis, Vector(0, 0, 1))) or (useHelixForBSpline and type(edge.Curve) == Part.BSplineCurve):
|
||||
if Side.Left == Side.of(p2 - p1, p3 - p2):
|
||||
cmd = 'G3'
|
||||
else:
|
||||
cmd = 'G2'
|
||||
#print("**** (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f)" % (p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z))
|
||||
print("**** (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f)" % (p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, p3.x, p3.y, p3.z))
|
||||
pd = Part.Circle(PathGeom.xy(p1), PathGeom.xy(p2), PathGeom.xy(p3)).Center
|
||||
|
||||
pa = PathGeom.xy(p1)
|
||||
|
@ -232,7 +236,7 @@ class PathGeom:
|
|||
#print("arc: A=(%.2f, %.2f) B=(%.2f, %.2f) -> d=%.2f" % (A.x, A.y, B.x, B.y, d))
|
||||
#print("arc: R=%.2f angle=%.2f" % (R, angle/math.pi))
|
||||
if startPoint.z == endPoint.z:
|
||||
midPoint = center + FreeCAD.Vector(math.cos(angle), math.sin(angle), 0) * R
|
||||
midPoint = center + Vector(math.cos(angle), math.sin(angle), 0) * R
|
||||
return Part.Edge(Part.Arc(startPoint, midPoint, endPoint))
|
||||
|
||||
# It's a Helix
|
||||
|
@ -255,7 +259,7 @@ class PathGeom:
|
|||
return None
|
||||
|
||||
@classmethod
|
||||
def wireForPath(cls, path, startPoint = FreeCAD.Vector(0, 0, 0)):
|
||||
def wireForPath(cls, path, startPoint = Vector(0, 0, 0)):
|
||||
"""(path, [startPoint=Vector(0,0,0)])
|
||||
Returns a wire representing all move commands found in the given path."""
|
||||
edges = []
|
||||
|
@ -271,7 +275,7 @@ class PathGeom:
|
|||
return (Part.Wire(edges), rapid)
|
||||
|
||||
@classmethod
|
||||
def wiresForPath(cls, path, startPoint = FreeCAD.Vector(0, 0, 0)):
|
||||
def wiresForPath(cls, path, startPoint = Vector(0, 0, 0)):
|
||||
"""(path, [startPoint=Vector(0,0,0)])
|
||||
Returns a collection of wires, each representing a continuous cutting Path in path."""
|
||||
wires = []
|
||||
|
@ -306,7 +310,7 @@ class PathGeom:
|
|||
#print("- (%.2f, %.2f, %.2f) - (%.2f, %.2f, %.2f): %.2f:%.2f" % (edge.Vertexes[0].X, edge.Vertexes[0].Y, edge.Vertexes[0].Z, edge.Vertexes[1].X, edge.Vertexes[1].Y, edge.Vertexes[1].Z, z0, z1))
|
||||
#print("- %s -> %s" % (cmd, command))
|
||||
|
||||
return cls.edgeForCmd(command, FreeCAD.Vector(p1.x, p1.y, z0))
|
||||
return cls.edgeForCmd(command, Vector(p1.x, p1.y, z0))
|
||||
|
||||
|
||||
@classmethod
|
||||
|
@ -316,9 +320,9 @@ class PathGeom:
|
|||
p1 = edge.valueAt(edge.FirstParameter)
|
||||
p2 = edge.valueAt((edge.FirstParameter + edge.LastParameter)/2)
|
||||
p3 = edge.valueAt(edge.LastParameter)
|
||||
p01 = FreeCAD.Vector(p1.x, p1.y, z)
|
||||
p02 = FreeCAD.Vector(p2.x, p2.y, z)
|
||||
p03 = FreeCAD.Vector(p3.x, p3.y, z)
|
||||
p01 = Vector(p1.x, p1.y, z)
|
||||
p02 = Vector(p2.x, p2.y, z)
|
||||
p03 = Vector(p3.x, p3.y, z)
|
||||
return Part.Edge(Part.Arc(p01, p02, p03))
|
||||
|
||||
@classmethod
|
||||
|
@ -364,6 +368,6 @@ class PathGeom:
|
|||
else:
|
||||
# it's a helix
|
||||
arc = cls.helixToArc(edge, 0)
|
||||
aes = cls.splitArcAt(arc, FreeCAD.Vector(pt.x, pt.y, 0))
|
||||
aes = cls.splitArcAt(arc, Vector(pt.x, pt.y, 0))
|
||||
return [cls.arcToHelix(aes[0], p1.z, p2.z), cls.arcToHelix(aes[1], p2.z, p3.z)]
|
||||
|
||||
|
|
|
@ -31,6 +31,10 @@ class PathPreferences:
|
|||
PostProcessorDefaultArgs = "PostProcessorDefaultArgs"
|
||||
PostProcessorBlacklist = "PostProcessorBlacklist"
|
||||
|
||||
@classmethod
|
||||
def preferences(cls):
|
||||
return FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
|
||||
@classmethod
|
||||
def allAvailablePostProcessors(cls):
|
||||
path = FreeCAD.getHomePath() + ("Mod/Path/PathScripts/")
|
||||
|
@ -58,28 +62,28 @@ class PathPreferences:
|
|||
|
||||
@classmethod
|
||||
def defaultPostProcessor(cls):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
return preferences.GetString(cls.PostProcessorDefault, "")
|
||||
pref = cls.preferences()
|
||||
return pref.GetString(cls.PostProcessorDefault, "")
|
||||
|
||||
@classmethod
|
||||
def defaultPostProcessorArgs(cls):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
return preferences.GetString(cls.PostProcessorDefaultArgs, "")
|
||||
pref = cls.preferences()
|
||||
return pref.GetString(cls.PostProcessorDefaultArgs, "")
|
||||
|
||||
@classmethod
|
||||
def postProcessorBlacklist(cls):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
blacklist = preferences.GetString(cls.PostProcessorBlacklist, "")
|
||||
pref = cls.preferences()
|
||||
blacklist = pref.GetString(cls.PostProcessorBlacklist, "")
|
||||
if not blacklist:
|
||||
return []
|
||||
return eval(blacklist)
|
||||
|
||||
@classmethod
|
||||
def savePostProcessorDefaults(cls, processor, args, blacklist):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
preferences.SetString(cls.PostProcessorDefault, processor)
|
||||
preferences.SetString(cls.PostProcessorDefaultArgs, args)
|
||||
preferences.SetString(cls.PostProcessorBlacklist, "%s" % (blacklist))
|
||||
pref = cls.preferences()
|
||||
pref.SetString(cls.PostProcessorDefault, processor)
|
||||
pref.SetString(cls.PostProcessorDefaultArgs, args)
|
||||
pref.SetString(cls.PostProcessorBlacklist, "%s" % (blacklist))
|
||||
|
||||
|
||||
DefaultOutputFile = "DefaultOutputFile"
|
||||
|
@ -87,16 +91,16 @@ class PathPreferences:
|
|||
|
||||
@classmethod
|
||||
def saveOutputFileDefaults(cls, file, policy):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
preferences.SetString(cls.DefaultOutputFile, file)
|
||||
preferences.SetString(cls.DefaultOutputPolicy, policy)
|
||||
pref = cls.preferences()
|
||||
pref.SetString(cls.DefaultOutputFile, file)
|
||||
pref.SetString(cls.DefaultOutputPolicy, policy)
|
||||
|
||||
@classmethod
|
||||
def defaultOutputFile(cls):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
return preferences.GetString(cls.DefaultOutputFile, "")
|
||||
pref = cls.preferences()
|
||||
return pref.GetString(cls.DefaultOutputFile, "")
|
||||
|
||||
@classmethod
|
||||
def defaultOutputPolicy(cls):
|
||||
preferences = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
return preferences.GetString(cls.DefaultOutputPolicy, "")
|
||||
pref = cls.preferences()
|
||||
return pref.GetString(cls.DefaultOutputPolicy, "")
|
||||
|
|
68
src/Mod/Path/PathScripts/PathPreferencesPathDressup.py
Normal file
68
src/Mod/Path/PathScripts/PathPreferencesPathDressup.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2016 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program is distributed in the hope that it will be useful, *
|
||||
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
# * GNU Library General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Library General Public *
|
||||
# * License along with this program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from PySide import QtCore, QtGui
|
||||
from PathScripts.PathPreferences import PathPreferences
|
||||
|
||||
# Qt tanslation handling
|
||||
try:
|
||||
_encoding = QtGui.QApplication.UnicodeUTF8
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return QtGui.QApplication.translate(context, text, disambig, _encoding)
|
||||
|
||||
except AttributeError:
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return QtGui.QApplication.translate(context, text, disambig)
|
||||
|
||||
_dressups = []
|
||||
|
||||
def RegisterDressup(dressup):
|
||||
_dressups.append(dressup)
|
||||
|
||||
class DressupPreferencesPage:
|
||||
def __init__(self, parent=None):
|
||||
self.form = QtGui.QToolBox()
|
||||
self.form.setWindowTitle(translate('PathPreferencesPathDressup', 'Dressups'))
|
||||
pages = []
|
||||
for dressup in _dressups:
|
||||
page = dressup.preferencesPage()
|
||||
if hasattr(page, 'icon') and page.icon:
|
||||
self.form.addItem(page.form, page.icon, page.label)
|
||||
else:
|
||||
self.form.addItem(page.form, page.label)
|
||||
pages.append(page)
|
||||
self.pages = pages
|
||||
|
||||
def saveSettings(self):
|
||||
for page in self.pages:
|
||||
page.saveSettings()
|
||||
|
||||
def loadSettings(self):
|
||||
for page in self.pages:
|
||||
page.loadSettings()
|
||||
|
|
@ -29,7 +29,7 @@ from PathScripts.PathPreferences import PathPreferences
|
|||
from PathScripts.PathPostProcessor import PostProcessor
|
||||
|
||||
|
||||
class Page:
|
||||
class JobPreferencesPage:
|
||||
def __init__(self, parent=None):
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":preferences/PathJob.ui")
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user