Merge pull request #4014 from sliptonic/feature/toolbitdock
[PATH] Feature/toolbitdock
This commit is contained in:
@@ -154,26 +154,28 @@ SET(PathScripts_post_SRCS
|
||||
)
|
||||
|
||||
SET(Tools_Bit_SRCS
|
||||
Tools/Bit/t1.fctb
|
||||
Tools/Bit/t2.fctb
|
||||
Tools/Bit/t3.fctb
|
||||
Tools/Bit/t4.fctb
|
||||
Tools/Bit/t5.fctb
|
||||
Tools/Bit/t6.fctb
|
||||
Tools/Bit/t7.fctb
|
||||
Tools/Bit/t8.fctb
|
||||
Tools/Bit/t9.fctb
|
||||
Tools/Bit/45degree_chamfer.fctb
|
||||
Tools/Bit/5mm_Drill.fctb
|
||||
Tools/Bit/5mm_Endmill.fctb
|
||||
Tools/Bit/60degree_Vbit.fctb
|
||||
Tools/Bit/6mm_Ball_End.fctb
|
||||
Tools/Bit/6mm_Bullnose.fctb
|
||||
Tools/Bit/slittingsaw.fctb
|
||||
Tools/Bit/probe.fctb
|
||||
)
|
||||
|
||||
SET(Tools_Library_SRCS
|
||||
Tools/Library/endmills.fctl
|
||||
Tools/Library/Default.fctl
|
||||
)
|
||||
|
||||
SET(Tools_Shape_SRCS
|
||||
Tools/Shape/ballend.fcstd
|
||||
Tools/Shape/bullnose.fcstd
|
||||
Tools/Shape/drill.fcstd
|
||||
Tools/Shape/chamfer.fcstd
|
||||
Tools/Shape/endmill.fcstd
|
||||
Tools/Shape/probe.fcstd
|
||||
Tools/Shape/slittingsaw.fcstd
|
||||
Tools/Shape/v-bit.fcstd
|
||||
)
|
||||
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<class>ToolBitAttributes</class>
|
||||
<widget class="QWidget" name="ToolBitAttributes">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>587</width>
|
||||
<height>744</height>
|
||||
<width>401</width>
|
||||
<height>715</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
<string>Tool Bit Attributes</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
@@ -114,7 +120,7 @@
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::InputField" name="toolCuttingEdgeAngle">
|
||||
<property name="text">
|
||||
<string>180°</string>
|
||||
<string>0 °</string>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string>°</string>
|
||||
@@ -131,7 +137,7 @@
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::InputField" name="toolCuttingEdgeHeight">
|
||||
<property name="text">
|
||||
<string>0.00</string>
|
||||
<string>0 mm</string>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string>mm</string>
|
||||
|
||||
@@ -11,297 +11,11 @@
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>ToolBit Library</string>
|
||||
<string>Library Manager</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QWidget" name="toolTableGroup" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="verticalWidget" native="true">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>226</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="ToolTable">
|
||||
<property name="text">
|
||||
<string>Tool Libraries</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonRenameToolTable">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Rename Tool Table</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/edit-edit.svg</normaloff>:/icons/edit-edit.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonAddToolTable">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Add New Tool Table</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/list-add.svg</normaloff>:/icons/list-add.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonRemoveToolTable">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>32</width>
|
||||
<height>32</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Remove Tool Table from Disc</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/list-remove.svg</normaloff>:/icons/list-remove.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="TableList">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTableView" name="toolTable">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Table of Tool Bits of the library.</p></body></html></string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="midLineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::InternalMove</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::MoveAction</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="addToolController">
|
||||
<property name="text">
|
||||
<string>Add Tool Controller(s) to Job</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/edit_OK.svg</normaloff>:/icons/edit_OK.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="libraryCancel">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Close the Tool Bit Library Editor</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/button_invalid.svg</normaloff>:/icons/button_invalid.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="librarySave">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Save the current Library</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save Table</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/document-save.svg</normaloff>:/icons/document-save.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="librarySaveAs">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Save the library to a new file</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save Table As...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/document-save-as.svg</normaloff>:/icons/document-save-as.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineLibPath">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>420</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="libraryOpen">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select the folder with the tool libraries to load.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/document-open.svg</normaloff>:/icons/document-open.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
@@ -315,22 +29,45 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolCreate">
|
||||
<property name="text">
|
||||
<string>Create Toolbit</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Path.qrc">
|
||||
<normaloff>:/icons/Path-ToolBit.svg</normaloff>:/icons/Path-ToolBit.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolAdd">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Add existing Tool Bit to this library.</p><p><br/></p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add Toolbit</string>
|
||||
<string>Add Existing</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/list-add.svg</normaloff>:/icons/list-add.svg</iconset>
|
||||
<iconset resource="../Path.qrc">
|
||||
<normaloff>:/icons/Path-ToolDuplicate.svg</normaloff>:/icons/Path-ToolDuplicate.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolDelete">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Delete selected Tool Bit(s) from the library.</p><p><br/></p></body></html></string>
|
||||
</property>
|
||||
@@ -343,17 +80,194 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="toolTableGroup" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="libraryOpen">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select a working path for the tool library editor.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/document-open.svg</normaloff>:/icons/document-open.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="addToolTable">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Add New Tool Table</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/document-new.svg</normaloff>:/icons/document-new.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="libraryExport">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Save the selected library with a new name or export to another format</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/document-save.svg</normaloff>:/icons/document-save.svg</iconset>
|
||||
</property>
|
||||
</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>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTreeView" name="TableList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTableView" name="toolTable">
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Table of Tool Bits of the library.</p></body></html></string>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Sunken</enum>
|
||||
</property>
|
||||
<property name="lineWidth">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="midLineWidth">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="dragEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropOverwriteMode">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DragOnly</enum>
|
||||
</property>
|
||||
<property name="defaultDropAction">
|
||||
<enum>Qt::IgnoreAction</enum>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolEnumerate">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>65555555</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="librarySave">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Assign numbers to each Tool Bit according to its current position in the library. The first Tool Bit is assigned the ID 1.</p></body></html></string>
|
||||
<string><html><head/><body><p>Save the current Library</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enumerate</string>
|
||||
<string>Close</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/button_sort.svg</normaloff>:/icons/button_sort.svg</iconset>
|
||||
<normaloff>:/icons/edit_OK.svg</normaloff>:/icons/edit_OK.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -363,6 +277,7 @@
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="../../../../../Gui/Icons/resource.qrc"/>
|
||||
<include location="../Path.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -1,119 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog</class>
|
||||
<widget class="QDialog" name="Dialog">
|
||||
<class>ToolSelector</class>
|
||||
<widget class="QDockWidget" name="ToolSelector">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>588</width>
|
||||
<height>396</height>
|
||||
<width>350</width>
|
||||
<height>542</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="windowTitle">
|
||||
<string>Tool Selector</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="dockWidgetContents">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lblLibrary">
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="libraryEditorOpen">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Path.qrc">
|
||||
<normaloff>:/icons/Path-ToolTable.svg</normaloff>:/icons/Path-ToolTable.svg</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QListWidget" name="tools">
|
||||
<widget class="QTreeView" name="tools">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Available Tool Bits to choose from.</p></body></html></string>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolLoad">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Load an existing Tool Bit from a file.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Load...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="toolCreate">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Create a new Tool Bit based on an existing shape.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>New</string>
|
||||
</property>
|
||||
</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>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="addToolController">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Create ToolControllers for the selected toolbits and add them to the Job</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add To Job</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../../../../Gui/Icons/resource.qrc">
|
||||
<normaloff>:/icons/edit_OK.svg</normaloff>:/icons/edit_OK.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>Dialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
<resources>
|
||||
<include location="../../../../../Gui/Icons/resource.qrc"/>
|
||||
<include location="../Path.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -76,20 +76,13 @@ class PathWorkbench (Workbench):
|
||||
|
||||
from PathScripts import PathToolBitCmd
|
||||
from PathScripts import PathToolBitLibraryCmd
|
||||
if PathPreferences.experimentalFeaturesEnabled():
|
||||
toolbitcmdlist = PathToolBitCmd.CommandList + ["Separator"] + PathToolBitLibraryCmd.CommandList + ["Path_ToolController", "Separator"]
|
||||
self.toolbitctxmenu = ["Path_ToolBitLibraryLoad", "Path_ToolController"]
|
||||
else:
|
||||
toolbitcmdlist = []
|
||||
self.toolbitctxmenu = []
|
||||
|
||||
import PathCommands
|
||||
PathGuiInit.Startup()
|
||||
|
||||
# build commands list
|
||||
projcmdlist = ["Path_Job", "Path_Post"]
|
||||
toolcmdlist = ["Path_Inspect", "Path_Simulator",
|
||||
"Path_ToolLibraryEdit", "Path_SelectLoop",
|
||||
toolcmdlist = ["Path_Inspect", "Path_Simulator", "Path_SelectLoop",
|
||||
"Path_OpActiveToggle"]
|
||||
prepcmdlist = ["Path_Fixture", "Path_Comment", "Path_Stop",
|
||||
"Path_Custom", "Path_Probe"]
|
||||
@@ -107,6 +100,16 @@ class PathWorkbench (Workbench):
|
||||
# modcmdmore = ["Path_Hop",]
|
||||
# remotecmdlist = ["Path_Remote"]
|
||||
|
||||
|
||||
if PathPreferences.toolsReallyUseLegacyTools():
|
||||
toolcmdlist.append("Path_ToolLibraryEdit")
|
||||
toolbitcmdlist = []
|
||||
else:
|
||||
toolcmdlist.extend(PathToolBitLibraryCmd.BarList)
|
||||
toolbitcmdlist = PathToolBitLibraryCmd.MenuList
|
||||
|
||||
|
||||
|
||||
engravecmdgroup = ['Path_EngraveTools']
|
||||
FreeCADGui.addCommand('Path_EngraveTools', PathCommandGroup(engravecmdlist, QtCore.QT_TRANSLATE_NOOP("Path", 'Engraving Operations')))
|
||||
|
||||
@@ -134,7 +137,7 @@ class PathWorkbench (Workbench):
|
||||
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"] +
|
||||
toolcmdlist + toolbitcmdlist + ["Separator"] + twodopcmdlist + engravecmdlist + ["Separator"] +
|
||||
threedopcmdlist + ["Separator"])
|
||||
self.appendMenu([QtCore.QT_TRANSLATE_NOOP("Path", "&Path"), QtCore.QT_TRANSLATE_NOOP(
|
||||
"Path", "Path Dressup")], dressupcmdlist)
|
||||
|
||||
@@ -94,6 +94,13 @@ def createModelResourceClone(obj, orig):
|
||||
return createResourceClone(obj, orig, 'Model', 'BaseGeometry')
|
||||
|
||||
|
||||
class NotificationClass(QtCore.QObject):
|
||||
updateTC = QtCore.Signal(object, object)
|
||||
|
||||
|
||||
Notification = NotificationClass()
|
||||
|
||||
|
||||
class ObjectJob:
|
||||
|
||||
def __init__(self, obj, models, templateFile=None):
|
||||
@@ -261,6 +268,7 @@ class ObjectJob:
|
||||
self.setupBaseModel(obj)
|
||||
self.fixupOperations(obj)
|
||||
self.setupSetupSheet(obj)
|
||||
|
||||
obj.setEditorMode('Operations', 2) # hide
|
||||
obj.setEditorMode('Placement', 2)
|
||||
|
||||
@@ -413,6 +421,7 @@ class ObjectJob:
|
||||
tc.setExpression('HorizRapid', "%s.%s" % (self.setupSheet.expressionReference(), PathSetupSheet.Template.HorizRapid))
|
||||
group.append(tc)
|
||||
self.obj.ToolController = group
|
||||
Notification.updateTC.emit(self.obj, tc)
|
||||
|
||||
def allOperations(self):
|
||||
ops = []
|
||||
|
||||
@@ -25,7 +25,6 @@ from collections import Counter
|
||||
from contextlib import contextmanager
|
||||
import math
|
||||
import traceback
|
||||
|
||||
from pivy import coin
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
@@ -45,6 +44,7 @@ import PathScripts.PathToolControllerGui as PathToolControllerGui
|
||||
import PathScripts.PathToolLibraryEditor as PathToolLibraryEditor
|
||||
import PathScripts.PathUtil as PathUtil
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
import PathScripts.PathToolBitGui as PathToolBitGui
|
||||
|
||||
# lazily loaded modules
|
||||
from lazy_loader.lazy_loader import LazyLoader
|
||||
@@ -866,7 +866,15 @@ class TaskPanel:
|
||||
self.toolControllerSelect()
|
||||
|
||||
def toolControllerAdd(self):
|
||||
PathToolLibraryEditor.CommandToolLibraryEdit().edit(self.obj, self.updateToolController)
|
||||
if PathPreferences.toolsUseLegacyTools():
|
||||
PathToolLibraryEditor.CommandToolLibraryEdit().edit(self.obj, self.updateToolController)
|
||||
else:
|
||||
tools = PathToolBitGui.LoadTools()
|
||||
for tool in tools:
|
||||
tc = PathToolControllerGui.Create(name=tool.Label, tool=tool)
|
||||
self.obj.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
self.updateToolController()
|
||||
|
||||
def toolControllerDelete(self):
|
||||
self.objectDelete(self.form.toolControllerList)
|
||||
|
||||
@@ -25,6 +25,7 @@ import FreeCADGui
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathScripts.PathGetPoint as PathGetPoint
|
||||
import PathScripts.PathGui as PathGui
|
||||
import PathScripts.PathJob as PathJob
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathOp as PathOp
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
@@ -211,6 +212,9 @@ class TaskPanelPage(object):
|
||||
self.parent = None
|
||||
self.panelTitle = 'Operation'
|
||||
|
||||
if hasattr(self.form, 'toolController'):
|
||||
PathJob.Notification.updateTC.connect(self.resetToolController)
|
||||
|
||||
def setParent(self, parent):
|
||||
'''setParent() ... used to transfer parent object link to child class.
|
||||
Do not overwrite.'''
|
||||
@@ -361,6 +365,12 @@ class TaskPanelPage(object):
|
||||
combo.setCurrentIndex(index)
|
||||
combo.blockSignals(False)
|
||||
|
||||
def resetToolController(self, job, tc):
|
||||
if self.obj is not None:
|
||||
self.obj.ToolController = tc
|
||||
combo = self.form.toolController
|
||||
self.setupToolController(self.obj, combo)
|
||||
|
||||
def setupToolController(self, obj, combo):
|
||||
'''setupToolController(obj, combo) ...
|
||||
helper function to setup obj's ToolController
|
||||
@@ -535,7 +545,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
PathLog.error(translate("PathProject", "Faces are not supported"))
|
||||
return False
|
||||
else:
|
||||
if not self.supportsPanels() or not 'Panel' in sel.Object.Name:
|
||||
if not self.supportsPanels() or 'Panel' not in sel.Object.Name:
|
||||
if not ignoreErrors:
|
||||
PathLog.error(translate("PathProject", "Please select %s of a solid" % self.featureName()))
|
||||
return False
|
||||
@@ -626,6 +636,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
row = (qList.count() + qList.frameWidth()) * 15
|
||||
qList.setFixedSize(col, row)
|
||||
|
||||
|
||||
class TaskPanelBaseLocationPage(TaskPanelPage):
|
||||
'''Page controller for base locations. Uses PathGetPoint.'''
|
||||
|
||||
@@ -926,6 +937,7 @@ class TaskPanelDepthsPage(TaskPanelPage):
|
||||
self.form.startDepthSet.setEnabled(False)
|
||||
self.form.finalDepthSet.setEnabled(False)
|
||||
|
||||
|
||||
class TaskPanelDiametersPage(TaskPanelPage):
|
||||
'''Page controller for diameters.'''
|
||||
|
||||
@@ -950,7 +962,7 @@ class TaskPanelDiametersPage(TaskPanelPage):
|
||||
self.minDiameter.updateProperty()
|
||||
self.maxDiameter.updateProperty()
|
||||
|
||||
def setFields(self, obj):
|
||||
def setFields(self, obj):
|
||||
self.minDiameter.updateSpinBox()
|
||||
self.maxDiameter.updateSpinBox()
|
||||
|
||||
@@ -964,6 +976,7 @@ class TaskPanelDiametersPage(TaskPanelPage):
|
||||
if prop in ['MinDiameter', 'MaxDiameter']:
|
||||
self.setFields(obj)
|
||||
|
||||
|
||||
class TaskPanel(object):
|
||||
'''
|
||||
Generic TaskPanel implementation handling the standard Path operation layout.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2014 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
@@ -25,8 +27,8 @@ import glob
|
||||
import os
|
||||
import PathScripts.PathLog as PathLog
|
||||
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
#PathLog.trackModule()
|
||||
# PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
# PathLog.trackModule()
|
||||
|
||||
DefaultFilePath = "DefaultFilePath"
|
||||
DefaultJobTemplate = "DefaultJobTemplate"
|
||||
@@ -42,15 +44,19 @@ PostProcessorOutputPolicy = "PostProcessorOutputPolicy"
|
||||
LastPathToolBit = "LastPathToolBit"
|
||||
LastPathToolLibrary = "LastPathToolLibrary"
|
||||
LastPathToolShape = "LastPathToolShape"
|
||||
LastPathToolTable ="LastPathToolTable"
|
||||
LastPathToolTable = "LastPathToolTable"
|
||||
|
||||
LastFileToolBit = "LastFileToolBit"
|
||||
LastFileToolLibrary = "LastFileToolLibrary"
|
||||
LastFileToolShape = "LastFileToolShape"
|
||||
|
||||
UseLegacyTools = "UseLegacyTools"
|
||||
UseAbsoluteToolPaths = "UseAbsoluteToolPaths"
|
||||
OpenLastLibrary = "OpenLastLibrary"
|
||||
|
||||
# Linear tolerance to use when generating Paths, eg when tessellating geometry
|
||||
GeometryTolerance = "GeometryTolerance"
|
||||
LibAreaCurveAccuracy = "LibAreaCurveAccuarcy"
|
||||
GeometryTolerance = "GeometryTolerance"
|
||||
LibAreaCurveAccuracy = "LibAreaCurveAccuarcy"
|
||||
|
||||
EnableExperimentalFeatures = "EnableExperimentalFeatures"
|
||||
|
||||
@@ -58,58 +64,70 @@ EnableExperimentalFeatures = "EnableExperimentalFeatures"
|
||||
def preferences():
|
||||
return FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Path")
|
||||
|
||||
|
||||
def pathScriptsSourcePath():
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/PathScripts/")
|
||||
|
||||
|
||||
def pathDefaultToolsPath(sub=None):
|
||||
if sub:
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/Tools/", sub)
|
||||
return os.path.join(FreeCAD.getHomePath(), "Mod/Path/Tools/")
|
||||
|
||||
|
||||
def allAvailablePostProcessors():
|
||||
allposts = []
|
||||
for path in searchPathsPost():
|
||||
posts = [ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in glob.glob(path + '/*_post.py')]
|
||||
posts = [str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in glob.glob(path + '/*_post.py')]
|
||||
allposts.extend(posts)
|
||||
allposts.sort()
|
||||
return allposts
|
||||
|
||||
def allEnabledPostProcessors(include = None):
|
||||
|
||||
def allEnabledPostProcessors(include=None):
|
||||
blacklist = postProcessorBlacklist()
|
||||
enabled = [processor for processor in allAvailablePostProcessors() if not processor in blacklist]
|
||||
enabled = [processor for processor in allAvailablePostProcessors() if processor not in blacklist]
|
||||
if include:
|
||||
l = list(set(include + enabled))
|
||||
l.sort()
|
||||
return l
|
||||
postlist = list(set(include + enabled))
|
||||
postlist.sort()
|
||||
return postlist
|
||||
return enabled
|
||||
|
||||
|
||||
def defaultPostProcessor():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorDefault, "")
|
||||
|
||||
|
||||
def defaultPostProcessorArgs():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorDefaultArgs, "")
|
||||
|
||||
|
||||
def defaultGeometryTolerance():
|
||||
return preferences().GetFloat(GeometryTolerance, 0.01)
|
||||
|
||||
|
||||
def defaultLibAreaCurveAccuracy():
|
||||
return preferences().GetFloat(LibAreaCurveAccuracy, 0.01)
|
||||
|
||||
|
||||
def defaultFilePath():
|
||||
return preferences().GetString(DefaultFilePath)
|
||||
|
||||
|
||||
def filePath():
|
||||
path = defaultFilePath()
|
||||
if not path:
|
||||
path = macroFilePath()
|
||||
return path
|
||||
|
||||
|
||||
def macroFilePath():
|
||||
grp = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")
|
||||
return grp.GetString("MacroPath", FreeCAD.getUserMacroDir())
|
||||
|
||||
|
||||
def searchPaths():
|
||||
paths = []
|
||||
p = defaultFilePath()
|
||||
@@ -118,6 +136,7 @@ def searchPaths():
|
||||
paths.append(macroFilePath())
|
||||
return paths
|
||||
|
||||
|
||||
def searchPathsPost():
|
||||
paths = []
|
||||
p = defaultFilePath()
|
||||
@@ -128,11 +147,14 @@ def searchPathsPost():
|
||||
paths.append(pathScriptsSourcePath())
|
||||
return paths
|
||||
|
||||
|
||||
def searchPathsTool(sub='Bit'):
|
||||
paths = []
|
||||
|
||||
if 'Bit' == sub:
|
||||
paths.append("{}/Bit".format(os.path.dirname(lastPathToolLibrary())))
|
||||
paths.append(lastPathToolBit())
|
||||
|
||||
if 'Library' == sub:
|
||||
paths.append(lastPathToolLibrary())
|
||||
if 'Shape' == sub:
|
||||
@@ -148,30 +170,37 @@ def searchPathsTool(sub='Bit'):
|
||||
appendPath(os.path.join(FreeCAD.getHomePath(), "Mod/Path/"), sub)
|
||||
return paths
|
||||
|
||||
|
||||
def toolsUseLegacyTools():
|
||||
return preferences().GetBool(UseLegacyTools, True)
|
||||
return preferences().GetBool(UseLegacyTools, False)
|
||||
|
||||
|
||||
def toolsReallyUseLegacyTools():
|
||||
return toolsUseLegacyTools() or not experimentalFeaturesEnabled()
|
||||
return toolsUseLegacyTools()
|
||||
|
||||
|
||||
def toolsStoreAbsolutePaths():
|
||||
return preferences().GetBool(UseAbsoluteToolPaths, False)
|
||||
|
||||
|
||||
def toolsOpenLastLibrary():
|
||||
return preferences().GetBool(OpenLastLibrary, False)
|
||||
|
||||
|
||||
def setToolsSettings(legacy, relative, lastlibrary):
|
||||
pref = preferences()
|
||||
pref.SetBool(UseLegacyTools, legacy)
|
||||
pref.SetBool(UseAbsoluteToolPaths, relative)
|
||||
pref.SetBool(OpenLastLibrary, lastlibrary)
|
||||
|
||||
|
||||
def defaultJobTemplate():
|
||||
template = preferences().GetString(DefaultJobTemplate)
|
||||
if 'xml' not in template:
|
||||
return template
|
||||
return ''
|
||||
|
||||
|
||||
def setJobDefaults(fileName, jobTemplate, geometryTolerance, curveAccuracy):
|
||||
PathLog.track("(%s='%s', %s, %s, %s)" % (DefaultFilePath, fileName, jobTemplate, geometryTolerance, curveAccuracy))
|
||||
pref = preferences()
|
||||
@@ -180,12 +209,14 @@ def setJobDefaults(fileName, jobTemplate, geometryTolerance, curveAccuracy):
|
||||
pref.SetFloat(GeometryTolerance, geometryTolerance)
|
||||
pref.SetFloat(LibAreaCurveAccuracy, curveAccuracy)
|
||||
|
||||
|
||||
def postProcessorBlacklist():
|
||||
pref = preferences()
|
||||
blacklist = pref.GetString(PostProcessorBlacklist, "")
|
||||
if not blacklist:
|
||||
return []
|
||||
return eval(blacklist) # pylint: disable=eval-used
|
||||
return eval(blacklist) # pylint: disable=eval-used
|
||||
|
||||
|
||||
def setPostProcessorDefaults(processor, args, blacklist):
|
||||
pref = preferences()
|
||||
@@ -193,54 +224,99 @@ def setPostProcessorDefaults(processor, args, blacklist):
|
||||
pref.SetString(PostProcessorDefaultArgs, args)
|
||||
pref.SetString(PostProcessorBlacklist, "%s" % (blacklist))
|
||||
|
||||
|
||||
def setOutputFileDefaults(fileName, policy):
|
||||
pref = preferences()
|
||||
pref.SetString(PostProcessorOutputFile, fileName)
|
||||
pref.SetString(PostProcessorOutputPolicy, policy)
|
||||
|
||||
|
||||
def defaultOutputFile():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorOutputFile, "")
|
||||
|
||||
|
||||
def defaultOutputPolicy():
|
||||
pref = preferences()
|
||||
return pref.GetString(PostProcessorOutputPolicy, "")
|
||||
|
||||
|
||||
def defaultStockTemplate():
|
||||
return preferences().GetString(DefaultStockTemplate, "")
|
||||
|
||||
|
||||
def setDefaultStockTemplate(template):
|
||||
preferences().SetString(DefaultStockTemplate, template)
|
||||
|
||||
|
||||
def defaultTaskPanelLayout():
|
||||
return preferences().GetInt(DefaultTaskPanelLayout, 0)
|
||||
|
||||
|
||||
def setDefaultTaskPanelLayout(style):
|
||||
preferences().SetInt(DefaultTaskPanelLayout, style)
|
||||
|
||||
|
||||
def experimentalFeaturesEnabled():
|
||||
return preferences().GetBool(EnableExperimentalFeatures, False)
|
||||
|
||||
|
||||
def lastFileToolLibrary():
|
||||
filename = preferences().GetString(LastFileToolLibrary)
|
||||
if filename.endswith('.fctl') and os.path.isfile(filename):
|
||||
return filename
|
||||
|
||||
libpath = preferences().GetString(LastPathToolLibrary, pathDefaultToolsPath('Library'))
|
||||
libFiles = [f for f in glob.glob(libpath + '/*.fctl')]
|
||||
libFiles.sort()
|
||||
if len(libFiles) >= 1:
|
||||
filename = libFiles[0]
|
||||
setLastFileToolLibrary(filename)
|
||||
PathLog.track(filename)
|
||||
return filename
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def setLastFileToolLibrary(path):
|
||||
PathLog.track(path)
|
||||
if os.path.isfile(path): # keep the path and file in sync
|
||||
preferences().SetString(LastPathToolLibrary, os.path.split(path)[0])
|
||||
return preferences().SetString(LastFileToolLibrary, path)
|
||||
|
||||
|
||||
def lastPathToolBit():
|
||||
return preferences().GetString(LastPathToolBit, pathDefaultToolsPath('Bit'))
|
||||
|
||||
|
||||
def setLastPathToolBit(path):
|
||||
return preferences().SetString(LastPathToolBit, path)
|
||||
|
||||
|
||||
def lastPathToolLibrary():
|
||||
PathLog.track()
|
||||
return preferences().GetString(LastPathToolLibrary, pathDefaultToolsPath('Library'))
|
||||
|
||||
|
||||
def setLastPathToolLibrary(path):
|
||||
PathLog.track(path)
|
||||
curLib = lastFileToolLibrary()
|
||||
if os.path.split(curLib)[0] != path:
|
||||
setLastFileToolLibrary('') # a path is known but not specific file
|
||||
return preferences().SetString(LastPathToolLibrary, path)
|
||||
|
||||
|
||||
def lastPathToolShape():
|
||||
return preferences().GetString(LastPathToolShape, pathDefaultToolsPath('Shape'))
|
||||
|
||||
|
||||
def setLastPathToolShape(path):
|
||||
return preferences().SetString(LastPathToolShape, path)
|
||||
|
||||
|
||||
def lastPathToolTable():
|
||||
return preferences().GetString(LastPathToolTable, "")
|
||||
|
||||
|
||||
def setLastPathToolTable(table):
|
||||
return preferences().SetString(LastPathToolTable, table)
|
||||
|
||||
@@ -38,6 +38,7 @@ __doc__ = "Profile operation page controller and command implementation."
|
||||
FeatureSide = 0x01
|
||||
FeatureProcessing = 0x02
|
||||
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
@@ -127,8 +128,6 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
|
||||
def updateVisibility(self):
|
||||
hasFace = False
|
||||
hasGeom = False
|
||||
fullModel = False
|
||||
objBase = list()
|
||||
|
||||
if hasattr(self.obj, 'Base'):
|
||||
@@ -140,8 +139,6 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage):
|
||||
if sub[:4] == 'Face':
|
||||
hasFace = True
|
||||
break
|
||||
else:
|
||||
fullModel = True
|
||||
|
||||
if hasFace:
|
||||
self.form.processCircles.show()
|
||||
|
||||
@@ -47,21 +47,54 @@ def translate(context, text, disambig=None):
|
||||
|
||||
|
||||
LOG_MODULE = 'PathSanity'
|
||||
PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
|
||||
# PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
|
||||
# PathLog.trackModule('PathSanity')
|
||||
|
||||
|
||||
class CommandPathSanity:
|
||||
baseobj = None
|
||||
outputpath = PathPreferences.defaultOutputFile()
|
||||
if outputpath == "":
|
||||
outputpath = PathPreferences.macroFilePath()
|
||||
if outputpath[-1] != os.sep:
|
||||
outputpath += os.sep
|
||||
if not os.path.exists(outputpath):
|
||||
os.makedirs(outputpath)
|
||||
|
||||
squawkData = {"items": []}
|
||||
def resolveOutputPath(self, job):
|
||||
if job.PostProcessorOutputFile != "":
|
||||
filepath = job.PostProcessorOutputFile
|
||||
elif PathPreferences.defaultOutputFile() != "":
|
||||
filepath = PathPreferences.defaultOutputFile()
|
||||
else:
|
||||
filepath = PathPreferences.macroFilePath()
|
||||
|
||||
if '%D' in filepath:
|
||||
D = FreeCAD.ActiveDocument.FileName
|
||||
if D:
|
||||
D = os.path.dirname(D)
|
||||
# in case the document is in the current working directory
|
||||
if not D:
|
||||
D = '.'
|
||||
else:
|
||||
FreeCAD.Console.PrintError("Please save document in order to resolve output path!\n")
|
||||
return None
|
||||
filepath = filepath.replace('%D', D)
|
||||
|
||||
if '%d' in filepath:
|
||||
d = FreeCAD.ActiveDocument.Label
|
||||
filepath = filepath.replace('%d', d)
|
||||
|
||||
if '%j' in filepath:
|
||||
j = job.Label
|
||||
filepath = filepath.replace('%j', j)
|
||||
|
||||
if '%M' in filepath:
|
||||
pref = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")
|
||||
M = pref.GetString("MacroPath", FreeCAD.getUserAppDataDir())
|
||||
filepath = filepath.replace('%M', M)
|
||||
|
||||
PathLog.debug('filepath: {}'.format(filepath))
|
||||
|
||||
# starting at the derived filename, iterate up until we have a valid
|
||||
# directory to write to
|
||||
while not os.path.isdir(filepath):
|
||||
filepath = os.path.dirname(filepath)
|
||||
|
||||
PathLog.debug('filepath: {}'.format(filepath))
|
||||
return filepath + os.sep
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-Sanity',
|
||||
@@ -77,9 +110,10 @@ class CommandPathSanity:
|
||||
|
||||
def Activated(self):
|
||||
# if everything is ok, execute
|
||||
self.squawkData["items"] = []
|
||||
self.squawkData = {"items": []}
|
||||
|
||||
obj = FreeCADGui.Selection.getSelectionEx()[0].Object
|
||||
self.outputpath = self.resolveOutputPath(obj)
|
||||
data = self.__summarize(obj)
|
||||
html = self.__report(data)
|
||||
if html is not None:
|
||||
@@ -369,8 +403,8 @@ class CommandPathSanity:
|
||||
|
||||
# Save the report
|
||||
|
||||
reportraw = self.outputpath + '/setupreport.asciidoc'
|
||||
reporthtml = self.outputpath + '/setupreport.html'
|
||||
reportraw = self.outputpath + 'setupreport.asciidoc'
|
||||
reporthtml = self.outputpath + 'setupreport.html'
|
||||
with open(reportraw, 'w') as fd:
|
||||
fd.write(report)
|
||||
fd.close()
|
||||
@@ -505,7 +539,7 @@ class CommandPathSanity:
|
||||
|
||||
tooldata['partNumber'] = ""
|
||||
imagedata = TC.Tool.Proxy.getBitThumbnail(TC.Tool)
|
||||
imagepath = '{}/T{}.png'.format(self.outputpath, TC.ToolNumber)
|
||||
imagepath = '{}T{}.png'.format(self.outputpath, TC.ToolNumber)
|
||||
tooldata['feedrate'] = str(TC.HorizFeed)
|
||||
if TC.HorizFeed.Value == 0.0:
|
||||
self.squawk("PathSanity",
|
||||
@@ -646,7 +680,7 @@ class CommandPathSanity:
|
||||
view.showNormal()
|
||||
view.resize(320, 320)
|
||||
|
||||
imagepath = '{}/origin'.format(self.outputpath)
|
||||
imagepath = '{}origin'.format(self.outputpath)
|
||||
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
FreeCADGui.SendMsgToActiveView("PerspectiveCamera")
|
||||
|
||||
@@ -45,29 +45,32 @@ __doc__ = "Class to deal with and represent a tool bit."
|
||||
# PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
# PathLog.trackModule()
|
||||
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
return PySide.QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
ParameterTypeConstraint = {
|
||||
'Angle': 'App::PropertyAngle',
|
||||
'Distance': 'App::PropertyLength',
|
||||
'DistanceX': 'App::PropertyLength',
|
||||
'DistanceY': 'App::PropertyLength',
|
||||
'Radius': 'App::PropertyLength'
|
||||
}
|
||||
'Radius': 'App::PropertyLength'}
|
||||
|
||||
|
||||
def _findTool(path, typ, dbg=False):
|
||||
if os.path.exists(path):
|
||||
if os.path.exists(path): # absolute reference
|
||||
if dbg:
|
||||
PathLog.debug("Found {} at {}".format(typ, path))
|
||||
return path
|
||||
|
||||
def searchFor(pname, fname):
|
||||
# PathLog.debug("pname: {} fname: {}".format(pname, fname))
|
||||
if dbg:
|
||||
PathLog.debug("Looking for {}".format(pname))
|
||||
if fname:
|
||||
for p in PathPreferences.searchPathsTool(typ):
|
||||
PathLog.track(p)
|
||||
f = os.path.join(p, fname)
|
||||
if dbg:
|
||||
PathLog.debug(" Checking {}".format(f))
|
||||
@@ -76,6 +79,7 @@ def _findTool(path, typ, dbg=False):
|
||||
PathLog.debug(" Found {} at {}".format(typ, f))
|
||||
return f
|
||||
if pname and os.path.sep != pname:
|
||||
PathLog.track(pname)
|
||||
ppname, pfname = os.path.split(pname)
|
||||
ffname = os.path.join(pfname, fname) if fname else pfname
|
||||
return searchFor(ppname, ffname)
|
||||
@@ -83,20 +87,28 @@ def _findTool(path, typ, dbg=False):
|
||||
|
||||
return searchFor(path, '')
|
||||
|
||||
|
||||
def findShape(path):
|
||||
'''findShape(path) ... search for path, full and partially in all known shape directories.'''
|
||||
'''
|
||||
findShape(path) ... search for path, full and partially
|
||||
in all known shape directories.
|
||||
'''
|
||||
return _findTool(path, 'Shape')
|
||||
|
||||
|
||||
def findBit(path):
|
||||
PathLog.track(path)
|
||||
if path.endswith('.fctb'):
|
||||
return _findTool(path, 'Bit')
|
||||
return _findTool("{}.fctb".format(path), 'Bit')
|
||||
|
||||
|
||||
def findLibrary(path, dbg=False):
|
||||
if path.endswith('.fctl'):
|
||||
return _findTool(path, 'Library', dbg)
|
||||
return _findTool("{}.fctl".format(path), 'Library', dbg)
|
||||
|
||||
|
||||
def _findRelativePath(path, typ):
|
||||
relative = path
|
||||
for p in PathPreferences.searchPathsTool(typ):
|
||||
@@ -108,15 +120,19 @@ def _findRelativePath(path, typ):
|
||||
relative = p
|
||||
return relative
|
||||
|
||||
|
||||
def findRelativePathShape(path):
|
||||
return _findRelativePath(path, 'Shape')
|
||||
|
||||
|
||||
def findRelativePathTool(path):
|
||||
return _findRelativePath(path, 'Bit')
|
||||
|
||||
|
||||
def findRelativePathLibrary(path):
|
||||
return _findRelativePath(path, 'Library')
|
||||
|
||||
|
||||
def updateConstraint(sketch, name, value):
|
||||
for i, constraint in enumerate(sketch.Constraints):
|
||||
if constraint.Name.split(';')[0] == name:
|
||||
@@ -128,7 +144,9 @@ def updateConstraint(sketch, name, value):
|
||||
|
||||
if constr is not None:
|
||||
if not PathGeom.isRoughly(constraint.Value, value.Value):
|
||||
PathLog.track(name, constraint.Type, 'update', i, "(%.2f -> %.2f)" % (constraint.Value, value.Value))
|
||||
PathLog.track(name, constraint.Type,
|
||||
'update', i, "(%.2f -> %.2f)"
|
||||
% (constraint.Value, value.Value))
|
||||
sketch.delConstraint(i)
|
||||
sketch.recompute()
|
||||
n = sketch.addConstraint(constr)
|
||||
@@ -141,15 +159,21 @@ def updateConstraint(sketch, name, value):
|
||||
PropertyGroupBit = 'Bit'
|
||||
PropertyGroupAttribute = 'Attribute'
|
||||
|
||||
|
||||
class ToolBit(object):
|
||||
|
||||
def __init__(self, obj, shapeFile):
|
||||
PathLog.track(obj.Label, shapeFile)
|
||||
self.obj = obj
|
||||
obj.addProperty('App::PropertyFile', 'BitShape', 'Base', translate('PathToolBit', 'Shape for bit shape'))
|
||||
obj.addProperty('App::PropertyLink', 'BitBody', 'Base', translate('PathToolBit', 'The parametrized body representing the tool bit'))
|
||||
obj.addProperty('App::PropertyFile', 'File', 'Base', translate('PathToolBit', 'The file of the tool'))
|
||||
obj.addProperty('App::PropertyString', 'ShapeName', 'Base', translate('PathToolBit', 'The name of the shape file'))
|
||||
obj.addProperty('App::PropertyFile', 'BitShape', 'Base',
|
||||
translate('PathToolBit', 'Shape for bit shape'))
|
||||
obj.addProperty('App::PropertyLink', 'BitBody', 'Base',
|
||||
translate('PathToolBit',
|
||||
'The parametrized body representing the tool bit'))
|
||||
obj.addProperty('App::PropertyFile', 'File', 'Base',
|
||||
translate('PathToolBit', 'The file of the tool'))
|
||||
obj.addProperty('App::PropertyString', 'ShapeName', 'Base',
|
||||
translate('PathToolBit', 'The name of the shape file'))
|
||||
if shapeFile is None:
|
||||
obj.BitShape = 'endmill.fcstd'
|
||||
self._setupBitShape(obj)
|
||||
@@ -184,14 +208,14 @@ class ToolBit(object):
|
||||
for prop in self.propertyNamesBit(obj):
|
||||
obj.setEditorMode(prop, 1)
|
||||
# I currently don't see why these need to be read-only
|
||||
#for prop in self.propertyNamesAttribute(obj):
|
||||
# for prop in self.propertyNamesAttribute(obj):
|
||||
# obj.setEditorMode(prop, 1)
|
||||
|
||||
def onChanged(self, obj, prop):
|
||||
PathLog.track(obj.Label, prop)
|
||||
if prop == 'BitShape' and not 'Restore' in obj.State:
|
||||
if prop == 'BitShape' and 'Restore' not in obj.State:
|
||||
self._setupBitShape(obj)
|
||||
#elif obj.getGroupOfProperty(prop) == PropertyGroupBit:
|
||||
# elif obj.getGroupOfProperty(prop) == PropertyGroupBit:
|
||||
# self._updateBitShape(obj, [prop])
|
||||
|
||||
def onDelete(self, obj, arg2=None):
|
||||
@@ -200,7 +224,7 @@ class ToolBit(object):
|
||||
obj.Document.removeObject(obj.Name)
|
||||
|
||||
def _updateBitShape(self, obj, properties=None):
|
||||
if not obj.BitBody is None:
|
||||
if obj.BitBody is not None:
|
||||
if not properties:
|
||||
properties = self.propertyNamesBit(obj)
|
||||
for prop in properties:
|
||||
@@ -234,7 +258,6 @@ class ToolBit(object):
|
||||
return (doc, docOpened)
|
||||
|
||||
def _removeBitBody(self, obj):
|
||||
print('in _removebitbody')
|
||||
if obj.BitBody:
|
||||
obj.BitBody.removeObjectsFromDocument()
|
||||
obj.Document.removeObject(obj.BitBody.Name)
|
||||
@@ -286,7 +309,7 @@ class ToolBit(object):
|
||||
prop = parts[0]
|
||||
desc = ''
|
||||
if len(parts) > 1:
|
||||
desc = parts[1]
|
||||
desc = parts[1]
|
||||
obj.addProperty(typ, prop, PropertyGroupBit, desc)
|
||||
obj.setEditorMode(prop, 1)
|
||||
value = constraint.Value
|
||||
@@ -307,7 +330,7 @@ class ToolBit(object):
|
||||
return None
|
||||
|
||||
def saveToFile(self, obj, path, setFile=True):
|
||||
print('were saving now')
|
||||
PathLog.track(path)
|
||||
try:
|
||||
with open(path, 'w') as fp:
|
||||
json.dump(self.templateAttrs(obj), fp, indent=' ')
|
||||
@@ -315,12 +338,13 @@ class ToolBit(object):
|
||||
obj.File = path
|
||||
return True
|
||||
except (OSError, IOError) as e:
|
||||
PathLog.error("Could not save tool %s to %s (%s)" % (obj.Label, path, e))
|
||||
PathLog.error("Could not save tool {} to {} ({})".format(
|
||||
obj.Label, path, e))
|
||||
raise
|
||||
|
||||
def templateAttrs(self, obj):
|
||||
attrs = {}
|
||||
attrs['version'] = 2 # Path.Tool is version 1
|
||||
attrs['version'] = 2 # Path.Tool is version 1
|
||||
attrs['name'] = obj.Label
|
||||
if PathPreferences.toolsStoreAbsolutePaths():
|
||||
attrs['shape'] = obj.BitShape
|
||||
@@ -332,7 +356,6 @@ class ToolBit(object):
|
||||
attrs['parameter'] = params
|
||||
params = {}
|
||||
for name in self.propertyNamesAttribute(obj):
|
||||
#print(f"shapeattr {name}")
|
||||
if name == "UserAttributes":
|
||||
for key, value in obj.UserAttributes.items():
|
||||
params[key] = value
|
||||
@@ -341,26 +364,43 @@ class ToolBit(object):
|
||||
attrs['attribute'] = params
|
||||
return attrs
|
||||
|
||||
|
||||
def Declaration(path):
|
||||
PathLog.track(path)
|
||||
with open(path, 'r') as fp:
|
||||
return json.load(fp)
|
||||
|
||||
|
||||
class AttributePrototype(PathSetupSheetOpPrototype.OpPrototype):
|
||||
|
||||
def __init__(self):
|
||||
PathSetupSheetOpPrototype.OpPrototype.__init__(self, 'ToolBitAttribute')
|
||||
self.addProperty('App::PropertyEnumeration', 'Material', PropertyGroupAttribute, translate('PathToolBit', 'Tool bit material'))
|
||||
self.Material = ['Carbide', 'CastAlloy', 'Ceramics', 'Diamond', 'HighCarbonToolSteel', 'HighSpeedSteel', 'Sialon']
|
||||
self.addProperty('App::PropertyDistance', 'LengthOffset', PropertyGroupAttribute, translate('PathToolBit', 'Length offset in Z direction'))
|
||||
self.addProperty('App::PropertyInteger', 'Flutes', PropertyGroupAttribute, translate('PathToolBit', 'The number of flutes'))
|
||||
self.addProperty('App::PropertyDistance', 'ChipLoad', PropertyGroupAttribute, translate('PathToolBit', 'Chipload as per manufacturer'))
|
||||
self.addProperty('App::PropertyMap', 'UserAttributes', PropertyGroupAttribute, translate('PathTooolBit', 'User Defined Values'))
|
||||
self.addProperty('App::PropertyEnumeration', 'Material',
|
||||
PropertyGroupAttribute,
|
||||
translate('PathToolBit', 'Tool bit material'))
|
||||
self.Material = ['Carbide', 'CastAlloy', 'Ceramics', 'Diamond',
|
||||
'HighCarbonToolSteel', 'HighSpeedSteel', 'Sialon']
|
||||
self.addProperty('App::PropertyDistance', 'LengthOffset',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'Length offset in Z direction'))
|
||||
self.addProperty('App::PropertyInteger', 'Flutes',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'The number of flutes'))
|
||||
self.addProperty('App::PropertyDistance', 'ChipLoad',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'Chipload as per manufacturer'))
|
||||
self.addProperty('App::PropertyMap', 'UserAttributes',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'User Defined Values'))
|
||||
self.addProperty('App::PropertyBool', 'SpindlePower',
|
||||
PropertyGroupAttribute, translate('PathToolBit',
|
||||
'Whether Spindle Power should be allowed'))
|
||||
|
||||
|
||||
class ToolBitFactory(object):
|
||||
|
||||
def CreateFromAttrs(self, attrs, name='ToolBit'):
|
||||
# pylint: disable=protected-access
|
||||
PathLog.debug(attrs)
|
||||
obj = Factory.Create(name, attrs['shape'])
|
||||
obj.Label = attrs['name']
|
||||
params = attrs['parameter']
|
||||
@@ -372,23 +412,17 @@ class ToolBitFactory(object):
|
||||
proto = AttributePrototype()
|
||||
uservals = {}
|
||||
for pname in params:
|
||||
#print(f"pname: {pname}")
|
||||
try:
|
||||
prop = proto.getProperty(pname)
|
||||
val = prop.valueFromString(params[pname])
|
||||
prop.setupProperty(obj, pname, PropertyGroupAttribute, prop.valueFromString(params[pname]))
|
||||
except:
|
||||
# prop = obj.addProperty('App::PropertyString', pname, "Attribute", translate('PathTooolBit', 'User Defined Value'))
|
||||
# setattr(obj, pname, params[pname])
|
||||
except Exception:
|
||||
prop = proto.getProperty("UserAttributes")
|
||||
uservals.update({pname: params[pname]})
|
||||
#prop.setupProperty(obj, pname, "UserAttributes", prop.valueFromString(params[pname]))
|
||||
|
||||
if len(uservals.items()) > 0:
|
||||
prop.setupProperty(obj, "UserAttributes", PropertyGroupAttribute, uservals)
|
||||
prop.setupProperty(obj, "UserAttributes",
|
||||
PropertyGroupAttribute, uservals)
|
||||
|
||||
# print("prop[%s] = %s (%s)" % (pname, params[pname], type(val)))
|
||||
#prop.setupProperty(obj, pname, PropertyGroupAttribute, prop.valueFromString(params[pname]))
|
||||
return obj
|
||||
|
||||
def CreateFrom(self, path, name='ToolBit'):
|
||||
@@ -406,4 +440,5 @@ class ToolBitFactory(object):
|
||||
obj.Proxy = ToolBit(obj, shapeFile)
|
||||
return obj
|
||||
|
||||
|
||||
Factory = ToolBitFactory()
|
||||
|
||||
@@ -31,7 +31,7 @@ import re
|
||||
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
# PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
# PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
|
||||
@@ -42,10 +42,12 @@ def translate(context, text, disambig=None):
|
||||
|
||||
class ToolBitEditor(object):
|
||||
'''UI and controller for editing a ToolBit.
|
||||
The controller embeds the UI to the parentWidget which has to have a layout attached to it.
|
||||
The controller embeds the UI to the parentWidget which has to have a
|
||||
layout attached to it.
|
||||
'''
|
||||
|
||||
def __init__(self, tool, parentWidget=None):
|
||||
def __init__(self, tool, parentWidget=None, loadBitBody=True):
|
||||
PathLog.track()
|
||||
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolBitEditor.ui")
|
||||
|
||||
if parentWidget:
|
||||
@@ -53,13 +55,18 @@ class ToolBitEditor(object):
|
||||
parentWidget.layout().addWidget(self.form)
|
||||
|
||||
self.tool = tool
|
||||
self.loadbitbody = loadBitBody
|
||||
if not tool.BitShape:
|
||||
self.tool.BitShape = 'endmill.fcstd'
|
||||
self.tool.Proxy.loadBitBody(self.tool)
|
||||
|
||||
if self.loadbitbody:
|
||||
self.tool.Proxy.loadBitBody(self.tool)
|
||||
|
||||
self.setupTool(self.tool)
|
||||
self.setupAttributes(self.tool)
|
||||
|
||||
def setupTool(self, tool):
|
||||
PathLog.track()
|
||||
layout = self.form.bitParams.layout()
|
||||
for i in range(layout.rowCount() - 1, -1, -1):
|
||||
layout.removeRow(i)
|
||||
@@ -69,7 +76,8 @@ class ToolBitEditor(object):
|
||||
if tool.getGroupOfProperty(name) == PathToolBit.PropertyGroupBit:
|
||||
qsb = ui.createWidget('Gui::QuantitySpinBox')
|
||||
editor[name] = PathGui.QuantitySpinBox(qsb, tool, name)
|
||||
label = QtGui.QLabel(re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', name)))
|
||||
label = QtGui.QLabel(re.sub('([A-Z][a-z]+)', r' \1',
|
||||
re.sub('([A-Z]+)', r' \1', name)))
|
||||
layout.addRow(label, qsb)
|
||||
self.bitEditor = editor
|
||||
img = tool.Proxy.getBitThumbnail(tool)
|
||||
@@ -79,6 +87,7 @@ class ToolBitEditor(object):
|
||||
self.form.image.setPixmap(QtGui.QPixmap())
|
||||
|
||||
def setupAttributes(self, tool):
|
||||
PathLog.track()
|
||||
self.proto = PathToolBit.AttributePrototype()
|
||||
self.props = sorted(self.proto.properties)
|
||||
self.delegate = PathSetupSheetGui.Delegate(self.form)
|
||||
@@ -86,7 +95,7 @@ class ToolBitEditor(object):
|
||||
self.model.setHorizontalHeaderLabels(['Set', 'Property', 'Value'])
|
||||
|
||||
for i, name in enumerate(self.props):
|
||||
print("propname: %s " % name)
|
||||
PathLog.debug("propname: %s " % name)
|
||||
|
||||
prop = self.proto.getProperty(name)
|
||||
isset = hasattr(tool, name)
|
||||
@@ -99,10 +108,15 @@ class ToolBitEditor(object):
|
||||
|
||||
else:
|
||||
|
||||
self.model.setData(self.model.index(i, 0), isset, QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 1), name, QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 2), prop, PathSetupSheetGui.Delegate.PropertyRole)
|
||||
self.model.setData(self.model.index(i, 2), prop.displayString(), QtCore.Qt.DisplayRole)
|
||||
self.model.setData(self.model.index(i, 0), isset,
|
||||
QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 1), name,
|
||||
QtCore.Qt.EditRole)
|
||||
self.model.setData(self.model.index(i, 2), prop,
|
||||
PathSetupSheetGui.Delegate.PropertyRole)
|
||||
self.model.setData(self.model.index(i, 2),
|
||||
prop.displayString(),
|
||||
QtCore.Qt.DisplayRole)
|
||||
|
||||
self.model.item(i, 0).setCheckable(True)
|
||||
self.model.item(i, 0).setText('')
|
||||
@@ -119,7 +133,7 @@ class ToolBitEditor(object):
|
||||
|
||||
if hasattr(tool, "UserAttributes"):
|
||||
for key, value in tool.UserAttributes.items():
|
||||
print(key, value)
|
||||
PathLog.debug(key, value)
|
||||
c1 = QtGui.QStandardItem()
|
||||
c1.setCheckable(False)
|
||||
c1.setEditable(False)
|
||||
@@ -141,26 +155,33 @@ class ToolBitEditor(object):
|
||||
self.model.dataChanged.connect(self.updateData)
|
||||
|
||||
def updateData(self, topLeft, bottomRight):
|
||||
# pylint: disable=unused-argument
|
||||
PathLog.track()
|
||||
if 0 == topLeft.column():
|
||||
isset = self.model.item(topLeft.row(), 0).checkState() == QtCore.Qt.Checked
|
||||
isset = self.model.item(topLeft.row(),
|
||||
0).checkState() == QtCore.Qt.Checked
|
||||
self.model.item(topLeft.row(), 1).setEnabled(isset)
|
||||
self.model.item(topLeft.row(), 2).setEnabled(isset)
|
||||
|
||||
def accept(self):
|
||||
PathLog.track()
|
||||
self.refresh()
|
||||
self.tool.Proxy.unloadBitBody(self.tool)
|
||||
|
||||
# get the attributes
|
||||
for i, name in enumerate(self.props):
|
||||
PathLog.debug('in accept: {}'.format(name))
|
||||
prop = self.proto.getProperty(name)
|
||||
enabled = self.model.item(i, 0).checkState() == QtCore.Qt.Checked
|
||||
if enabled and not prop.getValue() is None:
|
||||
prop.setupProperty(self.tool, name, PathToolBit.PropertyGroupAttribute, prop.getValue())
|
||||
elif hasattr(self.tool, name):
|
||||
self.tool.removeProperty(name)
|
||||
if self.model.item(i, 0) is not None:
|
||||
enabled = self.model.item(i, 0).checkState() == QtCore.Qt.Checked
|
||||
if enabled and not prop.getValue() is None:
|
||||
prop.setupProperty(self.tool, name,
|
||||
PathToolBit.PropertyGroupAttribute,
|
||||
prop.getValue())
|
||||
elif hasattr(self.tool, name):
|
||||
self.tool.removeProperty(name)
|
||||
|
||||
def reject(self):
|
||||
PathLog.track()
|
||||
self.tool.Proxy.unloadBitBody(self.tool)
|
||||
|
||||
def updateUI(self):
|
||||
@@ -172,6 +193,7 @@ class ToolBitEditor(object):
|
||||
self.bitEditor[editor].updateSpinBox()
|
||||
|
||||
def updateShape(self):
|
||||
PathLog.track()
|
||||
self.tool.BitShape = str(self.form.shapePath.text())
|
||||
self.setupTool(self.tool)
|
||||
self.form.toolName.setText(self.tool.Label)
|
||||
@@ -180,7 +202,6 @@ class ToolBitEditor(object):
|
||||
self.bitEditor[editor].updateSpinBox()
|
||||
|
||||
def updateTool(self):
|
||||
# pylint: disable=protected-access
|
||||
PathLog.track()
|
||||
self.tool.Label = str(self.form.toolName.text())
|
||||
self.tool.BitShape = str(self.form.shapePath.text())
|
||||
@@ -188,7 +209,7 @@ class ToolBitEditor(object):
|
||||
for editor in self.bitEditor:
|
||||
self.bitEditor[editor].updateProperty()
|
||||
|
||||
self.tool.Proxy._updateBitShape(self.tool)
|
||||
# self.tool.Proxy._updateBitShape(self.tool)
|
||||
|
||||
def refresh(self):
|
||||
PathLog.track()
|
||||
@@ -198,13 +219,14 @@ class ToolBitEditor(object):
|
||||
self.form.blockSignals(False)
|
||||
|
||||
def selectShape(self):
|
||||
PathLog.track()
|
||||
path = self.tool.BitShape
|
||||
if not path:
|
||||
path = PathPreferences.lastPathToolShape()
|
||||
foo = QtGui.QFileDialog.getOpenFileName(self.form,
|
||||
"Path - Tool Shape",
|
||||
path,
|
||||
"*.fcstd")
|
||||
"Path - Tool Shape",
|
||||
path,
|
||||
"*.fcstd")
|
||||
if foo and foo[0]:
|
||||
PathPreferences.setLastPathToolShape(os.path.dirname(foo[0]))
|
||||
self.form.shapePath.setText(foo[0])
|
||||
|
||||
@@ -36,12 +36,15 @@ __author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
__doc__ = "Task panel editor for a ToolBit"
|
||||
|
||||
|
||||
# Qt translation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
#PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
#PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
# PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
|
||||
class ViewProvider(object):
|
||||
'''ViewProvider for a ToolBit.
|
||||
@@ -58,7 +61,7 @@ class ViewProvider(object):
|
||||
def attach(self, vobj):
|
||||
PathLog.track(vobj.Object)
|
||||
self.vobj = vobj
|
||||
self.obj = vobj.Object
|
||||
self.obj = vobj.Object
|
||||
|
||||
def getIcon(self):
|
||||
png = self.obj.Proxy.getBitThumbnail(self.obj)
|
||||
@@ -111,7 +114,15 @@ class ViewProvider(object):
|
||||
return []
|
||||
|
||||
def doubleClicked(self, vobj):
|
||||
self.setEdit(vobj)
|
||||
if os.path.exists(vobj.Object.BitShape):
|
||||
self.setEdit(vobj)
|
||||
else:
|
||||
msg = translate('PathToolBit',
|
||||
'Toolbit cannot be edited: Shapefile not found')
|
||||
diag = QtGui.QMessageBox(QtGui.QMessageBox.Warning, 'Error', msg)
|
||||
diag.setWindowModality(QtCore.Qt.ApplicationModal)
|
||||
diag.exec_()
|
||||
|
||||
|
||||
class TaskPanel:
|
||||
'''TaskPanel for the SetupSheet - if it is being edited directly.'''
|
||||
@@ -123,7 +134,8 @@ class TaskPanel:
|
||||
self.editor = PathToolBitEdit.ToolBitEditor(self.obj)
|
||||
self.form = self.editor.form
|
||||
self.deleteOnReject = deleteOnReject
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit', 'Edit ToolBit'))
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit',
|
||||
'Edit ToolBit'))
|
||||
|
||||
def reject(self):
|
||||
FreeCAD.ActiveDocument.abortTransaction()
|
||||
@@ -145,6 +157,7 @@ class TaskPanel:
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def updateUI(self):
|
||||
PathLog.track()
|
||||
self.editor.updateUI()
|
||||
|
||||
def updateModel(self):
|
||||
@@ -155,141 +168,91 @@ class TaskPanel:
|
||||
self.editor.setupUI()
|
||||
|
||||
|
||||
class ToolBitSelector(object):
|
||||
ToolRole = QtCore.Qt.UserRole + 1
|
||||
|
||||
def __init__(self):
|
||||
self.buttons = None
|
||||
self.editor = None
|
||||
self.dialog = None
|
||||
self.form = FreeCADGui.PySideUic.loadUi(':/panels/ToolBitSelector.ui')
|
||||
self.setupUI()
|
||||
|
||||
def updateTools(self, selected=None):
|
||||
PathLog.track()
|
||||
selItem = None
|
||||
self.form.tools.setUpdatesEnabled(False)
|
||||
if selected is None and self.form.tools.currentItem():
|
||||
selected = self.form.tools.currentItem().text()
|
||||
self.form.tools.clear()
|
||||
for tool in sorted(self.loadedTools(), key=lambda t: t.Label):
|
||||
icon = None
|
||||
if tool.ViewObject and tool.ViewObject.Proxy:
|
||||
icon = tool.ViewObject.Proxy.getIcon()
|
||||
if icon and isinstance(icon, QtGui.QIcon):
|
||||
item = QtGui.QListWidgetItem(icon, tool.Label)
|
||||
else:
|
||||
item = QtGui.QListWidgetItem(tool.Label)
|
||||
item.setData(self.ToolRole, tool)
|
||||
if selected == tool.Label:
|
||||
selItem = item
|
||||
self.form.tools.addItem(item)
|
||||
if selItem:
|
||||
self.form.tools.setCurrentItem(selItem)
|
||||
self.updateSelection()
|
||||
self.form.tools.setUpdatesEnabled(True)
|
||||
|
||||
def getTool(self):
|
||||
PathLog.track()
|
||||
self.updateTools()
|
||||
res = self.form.exec_()
|
||||
if 1 == res and self.form.tools.currentItem():
|
||||
return self.form.tools.currentItem().data(self.ToolRole)
|
||||
return None
|
||||
|
||||
def loadedTools(self):
|
||||
PathLog.track()
|
||||
if FreeCAD.ActiveDocument:
|
||||
return [o for o in FreeCAD.ActiveDocument.Objects if hasattr(o, 'Proxy') and isinstance(o.Proxy, PathToolBit.ToolBit)]
|
||||
return []
|
||||
|
||||
def loadTool(self):
|
||||
PathLog.track()
|
||||
tool = LoadTool(self.form)
|
||||
if tool:
|
||||
self.updateTools(tool.Label)
|
||||
|
||||
def createTool(self):
|
||||
PathLog.track()
|
||||
tool = PathToolBit.Factory.Create()
|
||||
|
||||
def accept():
|
||||
self.editor.accept()
|
||||
self.dialog.done(1)
|
||||
self.updateTools(tool.Label)
|
||||
|
||||
def reject():
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit', 'Uncreate ToolBit'))
|
||||
self.editor.reject()
|
||||
self.dialog.done(0)
|
||||
FreeCAD.ActiveDocument.removeObject(tool.Name)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
|
||||
self.dialog = QtGui.QDialog(self.form)
|
||||
layout = QtGui.QVBoxLayout(self.dialog)
|
||||
self.editor = PathToolBitEdit.ToolBitEditor(tool, self.dialog)
|
||||
self.editor.setupUI()
|
||||
self.buttons = QtGui.QDialogButtonBox(
|
||||
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel,
|
||||
QtCore.Qt.Horizontal, self.dialog)
|
||||
layout.addWidget(self.buttons)
|
||||
self.buttons.accepted.connect(accept)
|
||||
self.buttons.rejected.connect(reject)
|
||||
print(self.dialog.exec_())
|
||||
|
||||
def updateSelection(self):
|
||||
PathLog.track()
|
||||
if self.form.tools.selectedItems():
|
||||
self.form.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
|
||||
else:
|
||||
self.form.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False)
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track()
|
||||
self.form.toolCreate.clicked.connect(self.createTool)
|
||||
self.form.toolLoad.clicked.connect(self.loadTool)
|
||||
self.form.tools.itemSelectionChanged.connect(self.updateSelection)
|
||||
self.form.tools.doubleClicked.connect(self.form.accept)
|
||||
|
||||
class ToolBitGuiFactory(PathToolBit.ToolBitFactory):
|
||||
|
||||
def Create(self, name='ToolBit', shapeFile=None):
|
||||
'''Create(name = 'ToolBit') ... creates a new tool bit.
|
||||
It is assumed the tool will be edited immediately so the internal bit body is still attached.'''
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit', 'Create ToolBit'))
|
||||
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('PathToolBit',
|
||||
'Create ToolBit'))
|
||||
tool = PathToolBit.ToolBitFactory.Create(self, name, shapeFile)
|
||||
PathIconViewProvider.Attach(tool.ViewObject, name)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
return tool
|
||||
|
||||
def GetToolFile(parent = None):
|
||||
|
||||
def GetNewToolFile(parent=None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
foo = QtGui.QFileDialog.getOpenFileName(parent, 'Tool', PathPreferences.lastPathToolBit(), '*.fctb')
|
||||
foo = QtGui.QFileDialog.getSaveFileName(parent, 'Tool',
|
||||
PathPreferences.lastPathToolBit(),
|
||||
'*.fctb')
|
||||
if foo and foo[0]:
|
||||
PathPreferences.setLastPathToolBit(os.path.dirname(foo[0]))
|
||||
return foo[0]
|
||||
return None
|
||||
|
||||
def GetToolFiles(parent = None):
|
||||
|
||||
def GetToolFile(parent=None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
foo = QtGui.QFileDialog.getOpenFileNames(parent, 'Tool', PathPreferences.lastPathToolBit(), '*.fctb')
|
||||
foo = QtGui.QFileDialog.getOpenFileName(parent, 'Tool',
|
||||
PathPreferences.lastPathToolBit(),
|
||||
'*.fctb')
|
||||
if foo and foo[0]:
|
||||
PathPreferences.setLastPathToolBit(os.path.dirname(foo[0]))
|
||||
return foo[0]
|
||||
return None
|
||||
|
||||
|
||||
def GetToolFiles(parent=None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
foo = QtGui.QFileDialog.getOpenFileNames(parent, 'Tool',
|
||||
PathPreferences.lastPathToolBit(),
|
||||
'*.fctb')
|
||||
if foo and foo[0]:
|
||||
PathPreferences.setLastPathToolBit(os.path.dirname(foo[0][0]))
|
||||
return foo[0]
|
||||
return []
|
||||
|
||||
|
||||
def LoadTool(parent = None):
|
||||
'''LoadTool(parent=None) ... Open a file dialog to load a tool from a file.'''
|
||||
def GetToolShapeFile(parent=None):
|
||||
if parent is None:
|
||||
parent = QtGui.QApplication.activeWindow()
|
||||
|
||||
location = PathPreferences.lastPathToolShape()
|
||||
if os.path.isfile(location):
|
||||
location = os.path.split(location)[0]
|
||||
elif not os.path.isdir(location):
|
||||
location = PathPreferences.filePath()
|
||||
|
||||
fname = QtGui.QFileDialog.getOpenFileName(parent, 'Select Tool Shape',
|
||||
location, '*.fcstd')
|
||||
if fname and fname[0]:
|
||||
if fname != location:
|
||||
PathPreferences.setLastPathToolShape(location)
|
||||
return fname[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def LoadTool(parent=None):
|
||||
'''
|
||||
LoadTool(parent=None) ... Open a file dialog to load a tool from a file.
|
||||
'''
|
||||
foo = GetToolFile(parent)
|
||||
return PathToolBit.Factory.CreateFrom(foo) if foo else foo
|
||||
|
||||
def LoadTools(parent = None):
|
||||
'''LoadTool(parent=None) ... Open a file dialog to load a tool from a file.'''
|
||||
|
||||
def LoadTools(parent=None):
|
||||
'''
|
||||
LoadTool(parent=None) ... Open a file dialog to load a tool from a file.
|
||||
'''
|
||||
return [PathToolBit.Factory.CreateFrom(foo) for foo in GetToolFiles(parent)]
|
||||
|
||||
|
||||
# Set the factory so all tools are created with UI
|
||||
PathToolBit.Factory = ToolBitGuiFactory()
|
||||
|
||||
|
||||
@@ -25,9 +25,10 @@ import FreeCADGui
|
||||
import PySide.QtCore as QtCore
|
||||
import PathScripts.PathPreferences as PathPreferences
|
||||
|
||||
class CommandToolBitLibraryOpen:
|
||||
|
||||
class CommandToolBitSelectorOpen:
|
||||
'''
|
||||
Command to ToolBitLibrary editor.
|
||||
Command to toggle the ToolBitSelector Dock
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
@@ -35,11 +36,42 @@ class CommandToolBitLibraryOpen:
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-ToolTable',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Open ToolBit Library editor"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Open an editor to manage ToolBit libraries")}
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "ToolBit Dock"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Toggle the Toolbit Dock"),
|
||||
'Accel': "P, T",
|
||||
'CmdType': "ForEdit"}
|
||||
|
||||
def IsActive(self):
|
||||
return True
|
||||
return FreeCAD.ActiveDocument is not None
|
||||
|
||||
def Activated(self):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
dock = PathToolBitLibraryGui.ToolBitSelector()
|
||||
|
||||
lastlib = PathPreferences.lastPathToolLibrary()
|
||||
|
||||
if PathPreferences.toolsOpenLastLibrary():
|
||||
dock.open(lastlib)
|
||||
else:
|
||||
dock.open()
|
||||
|
||||
|
||||
class CommandToolBitLibraryOpen:
|
||||
'''
|
||||
Command to open ToolBitLibrary editor.
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-ToolTable',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "ToolBit Library editor"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Open an editor to manage ToolBit libraries"),
|
||||
'CmdType': "ForEdit"}
|
||||
|
||||
def IsActive(self):
|
||||
return FreeCAD.ActiveDocument is not None
|
||||
|
||||
def Activated(self):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
@@ -52,55 +84,57 @@ class CommandToolBitLibraryOpen:
|
||||
else:
|
||||
library.open()
|
||||
|
||||
class CommandToolBitLibraryLoad:
|
||||
'''
|
||||
Command used to load an entire ToolBitLibrary (or part of it) from a file into a job.
|
||||
'''
|
||||
# class CommandToolBitLibraryLoad:
|
||||
# '''
|
||||
# Command used to load an entire ToolBitLibrary (or part of it) from a file into a job.
|
||||
# '''
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
# def __init__(self):
|
||||
# pass
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-ToolTable',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load ToolBit Library"),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load an entire ToolBit library or part of it into a job")}
|
||||
# def GetResources(self):
|
||||
# return {'Pixmap': 'Path-ToolTable',
|
||||
# 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load ToolBit Library"),
|
||||
# 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathToolBitLibrary", "Load an entire ToolBit library or part of it into a job")}
|
||||
|
||||
def selectedJob(self):
|
||||
if FreeCAD.ActiveDocument:
|
||||
sel = FreeCADGui.Selection.getSelectionEx()
|
||||
if sel and sel[0].Object.Name[:3] == 'Job':
|
||||
return sel[0].Object
|
||||
jobs = [o for o in FreeCAD.ActiveDocument.Objects if o.Name[:3] == 'Job']
|
||||
if 1 == len(jobs):
|
||||
return jobs[0]
|
||||
return None
|
||||
# def selectedJob(self):
|
||||
# if FreeCAD.ActiveDocument:
|
||||
# sel = FreeCADGui.Selection.getSelectionEx()
|
||||
# if sel and sel[0].Object.Name[:3] == 'Job':
|
||||
# return sel[0].Object
|
||||
# jobs = [o for o in FreeCAD.ActiveDocument.Objects if o.Name[:3] == 'Job']
|
||||
# if 1 == len(jobs):
|
||||
# return jobs[0]
|
||||
# return None
|
||||
|
||||
def IsActive(self):
|
||||
return not self.selectedJob() is None
|
||||
# def IsActive(self):
|
||||
# return not self.selectedJob() is None
|
||||
|
||||
def Activated(self):
|
||||
job = self.selectedJob()
|
||||
self.Execute(job)
|
||||
# def Activated(self):
|
||||
# job = self.selectedJob()
|
||||
# self.Execute(job)
|
||||
|
||||
@classmethod
|
||||
def Execute(cls, job):
|
||||
import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
import PathScripts.PathToolControllerGui as PathToolControllerGui
|
||||
# @classmethod
|
||||
# def Execute(cls, job):
|
||||
# import PathScripts.PathToolBitLibraryGui as PathToolBitLibraryGui
|
||||
# import PathScripts.PathToolControllerGui as PathToolControllerGui
|
||||
|
||||
library = PathToolBitLibraryGui.ToolBitLibrary()
|
||||
# library = PathToolBitLibraryGui.ToolBitLibrary()
|
||||
|
||||
# if 1 == library.open() and job:
|
||||
# for nr, tool in library.selectedOrAllTools():
|
||||
# tc = PathToolControllerGui.Create("TC: {}".format(tool.Label), tool, nr)
|
||||
# job.Proxy.addToolController(tc)
|
||||
# FreeCAD.ActiveDocument.recompute()
|
||||
# return True
|
||||
# return False
|
||||
|
||||
if 1 == library.open() and job:
|
||||
for nr, tool in library.selectedOrAllTools():
|
||||
tc = PathToolControllerGui.Create("TC: {}".format(tool.Label), tool, nr)
|
||||
job.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return True
|
||||
return False
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand('Path_ToolBitLibraryOpen', CommandToolBitLibraryOpen())
|
||||
FreeCADGui.addCommand('Path_ToolBitLibraryLoad', CommandToolBitLibraryLoad())
|
||||
FreeCADGui.addCommand('Path_ToolBitDock', CommandToolBitSelectorOpen())
|
||||
|
||||
CommandList = ['Path_ToolBitLibraryOpen', 'Path_ToolBitLibraryLoad']
|
||||
BarList = ['Path_ToolBitDock']
|
||||
MenuList = ['Path_ToolBitLibraryOpen', 'Path_ToolBitDock']
|
||||
|
||||
FreeCAD.Console.PrintLog("Loading PathToolBitLibraryCmd... done\n")
|
||||
|
||||
@@ -35,7 +35,7 @@ from PySide import QtCore, QtGui
|
||||
import PySide
|
||||
import json
|
||||
import os
|
||||
import traceback
|
||||
import glob
|
||||
import uuid as UUID
|
||||
from functools import partial
|
||||
|
||||
@@ -55,11 +55,11 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
|
||||
def __init__(self, parent):
|
||||
PySide.QtGui.QTableView.__init__(self, parent)
|
||||
self.setDragEnabled(True)
|
||||
self.setAcceptDrops(True)
|
||||
self.setDropIndicatorShown(True)
|
||||
self.setDragDropMode(PySide.QtGui.QAbstractItemView.InternalMove)
|
||||
self.setDefaultDropAction(PySide.QtCore.Qt.MoveAction)
|
||||
self.setDragEnabled(False)
|
||||
self.setAcceptDrops(False)
|
||||
self.setDropIndicatorShown(False)
|
||||
self.setDragDropMode(PySide.QtGui.QAbstractItemView.DragOnly)
|
||||
self.setDefaultDropAction(PySide.QtCore.Qt.IgnoreAction)
|
||||
self.setSortingEnabled(True)
|
||||
self.setSelectionBehavior(PySide.QtGui.QAbstractItemView.SelectRows)
|
||||
self.verticalHeader().hide()
|
||||
@@ -68,18 +68,18 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
return [PySide.QtCore.Qt.CopyAction, PySide.QtCore.Qt.MoveAction]
|
||||
|
||||
def _uuidOfRow(self, row):
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
return model.data(model.index(row, 0), _UuidRole)
|
||||
|
||||
def _rowWithUuid(self, uuid):
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
for row in range(model.rowCount()):
|
||||
if self._uuidOfRow(row) == uuid:
|
||||
return row
|
||||
return None
|
||||
|
||||
def _copyTool(self, uuid_, dstRow):
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
model.insertRow(dstRow)
|
||||
srcRow = self._rowWithUuid(uuid_)
|
||||
for col in range(model.columnCount()):
|
||||
@@ -108,23 +108,9 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
# pylint: disable=unused-variable
|
||||
row = stream.readInt32()
|
||||
srcRows.append(row)
|
||||
# col = stream.readInt32()
|
||||
# PathLog.track(row, col)
|
||||
# cnt = stream.readInt32()
|
||||
# for i in range(cnt):
|
||||
# key = stream.readInt32()
|
||||
# val = stream.readQVariant()
|
||||
# PathLog.track(' ', i, key, val, type(val))
|
||||
# I have no idea what these three integers are,
|
||||
# or if they even are three integers,
|
||||
# but it seems to work out this way.
|
||||
# i0 = stream.readInt32()
|
||||
# i1 = stream.readInt32()
|
||||
# i2 = stream.readInt32()
|
||||
# PathLog.track(' ', i0, i1, i2)
|
||||
|
||||
# get the uuids of all srcRows
|
||||
model = self.model()
|
||||
model = self.toolModel()
|
||||
srcUuids = [self._uuidOfRow(row) for row in set(srcRows)]
|
||||
destRow = self.rowAt(event.pos().y())
|
||||
|
||||
@@ -134,264 +120,432 @@ class _TableView(PySide.QtGui.QTableView):
|
||||
model.removeRow(self._rowWithUuid(uuid))
|
||||
|
||||
|
||||
class ToolBitLibrary(object):
|
||||
'''ToolBitLibrary is the controller for displaying/selecting/creating/editing a collection of ToolBits.'''
|
||||
class ModelFactory(object):
|
||||
''' Helper class to generate qtdata models for toolbit libraries
|
||||
'''
|
||||
|
||||
def __init__(self, path=None):
|
||||
self.path = path
|
||||
PathLog.track()
|
||||
self.path = ""
|
||||
# self.currentLib = ""
|
||||
|
||||
def __libraryLoad(self, path, datamodel):
|
||||
PathLog.track(path)
|
||||
PathPreferences.setLastFileToolLibrary(path)
|
||||
# self.currenLib = path
|
||||
|
||||
with open(path) as fp:
|
||||
library = json.load(fp)
|
||||
|
||||
for toolBit in library['tools']:
|
||||
try:
|
||||
nr = toolBit['nr']
|
||||
bit = PathToolBit.findBit(toolBit['path'])
|
||||
if bit:
|
||||
PathLog.track(bit)
|
||||
tool = PathToolBit.Declaration(bit)
|
||||
datamodel.appendRow(self._toolAdd(nr, tool, bit))
|
||||
else:
|
||||
PathLog.error("Could not find tool #{}: {}".format(nr, toolBit['path']))
|
||||
except Exception as e:
|
||||
msg = "Error loading tool: {} : {}".format(toolBit['path'], e)
|
||||
FreeCAD.Console.PrintError(msg)
|
||||
|
||||
def _toolAdd(self, nr, tool, path):
|
||||
|
||||
strShape = os.path.splitext(os.path.basename(tool['shape']))[0]
|
||||
# strDiam = tool['parameter']['Diameter']
|
||||
tooltip = "{}".format(strShape)
|
||||
|
||||
toolNr = PySide.QtGui.QStandardItem()
|
||||
toolNr.setData(nr, PySide.QtCore.Qt.EditRole)
|
||||
toolNr.setToolTip(tool['shape'])
|
||||
toolNr.setData(path, _PathRole)
|
||||
toolNr.setData(UUID.uuid4(), _UuidRole)
|
||||
toolNr.setToolTip(tooltip)
|
||||
|
||||
toolName = PySide.QtGui.QStandardItem()
|
||||
toolName.setData(tool['name'], PySide.QtCore.Qt.EditRole)
|
||||
toolName.setEditable(False)
|
||||
toolName.setToolTip(tooltip)
|
||||
|
||||
toolShape = PySide.QtGui.QStandardItem()
|
||||
toolShape.setData(strShape, PySide.QtCore.Qt.EditRole)
|
||||
toolShape.setEditable(False)
|
||||
|
||||
return [toolNr, toolName, toolShape]
|
||||
|
||||
def newTool(self, datamodel, path):
|
||||
'''
|
||||
Adds a toolbit item to a model
|
||||
'''
|
||||
PathLog.track()
|
||||
|
||||
try:
|
||||
nr = 0
|
||||
for row in range(datamodel.rowCount()):
|
||||
itemNr = int(datamodel.item(row, 0).data(PySide.QtCore.Qt.EditRole))
|
||||
nr = max(nr, itemNr)
|
||||
nr += 1
|
||||
tool = PathToolBit.Declaration(path)
|
||||
except Exception as e:
|
||||
PathLog.error(e)
|
||||
|
||||
datamodel.appendRow(self._toolAdd(nr, tool, path))
|
||||
|
||||
def findLibraries(self, model):
|
||||
'''
|
||||
Finds all the fctl files in a location
|
||||
Returns a QStandardItemModel
|
||||
'''
|
||||
PathLog.track()
|
||||
path = PathPreferences.lastPathToolLibrary()
|
||||
|
||||
if os.path.isdir(path): # opening all tables in a directory
|
||||
libFiles = [f for f in glob.glob(path + '/*.fctl')]
|
||||
libFiles.sort()
|
||||
for libFile in libFiles:
|
||||
loc, fnlong = os.path.split(libFile)
|
||||
fn, ext = os.path.splitext(fnlong)
|
||||
libItem = QtGui.QStandardItem(fn)
|
||||
libItem.setToolTip(loc)
|
||||
libItem.setData(libFile, _PathRole)
|
||||
libItem.setIcon(QtGui.QPixmap(':/icons/Path-ToolTable.svg'))
|
||||
model.appendRow(libItem)
|
||||
|
||||
PathLog.debug('model rows: {}'.format(model.rowCount()))
|
||||
return model
|
||||
|
||||
def libraryOpen(self, model, lib=""):
|
||||
'''
|
||||
opens the tools in library
|
||||
Returns a QStandardItemModel
|
||||
'''
|
||||
PathLog.track(lib)
|
||||
|
||||
if lib == "":
|
||||
lib = PathPreferences.lastFileToolLibrary()
|
||||
|
||||
if lib == "" or lib is None:
|
||||
return model
|
||||
|
||||
if os.path.isfile(lib): # An individual library is wanted
|
||||
self.__libraryLoad(lib, model)
|
||||
|
||||
PathLog.debug('model rows: {}'.format(model.rowCount()))
|
||||
return model
|
||||
|
||||
|
||||
class ToolBitSelector(object):
|
||||
'''Controller for displaying a library and creating ToolControllers'''
|
||||
|
||||
def __init__(self):
|
||||
self.form = FreeCADGui.PySideUic.loadUi(':/panels/ToolBitSelector.ui')
|
||||
self.factory = ModelFactory()
|
||||
self.toolModel = PySide.QtGui.QStandardItemModel(0, len(self.columnNames()))
|
||||
self.setupUI()
|
||||
self.title = self.form.windowTitle()
|
||||
|
||||
def columnNames(self):
|
||||
return ['#', 'Tool']
|
||||
|
||||
def curLib(self):
|
||||
libfile = PathPreferences.lastFileToolLibrary()
|
||||
if libfile is None or libfile == "":
|
||||
return ""
|
||||
else:
|
||||
libfile = os.path.split(PathPreferences.lastFileToolLibrary())[1]
|
||||
libfile = os.path.splitext(libfile)[0]
|
||||
return libfile
|
||||
|
||||
def loadData(self):
|
||||
PathLog.track()
|
||||
self.toolModel.clear()
|
||||
self.toolModel.setHorizontalHeaderLabels(self.columnNames())
|
||||
self.form.lblLibrary.setText(self.curLib())
|
||||
self.factory.libraryOpen(self.toolModel)
|
||||
self.toolModel.takeColumn(3)
|
||||
self.toolModel.takeColumn(2)
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track()
|
||||
self.loadData()
|
||||
|
||||
self.form.tools.setModel(self.toolModel)
|
||||
self.form.tools.selectionModel().selectionChanged.connect(self.enableButtons)
|
||||
self.form.tools.doubleClicked.connect(partial(self.selectedOrAllToolControllers))
|
||||
self.form.libraryEditorOpen.clicked.connect(self.libraryEditorOpen)
|
||||
self.form.addToolController.clicked.connect(self.selectedOrAllToolControllers)
|
||||
|
||||
def enableButtons(self):
|
||||
selected = (len(self.form.tools.selectedIndexes()) >= 1)
|
||||
if selected:
|
||||
jobs = len([1 for j in FreeCAD.ActiveDocument.Objects if j.Name[:3] == "Job"]) >= 1
|
||||
self.form.addToolController.setEnabled(selected and jobs)
|
||||
|
||||
def libraryEditorOpen(self):
|
||||
library = ToolBitLibrary()
|
||||
library.open()
|
||||
self.loadData()
|
||||
|
||||
def selectedOrAllTools(self):
|
||||
'''
|
||||
Iterate the selection and add individual tools
|
||||
If a group is selected, iterate and add children
|
||||
'''
|
||||
|
||||
itemsToProcess = []
|
||||
for index in self.form.tools.selectedIndexes():
|
||||
item = index.model().itemFromIndex(index)
|
||||
|
||||
if item.hasChildren():
|
||||
for i in range(item.rowCount()-1):
|
||||
if item.child(i).column() == 0:
|
||||
itemsToProcess.append(item.child(i))
|
||||
|
||||
elif item.column() == 0:
|
||||
itemsToProcess.append(item)
|
||||
|
||||
tools = []
|
||||
for item in itemsToProcess:
|
||||
toolNr = int(item.data(PySide.QtCore.Qt.EditRole))
|
||||
toolPath = item.data(_PathRole)
|
||||
tools.append((toolNr, PathToolBit.Factory.CreateFrom(toolPath)))
|
||||
return tools
|
||||
|
||||
def selectedOrAllToolControllers(self, index=None):
|
||||
'''
|
||||
if no jobs, don't do anything, otherwise all TCs for all
|
||||
selected toolbits
|
||||
'''
|
||||
jobs = PathUtilsGui.PathUtils.GetJobs()
|
||||
if len(jobs) == 0:
|
||||
return
|
||||
elif len(jobs) == 1:
|
||||
job = jobs[0]
|
||||
else:
|
||||
userinput = PathUtilsGui.PathUtilsUserInput()
|
||||
job = userinput.chooseJob(jobs)
|
||||
|
||||
if job is None: # user may have canceled
|
||||
return
|
||||
|
||||
tools = self.selectedOrAllTools()
|
||||
|
||||
for tool in tools:
|
||||
tc = PathToolControllerGui.Create(tool[1].Label, tool[1], tool[0])
|
||||
job.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def open(self, path=None):
|
||||
''' load library stored in path and bring up ui'''
|
||||
docs = FreeCADGui.getMainWindow().findChildren(QtGui.QDockWidget)
|
||||
for doc in docs:
|
||||
if doc.objectName() == "ToolSelector":
|
||||
if doc.isVisible():
|
||||
doc.deleteLater()
|
||||
return
|
||||
else:
|
||||
doc.setVisible(True)
|
||||
return
|
||||
|
||||
mw = FreeCADGui.getMainWindow()
|
||||
mw.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.form,
|
||||
PySide.QtCore.Qt.Orientation.Vertical)
|
||||
|
||||
|
||||
class ToolBitLibrary(object):
|
||||
'''ToolBitLibrary is the controller for
|
||||
displaying/selecting/creating/editing a collection of ToolBits.'''
|
||||
|
||||
def __init__(self):
|
||||
PathLog.track()
|
||||
self.factory = ModelFactory()
|
||||
self.temptool = None
|
||||
self.toolModel = PySide.QtGui.QStandardItemModel(0, len(self.columnNames()))
|
||||
self.listModel = PySide.QtGui.QStandardItemModel()
|
||||
self.form = FreeCADGui.PySideUic.loadUi(':/panels/ToolBitLibraryEdit.ui')
|
||||
self.toolTableView = _TableView(self.form.toolTableGroup)
|
||||
self.form.toolTableGroup.layout().replaceWidget(self.form.toolTable, self.toolTableView)
|
||||
self.form.toolTable.hide()
|
||||
self.setupUI()
|
||||
self.title = self.form.windowTitle()
|
||||
self.LibFiles = []
|
||||
if path:
|
||||
self.libraryLoad(path)
|
||||
|
||||
self.form.addToolController.setEnabled(False)
|
||||
self.form.ButtonRemoveToolTable.setEnabled(False)
|
||||
self.form.ButtonRenameToolTable.setEnabled(False)
|
||||
|
||||
def _toolAdd(self, nr, tool, path):
|
||||
toolNr = PySide.QtGui.QStandardItem()
|
||||
toolNr.setData(nr, PySide.QtCore.Qt.EditRole)
|
||||
toolNr.setData(path, _PathRole)
|
||||
toolNr.setData(UUID.uuid4(), _UuidRole)
|
||||
|
||||
toolName = PySide.QtGui.QStandardItem()
|
||||
toolName.setData(tool['name'], PySide.QtCore.Qt.EditRole)
|
||||
toolName.setEditable(False)
|
||||
|
||||
toolShape = PySide.QtGui.QStandardItem()
|
||||
toolShape.setData(os.path.splitext(os.path.basename(tool['shape']))[0], PySide.QtCore.Qt.EditRole)
|
||||
toolShape.setEditable(False)
|
||||
|
||||
toolDiameter = PySide.QtGui.QStandardItem()
|
||||
toolDiameter.setData(tool['parameter']['Diameter'], PySide.QtCore.Qt.EditRole)
|
||||
toolDiameter.setEditable(False)
|
||||
|
||||
self.model.appendRow([toolNr, toolName, toolShape, toolDiameter])
|
||||
|
||||
def toolAdd(self):
|
||||
def toolBitNew(self):
|
||||
PathLog.track()
|
||||
# pylint: disable=broad-except
|
||||
try:
|
||||
nr = 0
|
||||
for row in range(self.model.rowCount()):
|
||||
itemNr = int(self.model.item(row, 0).data(PySide.QtCore.Qt.EditRole))
|
||||
nr = max(nr, itemNr)
|
||||
nr += 1
|
||||
|
||||
for i, foo in enumerate(PathToolBitGui.GetToolFiles(self.form)):
|
||||
tool = PathToolBit.Declaration(foo)
|
||||
self._toolAdd(nr + i, tool, foo)
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
except Exception:
|
||||
PathLog.error('something happened')
|
||||
PathLog.error(traceback.print_exc())
|
||||
# select the shape file
|
||||
shapefile = PathToolBitGui.GetToolShapeFile()
|
||||
if shapefile is None: # user canceled
|
||||
return
|
||||
|
||||
def selectedOrAllTools(self):
|
||||
selectedRows = set([index.row() for index in self.toolTableView.selectedIndexes()])
|
||||
if not selectedRows:
|
||||
selectedRows = list(range(self.model.rowCount()))
|
||||
tools = []
|
||||
for row in selectedRows:
|
||||
item = self.model.item(row, 0)
|
||||
toolNr = int(item.data(PySide.QtCore.Qt.EditRole))
|
||||
toolPath = item.data(_PathRole)
|
||||
tools.append((toolNr, PathToolBit.Factory.CreateFrom(toolPath)))
|
||||
return tools
|
||||
filename = PathToolBitGui.GetNewToolFile()
|
||||
if filename is None:
|
||||
return
|
||||
|
||||
def selectedOrAllToolControllers(self):
|
||||
tools = self.selectedOrAllTools()
|
||||
# Parse out the name of the file and write the structure
|
||||
loc, fil = os.path.split(filename)
|
||||
fname = os.path.splitext(fil)[0]
|
||||
fullpath = "{}/{}.fctb".format(loc, fname)
|
||||
PathLog.debug(fullpath)
|
||||
|
||||
userinput = PathUtilsGui.PathUtilsUserInput()
|
||||
job = userinput.chooseJob(PathUtilsGui.PathUtils.GetJobs())
|
||||
for tool in tools:
|
||||
print(tool)
|
||||
tc = PathToolControllerGui.Create(tool[1].Label, tool[1], tool[0])
|
||||
job.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
self.temptool = PathToolBit.ToolBitFactory().Create(name=fname)
|
||||
self.temptool.BitShape = shapefile
|
||||
self.temptool.Proxy.unloadBitBody(self.temptool)
|
||||
self.temptool.Label = fname
|
||||
self.temptool.Proxy.saveToFile(self.temptool, fullpath)
|
||||
self.temptool.Document.removeObject(self.temptool.Name)
|
||||
self.temptool = None
|
||||
|
||||
# add it to the model
|
||||
self.factory.newTool(self.toolModel, fullpath)
|
||||
|
||||
def toolBitExisting(self):
|
||||
|
||||
filenames = PathToolBitGui.GetToolFiles()
|
||||
|
||||
if len(filenames) == 0:
|
||||
return
|
||||
|
||||
for f in filenames:
|
||||
|
||||
loc, fil = os.path.split(f)
|
||||
fname = os.path.splitext(fil)[0]
|
||||
fullpath = "{}/{}.fctb".format(loc, fname)
|
||||
|
||||
self.factory.newTool(self.toolModel, fullpath)
|
||||
|
||||
def toolDelete(self):
|
||||
PathLog.track()
|
||||
selectedRows = set([index.row() for index in self.toolTableView.selectedIndexes()])
|
||||
for row in sorted(list(selectedRows), key=lambda r: -r):
|
||||
self.model.removeRows(row, 1)
|
||||
|
||||
def libraryDelete(self):
|
||||
PathLog.track()
|
||||
reply = QtGui.QMessageBox.question(self.form, 'Warning', "Delete " + os.path.basename(self.path) + "?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)
|
||||
if reply == QtGui.QMessageBox.Yes and len(self.path) > 0:
|
||||
os.remove(self.path)
|
||||
PathPreferences.setLastPathToolTable("")
|
||||
self.libraryOpen(filedialog=False)
|
||||
|
||||
def toolEnumerate(self):
|
||||
PathLog.track()
|
||||
for row in range(self.model.rowCount()):
|
||||
self.model.setData(self.model.index(row, 0), row + 1, PySide.QtCore.Qt.EditRole)
|
||||
self.toolModel.removeRows(row, 1)
|
||||
|
||||
def toolSelect(self, selected, deselected):
|
||||
# pylint: disable=unused-argument
|
||||
sel = len(self.toolTableView.selectedIndexes()) > 0
|
||||
self.form.toolDelete.setEnabled(sel)
|
||||
|
||||
if sel:
|
||||
self.form.addToolController.setEnabled(True)
|
||||
else:
|
||||
self.form.addToolController.setEnabled(False)
|
||||
|
||||
def tableSelected(self, index):
|
||||
''' loads the tools for the selected tool table '''
|
||||
name = self.form.TableList.itemWidget(self.form.TableList.itemFromIndex(index)).getTableName()
|
||||
self.libraryLoad(PathPreferences.lastPathToolLibrary() + '/' + name)
|
||||
self.form.ButtonRemoveToolTable.setEnabled(True)
|
||||
self.form.ButtonRenameToolTable.setEnabled(True)
|
||||
PathLog.track()
|
||||
item = index.model().itemFromIndex(index)
|
||||
libpath = item.data(_PathRole)
|
||||
self.loadData(libpath)
|
||||
self.path = libpath
|
||||
|
||||
def open(self, path=None, dialog=False):
|
||||
'''open(path=None, dialog=False) ... load library stored in path and bring up ui.
|
||||
Returns 1 if user pressed OK, 0 otherwise.'''
|
||||
if path:
|
||||
self.libraryOpen(path, filedialog=False)
|
||||
elif dialog:
|
||||
self.libraryOpen(None, True)
|
||||
else:
|
||||
self.libraryOpen(None, False)
|
||||
def open(self):
|
||||
PathLog.track()
|
||||
return self.form.exec_()
|
||||
|
||||
def updateToolbar(self):
|
||||
if self.path:
|
||||
self.form.librarySave.setEnabled(True)
|
||||
else:
|
||||
self.form.librarySave.setEnabled(False)
|
||||
|
||||
def libraryOpen(self, path=None, filedialog=True):
|
||||
import glob
|
||||
def libraryPath(self):
|
||||
PathLog.track()
|
||||
path = PySide.QtGui.QFileDialog.getExistingDirectory(self.form, 'Tool Library Path', PathPreferences.lastPathToolLibrary())
|
||||
if len(path) == 0:
|
||||
return
|
||||
|
||||
# Load default search path
|
||||
path = PathPreferences.lastPathToolLibrary()
|
||||
PathPreferences.setLastPathToolLibrary(path)
|
||||
self.loadData()
|
||||
|
||||
if filedialog or len(path) == 0:
|
||||
path = PySide.QtGui.QFileDialog.getExistingDirectory(self.form, 'Tool Library Path', PathPreferences.lastPathToolLibrary())
|
||||
if len(path) > 0:
|
||||
PathPreferences.setLastPathToolLibrary(path)
|
||||
else:
|
||||
return
|
||||
def cleanupDocument(self):
|
||||
# This feels like a hack. Remove the toolbit object
|
||||
# remove the editor from the dialog
|
||||
# re-enable all the controls
|
||||
self.temptool.Proxy.unloadBitBody(self.temptool)
|
||||
self.temptool.Document.removeObject(self.temptool.Name)
|
||||
self.temptool = None
|
||||
widget = self.form.toolTableGroup.children()[-1]
|
||||
widget.setParent(None)
|
||||
self.editor = None
|
||||
self.lockoff()
|
||||
|
||||
# Clear view
|
||||
self.form.TableList.clear()
|
||||
self.LibFiles.clear()
|
||||
self.form.lineLibPath.clear()
|
||||
self.form.lineLibPath.insert(path)
|
||||
def accept(self):
|
||||
self.editor.accept()
|
||||
self.temptool.Proxy.saveToFile(self.temptool, self.temptool.File)
|
||||
self.librarySave()
|
||||
self.loadData()
|
||||
self.cleanupDocument()
|
||||
|
||||
# Find all tool tables in directory
|
||||
for file in glob.glob(path + '/*.fctl'):
|
||||
self.LibFiles.append(file)
|
||||
def reject(self):
|
||||
self.cleanupDocument()
|
||||
|
||||
self.LibFiles.sort()
|
||||
def lockon(self):
|
||||
self.toolTableView.setEnabled(False)
|
||||
self.form.toolCreate.setEnabled(False)
|
||||
self.form.toolDelete.setEnabled(False)
|
||||
self.form.toolAdd.setEnabled(False)
|
||||
self.form.TableList.setEnabled(False)
|
||||
self.form.libraryOpen.setEnabled(False)
|
||||
self.form.libraryExport.setEnabled(False)
|
||||
self.form.addToolTable.setEnabled(False)
|
||||
self.form.librarySave.setEnabled(False)
|
||||
|
||||
# Add all tables to list
|
||||
for table in self.LibFiles:
|
||||
listWidgetItem = QtGui.QListWidgetItem()
|
||||
listItem = ToolTableListWidgetItem()
|
||||
listItem.setTableName(os.path.basename(table))
|
||||
listItem.setIcon(QtGui.QPixmap(':/icons/Path-ToolTable.svg'))
|
||||
listWidgetItem.setSizeHint(QtCore.QSize(0, 40))
|
||||
self.form.TableList.addItem(listWidgetItem)
|
||||
self.form.TableList.setItemWidget(listWidgetItem, listItem)
|
||||
def lockoff(self):
|
||||
self.toolTableView.setEnabled(True)
|
||||
self.form.toolCreate.setEnabled(True)
|
||||
self.form.toolDelete.setEnabled(True)
|
||||
self.form.toolAdd.setEnabled(True)
|
||||
self.form.toolTable.setEnabled(True)
|
||||
self.form.TableList.setEnabled(True)
|
||||
self.form.libraryOpen.setEnabled(True)
|
||||
self.form.libraryExport.setEnabled(True)
|
||||
self.form.addToolTable.setEnabled(True)
|
||||
self.form.librarySave.setEnabled(True)
|
||||
|
||||
self.path = []
|
||||
self.form.ButtonRemoveToolTable.setEnabled(False)
|
||||
self.form.ButtonRenameToolTable.setEnabled(False)
|
||||
def toolEdit(self, selected):
|
||||
item = self.toolModel.item(selected.row(), 0)
|
||||
|
||||
self.toolTableView.setUpdatesEnabled(False)
|
||||
self.model.clear()
|
||||
self.model.setHorizontalHeaderLabels(self.columnNames())
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
self.toolTableView.setUpdatesEnabled(True)
|
||||
if self.temptool is not None:
|
||||
self.temptool.Document.removeObject(self.temptool.Name)
|
||||
|
||||
# Search last selected table
|
||||
if len(self.LibFiles) > 0:
|
||||
for idx in range(len(self.LibFiles)):
|
||||
if PathPreferences.lastPathToolTable() == os.path.basename(self.LibFiles[idx]):
|
||||
break
|
||||
# Not found, select first entry
|
||||
if idx >= len(self.LibFiles):
|
||||
idx = 0
|
||||
if selected.column() == 0: # editing Nr
|
||||
pass
|
||||
else:
|
||||
tbpath = item.data(_PathRole)
|
||||
self.temptool = PathToolBit.ToolBitFactory().CreateFrom(tbpath, 'temptool')
|
||||
self.editor = PathToolBitEdit.ToolBitEditor(self.temptool, self.form.toolTableGroup, loadBitBody=False)
|
||||
|
||||
# Load selected table
|
||||
self.libraryLoad(self.LibFiles[idx])
|
||||
self.form.TableList.setCurrentRow(idx)
|
||||
self.form.ButtonRemoveToolTable.setEnabled(True)
|
||||
self.form.ButtonRenameToolTable.setEnabled(True)
|
||||
QBtn = QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel
|
||||
buttonBox = QtGui.QDialogButtonBox(QBtn)
|
||||
buttonBox.accepted.connect(self.accept)
|
||||
buttonBox.rejected.connect(self.reject)
|
||||
|
||||
def libraryLoad(self, path):
|
||||
self.toolTableView.setUpdatesEnabled(False)
|
||||
self.model.clear()
|
||||
self.model.setHorizontalHeaderLabels(self.columnNames())
|
||||
layout = self.editor.form.layout()
|
||||
layout.addWidget(buttonBox)
|
||||
self.lockon()
|
||||
self.editor.setupUI()
|
||||
|
||||
if path:
|
||||
with open(path) as fp:
|
||||
PathPreferences.setLastPathToolTable(os.path.basename(path))
|
||||
library = json.load(fp)
|
||||
|
||||
for toolBit in library['tools']:
|
||||
nr = toolBit['nr']
|
||||
bit = PathToolBit.findBit(toolBit['path'])
|
||||
if bit:
|
||||
PathLog.track(bit)
|
||||
tool = PathToolBit.Declaration(bit)
|
||||
self._toolAdd(nr, tool, bit)
|
||||
else:
|
||||
PathLog.error("Could not find tool #{}: {}".format(nr, library['tools'][nr]))
|
||||
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
|
||||
self.toolTableView.setUpdatesEnabled(True)
|
||||
|
||||
self.form.setWindowTitle("{} - {}".format(self.title, os.path.basename(path) if path else ''))
|
||||
self.path = path
|
||||
self.updateToolbar()
|
||||
def toolEditDone(self, success=True):
|
||||
FreeCAD.ActiveDocument.removeObject("temptool")
|
||||
print('all done')
|
||||
|
||||
def libraryNew(self):
|
||||
self.libraryLoad(None)
|
||||
self.librarySaveAs()
|
||||
TooltableTypeJSON = translate("PathToolLibraryManager", "Tooltable JSON (*.fctl)")
|
||||
|
||||
def renameLibrary(self):
|
||||
name = self.form.TableList.itemWidget(self.form.TableList.currentItem()).getTableName()
|
||||
newName, ok = QtGui.QInputDialog.getText(None, translate(
|
||||
"TooltableEditor", "Rename Tooltable"), translate(
|
||||
"TooltableEditor", "Enter Name:"), QtGui.QLineEdit.Normal, name)
|
||||
if ok and newName:
|
||||
os.rename(PathPreferences.lastPathToolLibrary() + '/' + name, PathPreferences.lastPathToolLibrary() + '/' + newName)
|
||||
self.libraryOpen(filedialog=False)
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(), "{}".format(TooltableTypeJSON))
|
||||
|
||||
# def createToolBit(self):
|
||||
# tool = PathToolBit.ToolBitFactory().Create()
|
||||
if not (filename and filename[0]):
|
||||
self.loadData()
|
||||
|
||||
# #self.dialog = PySide.QtGui.QDialog(self.form)
|
||||
# #layout = PySide.QtGui.QVBoxLayout(self.dialog)
|
||||
# self.editor = PathToolBitEdit.ToolBitEditor(tool, self.form.toolTableGroup)
|
||||
# self.editor.setupUI()
|
||||
# self.buttons = PySide.QtGui.QDialogButtonBox(
|
||||
# PySide.QtGui.QDialogButtonBox.Ok | PySide.QtGui.QDialogButtonBox.Cancel,
|
||||
# PySide.QtCore.Qt.Horizontal, self.dialog)
|
||||
# layout.addWidget(self.buttons)
|
||||
# #self.buttons.accepted.connect(accept)
|
||||
# #self.buttons.rejected.connect(reject)
|
||||
# print(self.dialog.exec_())
|
||||
path = filename[0] if filename[0].endswith('.fctl') else "{}.fctl".format(filename[0])
|
||||
library = {}
|
||||
tools = []
|
||||
library['version'] = 1
|
||||
library['tools'] = tools
|
||||
with open(path, 'w') as fp:
|
||||
json.dump(library, fp, sort_keys=True, indent=2)
|
||||
|
||||
self.loadData()
|
||||
|
||||
def librarySave(self):
|
||||
library = {}
|
||||
tools = []
|
||||
library['version'] = 1
|
||||
library['tools'] = tools
|
||||
for row in range(self.model.rowCount()):
|
||||
toolNr = self.model.data(self.model.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolPath = self.model.data(self.model.index(row, 0), _PathRole)
|
||||
for row in range(self.toolModel.rowCount()):
|
||||
toolNr = self.toolModel.data(self.toolModel.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolPath = self.toolModel.data(self.toolModel.index(row, 0), _PathRole)
|
||||
if PathPreferences.toolsStoreAbsolutePaths():
|
||||
tools.append({'nr': toolNr, 'path': toolPath})
|
||||
else:
|
||||
@@ -400,13 +554,109 @@ class ToolBitLibrary(object):
|
||||
with open(self.path, 'w') as fp:
|
||||
json.dump(library, fp, sort_keys=True, indent=2)
|
||||
|
||||
def libraryOk(self):
|
||||
self.librarySave()
|
||||
self.form.close()
|
||||
|
||||
def libPaths(self):
|
||||
lib = PathPreferences.lastFileToolLibrary()
|
||||
loc = PathPreferences.lastPathToolLibrary()
|
||||
|
||||
PathLog.track("lib: {} loc: {}".format(lib, loc))
|
||||
return lib, loc
|
||||
|
||||
def columnNames(self):
|
||||
return ['Nr', 'Tool', 'Shape']
|
||||
|
||||
def loadData(self, path=None):
|
||||
PathLog.track(path)
|
||||
self.toolTableView.setUpdatesEnabled(False)
|
||||
self.form.TableList.setUpdatesEnabled(False)
|
||||
|
||||
if path is None:
|
||||
path, loc = self.libPaths()
|
||||
|
||||
self.toolModel.clear()
|
||||
self.listModel.clear()
|
||||
self.factory.libraryOpen(self.toolModel, lib=path)
|
||||
self.factory.findLibraries(self.listModel)
|
||||
|
||||
else:
|
||||
self.toolModel.clear()
|
||||
self.factory.libraryOpen(self.toolModel, lib=path)
|
||||
|
||||
self.path = path
|
||||
self.form.setWindowTitle("{}".format(PathPreferences.lastPathToolLibrary()))
|
||||
self.toolModel.setHorizontalHeaderLabels(self.columnNames())
|
||||
self.listModel.setHorizontalHeaderLabels(['Library'])
|
||||
|
||||
# Select the current library in the list of tables
|
||||
curIndex = None
|
||||
for i in range(self.listModel.rowCount()):
|
||||
item = self.listModel.item(i)
|
||||
if item.data(_PathRole) == path:
|
||||
curIndex = self.listModel.indexFromItem(item)
|
||||
|
||||
if curIndex:
|
||||
sm = self.form.TableList.selectionModel()
|
||||
sm.select(curIndex, QtCore.QItemSelectionModel.Select)
|
||||
|
||||
self.toolTableView.setUpdatesEnabled(True)
|
||||
self.form.TableList.setUpdatesEnabled(True)
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track()
|
||||
self.form.TableList.setModel(self.listModel)
|
||||
self.toolTableView.setModel(self.toolModel)
|
||||
|
||||
self.loadData()
|
||||
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
self.toolTableView.selectionModel().selectionChanged.connect(self.toolSelect)
|
||||
self.toolTableView.doubleClicked.connect(self.toolEdit)
|
||||
|
||||
self.form.TableList.clicked.connect(self.tableSelected)
|
||||
|
||||
self.form.toolAdd.clicked.connect(self.toolBitExisting)
|
||||
self.form.toolDelete.clicked.connect(self.toolDelete)
|
||||
self.form.toolCreate.clicked.connect(self.toolBitNew)
|
||||
|
||||
self.form.addToolTable.clicked.connect(self.libraryNew)
|
||||
|
||||
self.form.libraryOpen.clicked.connect(self.libraryPath)
|
||||
self.form.librarySave.clicked.connect(self.libraryOk)
|
||||
self.form.libraryExport.clicked.connect(self.librarySaveAs)
|
||||
|
||||
self.toolSelect([], [])
|
||||
|
||||
def librarySaveAs(self, path):
|
||||
|
||||
TooltableTypeJSON = translate("PathToolLibraryManager", "Tooltable JSON (*.fctl)")
|
||||
TooltableTypeLinuxCNC = translate("PathToolLibraryManager", "LinuxCNC tooltable (*.tbl)")
|
||||
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(), "{};;{}".format(TooltableTypeJSON,
|
||||
TooltableTypeLinuxCNC))
|
||||
if filename and filename[0]:
|
||||
if filename[1] == TooltableTypeLinuxCNC:
|
||||
path = filename[0] if filename[0].endswith('.tbl') else "{}.tbl".format(filename[0])
|
||||
self.libararySaveLinuxCNC(path)
|
||||
else:
|
||||
path = filename[0] if filename[0].endswith('.fctl') else "{}.fctl".format(filename[0])
|
||||
self.path = path
|
||||
self.librarySave()
|
||||
self.updateToolbar()
|
||||
|
||||
def libararySaveLinuxCNC(self, path):
|
||||
# linuxcnc line template
|
||||
LIN = "T{} P{} X{} Y{} Z{} A{} B{} C{} U{} V{} W{} D{} I{} J{} Q{}; {}"
|
||||
with open(path, 'w') as fp:
|
||||
fp.write(";\n")
|
||||
|
||||
for row in range(self.model.rowCount()):
|
||||
toolNr = self.model.data(self.model.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolPath = self.model.data(self.model.index(row, 0), _PathRole)
|
||||
for row in range(self.toolModel.rowCount()):
|
||||
toolNr = self.toolModel.data(self.toolModel.index(row, 0), PySide.QtCore.Qt.EditRole)
|
||||
toolPath = self.toolModel.data(self.toolModel.index(row, 0), _PathRole)
|
||||
|
||||
bit = PathToolBit.Factory.CreateFrom(toolPath)
|
||||
if bit:
|
||||
@@ -429,129 +679,12 @@ class ToolBitLibrary(object):
|
||||
orientation = bit.Orientation if hasattr(bit, "Orientation") else "0"
|
||||
remark = bit.Label
|
||||
|
||||
fp.write("T%s P%s X%s Y%s Z%s A%s B%s C%s U%s V%s W%s D%s I%s J%s Q%s ; %s\n" %
|
||||
(toolNr,
|
||||
pocket,
|
||||
xoffset,
|
||||
yoffset,
|
||||
zoffset,
|
||||
aoffset,
|
||||
boffset,
|
||||
coffset,
|
||||
uoffset,
|
||||
voffset,
|
||||
woffset,
|
||||
diameter,
|
||||
frontangle,
|
||||
backangle,
|
||||
orientation,
|
||||
remark))
|
||||
fp.write(LIN.format(toolNr, pocket, xoffset, yoffset,
|
||||
zoffset, aoffset, boffset, coffset, uoffset,
|
||||
voffset, woffset, diameter, frontangle, backangle,
|
||||
orientation, remark) + "\n")
|
||||
|
||||
FreeCAD.ActiveDocument.removeObject(bit.Name)
|
||||
|
||||
else:
|
||||
PathLog.error("Could not find tool #{} ".format(toolNr))
|
||||
|
||||
def librarySaveAs(self):
|
||||
TooltableTypeJSON = translate("PathToolLibraryManager", "Tooltable JSON (*.fctl)")
|
||||
TooltableTypeLinuxCNC = translate("PathToolLibraryManager", "LinuxCNC tooltable (*.tbl)")
|
||||
|
||||
filename = PySide.QtGui.QFileDialog.getSaveFileName(self.form,
|
||||
translate("TooltableEditor", "Save toolbit library", None),
|
||||
PathPreferences.lastPathToolLibrary(), "{};;{}".format(TooltableTypeJSON,
|
||||
TooltableTypeLinuxCNC))
|
||||
# filename = PySide.QtGui.QFileDialog.getSaveFileName(self.form, \
|
||||
# 'Tool Library', PathPreferences.lastPathToolLibrary(), '*.fctl')
|
||||
if filename and filename[0]:
|
||||
if filename[1] == TooltableTypeLinuxCNC:
|
||||
path = filename[0] if filename[0].endswith('.tbl') else "{}.tbl".format(filename[0])
|
||||
self.libararySaveLinuxCNC(path)
|
||||
else:
|
||||
path = filename[0] if filename[0].endswith('.fctl') else "{}.fctl".format(filename[0])
|
||||
PathPreferences.setLastPathToolLibrary(os.path.dirname(path))
|
||||
self.path = path
|
||||
self.librarySave()
|
||||
self.updateToolbar()
|
||||
PathPreferences.setLastPathToolTable(os.path.basename(path))
|
||||
self.libraryOpen(None, False)
|
||||
|
||||
def libraryCancel(self):
|
||||
self.form.close()
|
||||
|
||||
def columnNames(self):
|
||||
return ['Nr', 'Tool', 'Shape', 'Diameter']
|
||||
|
||||
def toolEdit(self, selected):
|
||||
print('here')
|
||||
print(selected)
|
||||
if selected.column() == 0:
|
||||
print('nope')
|
||||
else:
|
||||
print('yep')
|
||||
|
||||
def setupUI(self):
|
||||
PathLog.track('+')
|
||||
self.model = PySide.QtGui.QStandardItemModel(0, len(self.columnNames()), self.toolTableView)
|
||||
self.model.setHorizontalHeaderLabels(self.columnNames())
|
||||
|
||||
self.toolTableView.setModel(self.model)
|
||||
self.toolTableView.resizeColumnsToContents()
|
||||
self.toolTableView.selectionModel().selectionChanged.connect(self.toolSelect)
|
||||
self.toolTableView.doubleClicked.connect(self.toolEdit)
|
||||
|
||||
self.form.toolAdd.clicked.connect(self.toolAdd)
|
||||
self.form.toolDelete.clicked.connect(self.toolDelete)
|
||||
self.form.toolEnumerate.clicked.connect(self.toolEnumerate)
|
||||
# self.form.createToolBit.clicked.connect(self.createToolBit)
|
||||
|
||||
self.form.ButtonAddToolTable.clicked.connect(self.libraryNew)
|
||||
self.form.ButtonRemoveToolTable.clicked.connect(self.libraryDelete)
|
||||
self.form.ButtonRenameToolTable.clicked.connect(self.renameLibrary)
|
||||
|
||||
# self.form.libraryNew.clicked.connect(self.libraryNew)
|
||||
self.form.libraryOpen.clicked.connect(partial(self.libraryOpen, filedialog=True))
|
||||
self.form.librarySave.clicked.connect(self.librarySave)
|
||||
self.form.librarySaveAs.clicked.connect(self.librarySaveAs)
|
||||
self.form.libraryCancel.clicked.connect(self.libraryCancel)
|
||||
|
||||
self.form.addToolController.clicked.connect(self.selectedOrAllToolControllers)
|
||||
|
||||
self.form.TableList.clicked.connect(self.tableSelected)
|
||||
|
||||
self.toolSelect([], [])
|
||||
self.updateToolbar()
|
||||
PathLog.track('-')
|
||||
|
||||
|
||||
class ToolTableListWidgetItem(QtGui.QWidget):
|
||||
toolMoved = QtCore.Signal()
|
||||
|
||||
def __init__(self):
|
||||
super(ToolTableListWidgetItem, self).__init__()
|
||||
|
||||
self.setAcceptDrops(True)
|
||||
|
||||
self.mainLayout = QtGui.QHBoxLayout()
|
||||
self.iconQLabel = QtGui.QLabel()
|
||||
self.tableNameLabel = QtGui.QLabel()
|
||||
self.mainLayout.addWidget(self.iconQLabel, 0)
|
||||
self.mainLayout.addWidget(self.tableNameLabel, 1)
|
||||
self.setLayout(self.mainLayout)
|
||||
|
||||
def setTableName(self, text):
|
||||
self.tableNameLabel.setText(text)
|
||||
|
||||
def getTableName(self):
|
||||
return self.tableNameLabel.text()
|
||||
|
||||
def setIcon(self, icon):
|
||||
icon = icon.scaled(22, 22)
|
||||
self.iconQLabel.setPixmap(icon)
|
||||
|
||||
# def dragEnterEvent(self, e):
|
||||
# currentToolTable = self.tlm.getCurrentTableName()
|
||||
# thisToolTable = self.getTableName()
|
||||
|
||||
def dropEvent(self, e):
|
||||
selectedTools = e.source().selectedIndexes()
|
||||
print("Drop: {}, {}".format(selectedTools, selectedTools[1].data()))
|
||||
|
||||
@@ -30,16 +30,17 @@ import PathScripts.PathToolBit as PathToolBit
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
#PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
#PathLog.trackModule(PathLog.thisModule())
|
||||
# PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
# PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
|
||||
# Qt translation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
class ToolControllerTemplate:
|
||||
'''Attribute and sub element strings for template export/import.'''
|
||||
# pylint: disable=no-init
|
||||
|
||||
Expressions = 'xengine'
|
||||
ExprExpr = 'expr'
|
||||
@@ -56,21 +57,36 @@ class ToolControllerTemplate:
|
||||
VertFeed = 'vfeed'
|
||||
VertRapid = 'vrapid'
|
||||
|
||||
|
||||
class ToolController:
|
||||
|
||||
def __init__(self, obj, cTool=False):
|
||||
PathLog.track('tool: {}'.format(cTool))
|
||||
|
||||
obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber", "Tool", QtCore.QT_TRANSLATE_NOOP("PathToolController", "The active tool"))
|
||||
obj.addProperty("App::PropertyIntegerConstraint", "ToolNumber",
|
||||
"Tool", QtCore.QT_TRANSLATE_NOOP("PathToolController",
|
||||
"The active tool"))
|
||||
obj.ToolNumber = (0, 0, 10000, 1)
|
||||
self.ensureUseLegacyTool(obj, cTool)
|
||||
obj.addProperty("App::PropertyFloat", "SpindleSpeed", "Tool", QtCore.QT_TRANSLATE_NOOP("PathToolController", "The speed of the cutting spindle in RPM"))
|
||||
obj.addProperty("App::PropertyEnumeration", "SpindleDir", "Tool", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Direction of spindle rotation"))
|
||||
obj.addProperty("App::PropertyFloat", "SpindleSpeed", "Tool",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathToolController",
|
||||
"The speed of the cutting spindle in RPM"))
|
||||
obj.addProperty("App::PropertyEnumeration", "SpindleDir", "Tool",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathToolController",
|
||||
"Direction of spindle rotation"))
|
||||
obj.SpindleDir = ['Forward', 'Reverse']
|
||||
obj.addProperty("App::PropertySpeed", "VertFeed", "Feed", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Feed rate for vertical moves in Z"))
|
||||
obj.addProperty("App::PropertySpeed", "HorizFeed", "Feed", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Feed rate for horizontal moves"))
|
||||
obj.addProperty("App::PropertySpeed", "VertRapid", "Rapid", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Rapid rate for vertical moves in Z"))
|
||||
obj.addProperty("App::PropertySpeed", "HorizRapid", "Rapid", QtCore.QT_TRANSLATE_NOOP("PathToolController", "Rapid rate for horizontal moves"))
|
||||
obj.addProperty("App::PropertySpeed", "VertFeed", "Feed",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathToolController",
|
||||
"Feed rate for vertical moves in Z"))
|
||||
obj.addProperty("App::PropertySpeed", "HorizFeed", "Feed",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathToolController",
|
||||
"Feed rate for horizontal moves"))
|
||||
obj.addProperty("App::PropertySpeed", "VertRapid", "Rapid",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathToolController",
|
||||
"Rapid rate for vertical moves in Z"))
|
||||
obj.addProperty("App::PropertySpeed", "HorizRapid", "Rapid",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathToolController",
|
||||
"Rapid rate for horizontal moves"))
|
||||
obj.setEditorMode('Placement', 2)
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
@@ -82,10 +98,12 @@ class ToolController:
|
||||
if hasattr(obj.Tool, 'InList') and len(obj.Tool.InList) == 1:
|
||||
if hasattr(obj.Tool.Proxy, 'onDelete'):
|
||||
obj.Tool.Proxy.onDelete(obj.Tool)
|
||||
obj.Document.removeObject(obj.Tool.Name)
|
||||
|
||||
def setFromTemplate(self, obj, template):
|
||||
'''setFromTemplate(obj, xmlItem) ... extract properties from xmlItem and assign to receiver.'''
|
||||
'''
|
||||
setFromTemplate(obj, xmlItem) ... extract properties from xmlItem
|
||||
and assign to receiver.
|
||||
'''
|
||||
PathLog.track(obj.Name, template)
|
||||
version = 0
|
||||
if template.get(ToolControllerTemplate.Version):
|
||||
@@ -158,10 +176,21 @@ class ToolController:
|
||||
commands += "(" + obj.Label + ")"+'\n'
|
||||
commands += 'M6 T'+str(obj.ToolNumber)+'\n'
|
||||
|
||||
if obj.SpindleDir == 'Forward':
|
||||
commands += 'M3 S' + str(obj.SpindleSpeed) + '\n'
|
||||
else:
|
||||
commands += 'M4 S' + str(obj.SpindleSpeed) + '\n'
|
||||
# If a toolbit is used, check to see if spindlepower is allowed.
|
||||
# This is to prevent accidentally spinning the spindle with an
|
||||
# unpowered tool like probe or dragknife
|
||||
|
||||
allowSpindlePower = True
|
||||
if (not isinstance(obj.Tool, Path.Tool) and
|
||||
hasattr(obj.Tool, "SpindlePower")):
|
||||
allowSpindlePower = obj.Tool.SpindlePower
|
||||
|
||||
if allowSpindlePower:
|
||||
PathLog.debug('selected tool preventing spindle power')
|
||||
if obj.SpindleDir == 'Forward':
|
||||
commands += 'M3 S' + str(obj.SpindleSpeed) + '\n'
|
||||
else:
|
||||
commands += 'M4 S' + str(obj.SpindleSpeed) + '\n'
|
||||
|
||||
if commands == "":
|
||||
commands += "(No commands processed)"
|
||||
@@ -195,13 +224,14 @@ class ToolController:
|
||||
else:
|
||||
obj.addProperty("App::PropertyLink", "Tool", "Base", QtCore.QT_TRANSLATE_NOOP("PathToolController", "The tool used by this controller"))
|
||||
|
||||
def Create(name = 'Default Tool', tool=None, toolNumber=1, assignViewProvider=True):
|
||||
|
||||
def Create(name='Default Tool', tool=None, toolNumber=1, assignViewProvider=True):
|
||||
legacyTool = PathPreferences.toolsReallyUseLegacyTools() if tool is None else isinstance(tool, Path.Tool)
|
||||
|
||||
PathLog.track(tool, toolNumber, legacyTool)
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
|
||||
obj.Label = name
|
||||
obj.Label = "TC: {}".format(name)
|
||||
obj.Proxy = ToolController(obj, legacyTool)
|
||||
|
||||
if FreeCAD.GuiUp and assignViewProvider:
|
||||
@@ -224,6 +254,7 @@ def Create(name = 'Default Tool', tool=None, toolNumber=1, assignViewProvider=Tr
|
||||
obj.ToolNumber = toolNumber
|
||||
return obj
|
||||
|
||||
|
||||
def FromTemplate(template, assignViewProvider=True):
|
||||
# pylint: disable=unused-argument
|
||||
PathLog.track()
|
||||
@@ -234,6 +265,7 @@ def FromTemplate(template, assignViewProvider=True):
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
# need ViewProvider class in this file to support loading of old files
|
||||
from PathScripts.PathToolControllerGui import ViewProvider
|
||||
|
||||
@@ -35,10 +35,12 @@ from PySide import QtCore, QtGui
|
||||
from lazy_loader.lazy_loader import LazyLoader
|
||||
Part = LazyLoader('Part', globals(), 'Part')
|
||||
|
||||
|
||||
# Qt translation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
class ViewProvider:
|
||||
|
||||
def __init__(self, vobj):
|
||||
@@ -122,7 +124,8 @@ class ViewProvider:
|
||||
return [obj.Tool]
|
||||
return []
|
||||
|
||||
def Create(name = 'Default Tool', tool=None, toolNumber=1):
|
||||
|
||||
def Create(name='Default Tool', tool=None, toolNumber=1):
|
||||
PathLog.track(tool, toolNumber)
|
||||
|
||||
obj = PathScripts.PathToolController.Create(name, tool, toolNumber)
|
||||
@@ -172,6 +175,7 @@ class CommandPathToolController(object):
|
||||
job.Proxy.addToolController(tc)
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
|
||||
class ToolControllerEditor(object):
|
||||
|
||||
def __init__(self, obj, asDialog):
|
||||
@@ -180,13 +184,18 @@ class ToolControllerEditor(object):
|
||||
self.form.buttonBox.hide()
|
||||
self.obj = obj
|
||||
|
||||
self.vertFeed = PathGui.QuantitySpinBox(self.form.vertFeed, obj, 'VertFeed')
|
||||
self.horizFeed = PathGui.QuantitySpinBox(self.form.horizFeed, obj, 'HorizFeed')
|
||||
self.vertRapid = PathGui.QuantitySpinBox(self.form.vertRapid, obj, 'VertRapid')
|
||||
self.horizRapid = PathGui.QuantitySpinBox(self.form.horizRapid, obj, 'HorizRapid')
|
||||
self.vertFeed = PathGui.QuantitySpinBox(self.form.vertFeed, obj,
|
||||
'VertFeed')
|
||||
self.horizFeed = PathGui.QuantitySpinBox(self.form.horizFeed, obj,
|
||||
'HorizFeed')
|
||||
self.vertRapid = PathGui.QuantitySpinBox(self.form.vertRapid, obj,
|
||||
'VertRapid')
|
||||
self.horizRapid = PathGui.QuantitySpinBox(self.form.horizRapid, obj,
|
||||
'HorizRapid')
|
||||
|
||||
if obj.Proxy.usesLegacyTool(obj):
|
||||
self.editor = PathToolEdit.ToolEditor(obj.Tool, self.form.toolEditor)
|
||||
self.editor = PathToolEdit.ToolEditor(obj.Tool,
|
||||
self.form.toolEditor)
|
||||
else:
|
||||
self.editor = None
|
||||
self.form.toolBox.widget(1).hide()
|
||||
@@ -201,7 +210,8 @@ class ToolControllerEditor(object):
|
||||
self.vertFeed.updateSpinBox()
|
||||
self.vertRapid.updateSpinBox()
|
||||
self.form.spindleSpeed.setValue(tc.SpindleSpeed)
|
||||
index = self.form.spindleDirection.findText(tc.SpindleDir, QtCore.Qt.MatchFixedString)
|
||||
index = self.form.spindleDirection.findText(tc.SpindleDir,
|
||||
QtCore.Qt.MatchFixedString)
|
||||
if index >= 0:
|
||||
self.form.spindleDirection.setCurrentIndex(index)
|
||||
|
||||
@@ -224,9 +234,9 @@ class ToolControllerEditor(object):
|
||||
self.editor.updateTool()
|
||||
tc.Tool = self.editor.tool
|
||||
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
PathLog.error(translate("PathToolController", "Error updating TC: %s") % e)
|
||||
|
||||
except Exception as e:
|
||||
PathLog.error(translate("PathToolController",
|
||||
"Error updating TC: %s") % e)
|
||||
|
||||
def refresh(self):
|
||||
self.form.blockSignals(True)
|
||||
@@ -296,7 +306,8 @@ class TaskPanel:
|
||||
def setupUi(self):
|
||||
if self.editor.editor:
|
||||
t = Part.makeCylinder(1, 1)
|
||||
self.toolrep = FreeCAD.ActiveDocument.addObject("Part::Feature", "tool")
|
||||
self.toolrep = FreeCAD.ActiveDocument.addObject("Part::Feature",
|
||||
"tool")
|
||||
self.toolrep.Shape = t
|
||||
|
||||
self.setFields()
|
||||
@@ -311,7 +322,7 @@ class DlgToolControllerEdit:
|
||||
self.obj = obj
|
||||
|
||||
def exec_(self):
|
||||
restoreTC = self.obj.Proxy.templateAttrs(self.obj)
|
||||
restoreTC = self.obj.Proxy.templateAttrs(self.obj)
|
||||
|
||||
rc = False
|
||||
if not self.editor.form.exec_():
|
||||
@@ -320,6 +331,7 @@ class DlgToolControllerEdit:
|
||||
rc = True
|
||||
return rc
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
# register the FreeCAD command
|
||||
FreeCADGui.addCommand('Path_ToolController', CommandPathToolController())
|
||||
|
||||
14
src/Mod/Path/Tools/Bit/45degree_chamfer.fctb
Normal file
14
src/Mod/Path/Tools/Bit/45degree_chamfer.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "45 Deg. Chamfer",
|
||||
"shape": "chamfer.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeAngle": "45.0000 \u00b0",
|
||||
"CuttingEdgeHeight": "6.3500 mm",
|
||||
"Diameter": "12.3323 mm",
|
||||
"FlatRadius": "5.0000 mm",
|
||||
"Length": "30.0000 mm",
|
||||
"ShankDiameter": "6.3500 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
11
src/Mod/Path/Tools/Bit/5mm_Drill.fctb
Normal file
11
src/Mod/Path/Tools/Bit/5mm_Drill.fctb
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "5mm Drill",
|
||||
"shape": "drill.fcstd",
|
||||
"parameter": {
|
||||
"Diameter": "5.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"TipAngle": "119.0000 \u00b0"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
12
src/Mod/Path/Tools/Bit/5mm_Endmill.fctb
Normal file
12
src/Mod/Path/Tools/Bit/5mm_Endmill.fctb
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "5mm Endmill",
|
||||
"shape": "endmill.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.0000 mm",
|
||||
"Diameter": "5.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "3.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
14
src/Mod/Path/Tools/Bit/60degree_Vbit.fctb
Normal file
14
src/Mod/Path/Tools/Bit/60degree_Vbit.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "60 Deg. V-Bit",
|
||||
"shape": "v-bit.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeAngle": "60.0000 \u00b0",
|
||||
"Diameter": "10.0000 mm",
|
||||
"FlatHeight": "1.0000 mm",
|
||||
"FlatRadius": "0.5000 mm",
|
||||
"Length": "20.0000 mm",
|
||||
"ShankDiameter": "5.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
12
src/Mod/Path/Tools/Bit/6mm_Ball_End.fctb
Normal file
12
src/Mod/Path/Tools/Bit/6mm_Ball_End.fctb
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "6mm Ball End",
|
||||
"shape": "ballend.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "40.0000 mm",
|
||||
"Diameter": "6.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "3.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
13
src/Mod/Path/Tools/Bit/6mm_Bullnose.fctb
Normal file
13
src/Mod/Path/Tools/Bit/6mm_Bullnose.fctb
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "6 mm Bull Nose",
|
||||
"shape": "bullnose.fcstd",
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "40.0000 mm",
|
||||
"Diameter": "6.0000 mm",
|
||||
"FlatRadius": "1.5000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "3.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
11
src/Mod/Path/Tools/Bit/probe.fctb
Normal file
11
src/Mod/Path/Tools/Bit/probe.fctb
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "Probe004",
|
||||
"shape": "probe.fcstd",
|
||||
"parameter": {
|
||||
"Diameter": "6.0000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShaftDiameter": "4.0000 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
14
src/Mod/Path/Tools/Bit/slittingsaw.fctb
Normal file
14
src/Mod/Path/Tools/Bit/slittingsaw.fctb
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "Slitting Saw",
|
||||
"shape": "slittingsaw.fcstd",
|
||||
"parameter": {
|
||||
"BladeThickness": "3.0000 mm",
|
||||
"BoltHeight": "3.0000 mm",
|
||||
"BoltWidth": "8.0000 mm",
|
||||
"Diameter": "76.2000 mm",
|
||||
"Length": "50.0000 mm",
|
||||
"ShankDiameter": "19.0500 mm"
|
||||
},
|
||||
"attribute": {}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "T1",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "1.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "T2",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "2.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "T3",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "3.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "T4",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "4.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "T5",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "5.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "T6",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "6.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "T7",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "7.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "T8",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "8.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"name": "T9",
|
||||
"shape": "endmill.fcstd",
|
||||
"attribute": {},
|
||||
"parameter": {
|
||||
"CuttingEdgeHeight": "30.000 mm",
|
||||
"Diameter": "9.000 mm",
|
||||
"Length": "50.000 mm",
|
||||
"ShankDiameter": "3.000 mm"
|
||||
}
|
||||
}
|
||||
37
src/Mod/Path/Tools/Library/Default.fctl
Normal file
37
src/Mod/Path/Tools/Library/Default.fctl
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"nr": 1,
|
||||
"path": "5mm_Endmill.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 2,
|
||||
"path": "5mm_Drill.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 3,
|
||||
"path": "6mm_Ball_End.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 4,
|
||||
"path": "6mm_Bullnose.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 5,
|
||||
"path": "60degree_Vbit.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 6,
|
||||
"path": "45degree_chamfer.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 7,
|
||||
"path": "slittingsaw.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 8,
|
||||
"path": "probe.fctb"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"tools": [
|
||||
{
|
||||
"nr": 1,
|
||||
"path": "t1.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 2,
|
||||
"path": "t2.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 3,
|
||||
"path": "t3.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 4,
|
||||
"path": "t4.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 5,
|
||||
"path": "t5.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 6,
|
||||
"path": "t6.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 7,
|
||||
"path": "t7.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 8,
|
||||
"path": "t8.fctb"
|
||||
},
|
||||
{
|
||||
"nr": 9,
|
||||
"path": "t9.fctb"
|
||||
}
|
||||
],
|
||||
"version": 1
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
BIN
src/Mod/Path/Tools/Shape/chamfer.fcstd
Normal file
BIN
src/Mod/Path/Tools/Shape/chamfer.fcstd
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/Mod/Path/Tools/Shape/probe.fcstd
Normal file
BIN
src/Mod/Path/Tools/Shape/probe.fcstd
Normal file
Binary file not shown.
BIN
src/Mod/Path/Tools/Shape/slittingsaw.fcstd
Normal file
BIN
src/Mod/Path/Tools/Shape/slittingsaw.fcstd
Normal file
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user