Added stock creation.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>608</height>
|
||||
<height>924</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -24,7 +24,7 @@
|
||||
<item>
|
||||
<widget class="QToolBox" name="tbGeneral">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page">
|
||||
<property name="geometry">
|
||||
@@ -226,67 +226,184 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>378</width>
|
||||
<height>403</height>
|
||||
<height>719</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="label">
|
||||
<string>Layout</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="stockGroup">
|
||||
<property name="title">
|
||||
<string>Stock</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="stockExtXLabel">
|
||||
<property name="text">
|
||||
<string>Ext. X</string>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QComboBox" name="stock">
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Create Box</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Create Cylinder</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Extend Base Bound Box</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use Existing</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="stockExtYLabel">
|
||||
<property name="text">
|
||||
<string>Ext. Y</string>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>6</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="stockFromExisting">
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="stockExisting"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="Gui::InputField" name="stockExtXPlus">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="stockFromBase">
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="1" column="3">
|
||||
<widget class="Gui::InputField" name="stockExtYpos"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="stockExtXLabel">
|
||||
<property name="text">
|
||||
<string>Ext. X</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="Gui::InputField" name="stockExtXpos">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="stockExtYLabel">
|
||||
<property name="text">
|
||||
<string>Ext. Y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::InputField" name="stockExtXneg"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="stockExtZLabel">
|
||||
<property name="text">
|
||||
<string>Ext. Z</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="Gui::InputField" name="stockExtZneg"/>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="Gui::InputField" name="stockExtZpos"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::InputField" name="stockExtYneg"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="Gui::InputField" name="stockExtXMinus"/>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="stockExtZLabel">
|
||||
<property name="text">
|
||||
<string>Ext. Z</string>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QFrame" name="stockCreateCylinder">
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::InputField" name="stockCylinderRadius"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::InputField" name="stockCylinderHeight"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="stockCylinderRadiusLabel">
|
||||
<property name="text">
|
||||
<string>Radius</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="stockCylinderHeightLabel">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="Gui::InputField" name="stockExtZMinus"/>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="Gui::InputField" name="stockExtYMinus"/>
|
||||
</item>
|
||||
<item row="2" column="4">
|
||||
<widget class="Gui::InputField" name="stockExtYPlus"/>
|
||||
</item>
|
||||
<item row="3" column="4">
|
||||
<widget class="Gui::InputField" name="stockExtZPlus"/>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="comboBox"/>
|
||||
<item>
|
||||
<widget class="QFrame" name="stockCreateBox">
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="stockBoxLengthLabel">
|
||||
<property name="text">
|
||||
<string>Length</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="stockBoxWidthLabel">
|
||||
<property name="text">
|
||||
<string>Width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::InputField" name="stockBoxLength"/>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="Gui::InputField" name="stockBoxHeight"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::InputField" name="stockBoxWidth"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="stockBoxHeightLabel">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
@@ -612,7 +729,7 @@
|
||||
<item>
|
||||
<widget class="QToolBox" name="toolBox_2">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_9">
|
||||
<property name="geometry">
|
||||
@@ -862,6 +979,63 @@
|
||||
<header>Gui/InputField.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>infoLabel</tabstop>
|
||||
<tabstop>infoModel</tabstop>
|
||||
<tabstop>infoMaterial</tabstop>
|
||||
<tabstop>stock</tabstop>
|
||||
<tabstop>stockExisting</tabstop>
|
||||
<tabstop>stockExtXneg</tabstop>
|
||||
<tabstop>stockExtXpos</tabstop>
|
||||
<tabstop>stockExtYneg</tabstop>
|
||||
<tabstop>stockExtYpos</tabstop>
|
||||
<tabstop>stockExtZneg</tabstop>
|
||||
<tabstop>stockExtZpos</tabstop>
|
||||
<tabstop>stockCylinderRadius</tabstop>
|
||||
<tabstop>stockCylinderHeight</tabstop>
|
||||
<tabstop>stockBoxLength</tabstop>
|
||||
<tabstop>stockBoxWidth</tabstop>
|
||||
<tabstop>stockBoxHeight</tabstop>
|
||||
<tabstop>orientXAxis</tabstop>
|
||||
<tabstop>orientYAxis</tabstop>
|
||||
<tabstop>orientZAxis</tabstop>
|
||||
<tabstop>setOrigin</tabstop>
|
||||
<tabstop>moveToOrigin</tabstop>
|
||||
<tabstop>centerInStock</tabstop>
|
||||
<tabstop>centerInStockXY</tabstop>
|
||||
<tabstop>postProcessorOutputFile</tabstop>
|
||||
<tabstop>postProcessorSetOutputFile</tabstop>
|
||||
<tabstop>postProcessor</tabstop>
|
||||
<tabstop>postProcessorArguments</tabstop>
|
||||
<tabstop>templateDefaultValues</tabstop>
|
||||
<tabstop>templatePostProcessor</tabstop>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
<tabstop>templateGeneral</tabstop>
|
||||
<tabstop>templateMaterial</tabstop>
|
||||
<tabstop>templateSetup</tabstop>
|
||||
<tabstop>templateStock</tabstop>
|
||||
<tabstop>templateOperations</tabstop>
|
||||
<tabstop>templateTools</tabstop>
|
||||
<tabstop>toolControllerList</tabstop>
|
||||
<tabstop>toolControllerEdit</tabstop>
|
||||
<tabstop>toolControllerAdd</tabstop>
|
||||
<tabstop>toolControllerDelete</tabstop>
|
||||
<tabstop>activeToolController</tabstop>
|
||||
<tabstop>operationsList</tabstop>
|
||||
<tabstop>operationEdit</tabstop>
|
||||
<tabstop>operationDelete</tabstop>
|
||||
<tabstop>groupBox_5</tabstop>
|
||||
<tabstop>defaultSafeHeight</tabstop>
|
||||
<tabstop>defaultClearanceHeight</tabstop>
|
||||
<tabstop>groupBox_6</tabstop>
|
||||
<tabstop>defaultStepDown</tabstop>
|
||||
<tabstop>groupBox</tabstop>
|
||||
<tabstop>lineEdit</tabstop>
|
||||
<tabstop>lineEdit_2</tabstop>
|
||||
<tabstop>groupBox_7</tabstop>
|
||||
<tabstop>defaultMillingOp</tabstop>
|
||||
<tabstop>defaultToolCompensation</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
||||
@@ -27,6 +27,7 @@ import Draft
|
||||
import FreeCAD
|
||||
import PathScripts.PathIconViewProvider as PathIconViewProvider
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathStock as PathStock
|
||||
import PathScripts.PathToolController as PathToolController
|
||||
import PathScripts.PathUtil as PathUtil
|
||||
import xml.etree.ElementTree as xml
|
||||
@@ -58,6 +59,24 @@ class JobTemplate:
|
||||
Description = 'desc'
|
||||
ToolController = 'ToolController'
|
||||
|
||||
def isResourceClone(obj, propName, resourceName):
|
||||
'''isResourceClone(obj, propName, resourceName) ... Return True if the given property of obj is a clone of type resourceName.'''
|
||||
if hasattr(obj, propName):
|
||||
propLink = getattr(obj, propName)
|
||||
if hasattr(propLink, 'PathResource') and resourceName == propLink.PathResource:
|
||||
return True
|
||||
return False
|
||||
|
||||
def createResourceClone(obj, orig, name, icon):
|
||||
clone = Draft.clone(orig)
|
||||
clone.Label = "%s-%s" % (name, orig.Label)
|
||||
clone.addProperty('App::PropertyString', 'PathResource')
|
||||
clone.PathResource = name
|
||||
if clone.ViewObject:
|
||||
PathIconViewProvider.ViewProvider(clone.ViewObject, icon)
|
||||
clone.ViewObject.Visibility = False
|
||||
return clone
|
||||
|
||||
class ObjectJob:
|
||||
|
||||
def __init__(self, obj, base, template = None):
|
||||
@@ -91,10 +110,14 @@ class ObjectJob:
|
||||
obj.setEditorMode('Operations', 2) # hide
|
||||
obj.setEditorMode('Placement', 2)
|
||||
|
||||
self.createResourceClone(obj, base, 'Base')
|
||||
obj.Base = createResourceClone(obj, base, 'Base', 'BaseGeometry')
|
||||
obj.Proxy = self
|
||||
|
||||
self.assignTemplate(obj, template)
|
||||
if not obj.Stock:
|
||||
obj.Stock = PathStock.CreateFromBase(obj)
|
||||
if obj.Stock.ViewObject:
|
||||
obj.Stock.ViewObject.Visibility = False
|
||||
|
||||
def onDelete(self, obj, arg2=None):
|
||||
'''Called by the view provider, there doesn't seem to be a callback on the obj itself.'''
|
||||
@@ -115,36 +138,18 @@ class ObjectJob:
|
||||
doc.removeObject(obj.Stock.Name)
|
||||
obj.Stock = None
|
||||
|
||||
def isResourceClone(self, obj, propName, resourceName):
|
||||
if hasattr(obj, propName):
|
||||
propLink = getattr(obj, propName)
|
||||
if hasattr(propLink, 'PathResource') and resourceName == propLink.PathResource:
|
||||
return True
|
||||
return False
|
||||
|
||||
def createResourceClone(self, obj, orig, name):
|
||||
clone = Draft.clone(orig)
|
||||
clone.Label = "%s-%s" % (name, orig.Label)
|
||||
clone.addProperty('App::PropertyString', 'PathResource')
|
||||
clone.PathResource = name
|
||||
if clone.ViewObject:
|
||||
PathIconViewProvider.ViewProvider(clone.ViewObject, 'BaseGeometry')
|
||||
clone.ViewObject.Visibility = False
|
||||
setattr(obj, name, clone)
|
||||
|
||||
def fixupResourceClone(self, obj, name):
|
||||
if not self.isResourceClone(obj, name, name):
|
||||
def fixupResourceClone(self, obj, name, icon):
|
||||
if not isResourceClone(obj, name, name):
|
||||
orig = getattr(obj, name)
|
||||
if orig:
|
||||
self.createResourceClone(obj, orig, name)
|
||||
setattr(obj, name, createResourceClone(obj, orig, name, icon))
|
||||
|
||||
def onDocumentRestored(self, obj):
|
||||
self.fixupResourceClone(obj, 'Base')
|
||||
self.fixupResourceClone(obj, 'Stock')
|
||||
self.fixupResourceClone(obj, 'Base', 'BaseGeometry')
|
||||
|
||||
def baseObject(self, obj):
|
||||
'''Return the base object, not its clone.'''
|
||||
if self.isResourceClone(obj, 'Base', 'Base'):
|
||||
if isResourceClone(obj, 'Base', 'Base'):
|
||||
return obj.Base.Objects[0]
|
||||
return obj.Base
|
||||
|
||||
|
||||
@@ -28,8 +28,10 @@ import FreeCAD
|
||||
import FreeCADGui
|
||||
import PathScripts.PathJob as PathJob
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathStock as PathStock
|
||||
import PathScripts.PathToolController as PathToolController
|
||||
import PathScripts.PathToolLibraryManager as PathToolLibraryManager
|
||||
import PathScripts.PathUtil as PathUtil
|
||||
import math
|
||||
import sys
|
||||
|
||||
@@ -104,6 +106,223 @@ class ViewProvider:
|
||||
self.obj.Proxy.onDelete(self.obj, arg2)
|
||||
return True
|
||||
|
||||
class StockEdit(object):
|
||||
|
||||
def __init__(self, obj, form):
|
||||
self.obj = obj
|
||||
self.form = form
|
||||
self.setupUi(obj)
|
||||
|
||||
def activate(self, obj, select = False):
|
||||
PathLog.track(obj.Label, select)
|
||||
def showHide(widget, activeWidget):
|
||||
if widget == activeWidget:
|
||||
widget.show()
|
||||
else:
|
||||
widget.hide()
|
||||
if select:
|
||||
self.form.stock.setCurrentIndex(self.Index)
|
||||
editor = self.editorFrame()
|
||||
showHide(self.form.stockFromExisting, editor)
|
||||
showHide(self.form.stockFromBase, editor)
|
||||
showHide(self.form.stockCreateBox, editor)
|
||||
showHide(self.form.stockCreateCylinder, editor)
|
||||
self.setFields(obj)
|
||||
|
||||
def setStock(self, obj, stock):
|
||||
if obj.Stock:
|
||||
obj.Document.removeObject(self.obj.Stock.Name)
|
||||
obj.Stock = stock
|
||||
|
||||
def setLengthField(self, widget, prop):
|
||||
widget.setText(FreeCAD.Units.Quantity(prop.Value, FreeCAD.Units.Length).UserString)
|
||||
|
||||
class StockFromBaseBoundBoxEdit(StockEdit):
|
||||
Index = 2
|
||||
StockType = 'FromBase'
|
||||
|
||||
@classmethod
|
||||
def IsStock(cls, obj):
|
||||
return hasattr(obj.Stock, 'ExtXneg') and hasattr(obj.Stock, 'ExtZpos')
|
||||
|
||||
def editorFrame(self):
|
||||
return self.form.stockFromBase
|
||||
|
||||
def getFields(self, obj, fields = ['xneg', 'xpos', 'yneg', 'ypos', 'zneg', 'zpos']):
|
||||
PathLog.track(obj.Label, fields)
|
||||
if self.IsStock(obj):
|
||||
if 'xneg' in fields:
|
||||
obj.Stock.ExtXneg = FreeCAD.Units.Quantity(self.form.stockExtXneg.text())
|
||||
if 'xpos' in fields:
|
||||
obj.Stock.ExtXpos = FreeCAD.Units.Quantity(self.form.stockExtXpos.text())
|
||||
if 'yneg' in fields:
|
||||
obj.Stock.ExtYneg = FreeCAD.Units.Quantity(self.form.stockExtYneg.text())
|
||||
if 'ypos' in fields:
|
||||
obj.Stock.ExtYpos = FreeCAD.Units.Quantity(self.form.stockExtYpos.text())
|
||||
if 'zneg' in fields:
|
||||
obj.Stock.ExtZneg = FreeCAD.Units.Quantity(self.form.stockExtZneg.text())
|
||||
if 'zpos' in fields:
|
||||
obj.Stock.ExtZpos = FreeCAD.Units.Quantity(self.form.stockExtZpos.text())
|
||||
else:
|
||||
PathLog.error(translate('PathJob', 'Stock not from Base bound box!'))
|
||||
|
||||
def setFields(self, obj):
|
||||
if not self.IsStock(obj):
|
||||
self.setStock(obj, PathStock.CreateFromBase(obj))
|
||||
self.setLengthField(self.form.stockExtXneg, obj.Stock.ExtXneg)
|
||||
self.setLengthField(self.form.stockExtXpos, obj.Stock.ExtXpos)
|
||||
self.setLengthField(self.form.stockExtYneg, obj.Stock.ExtYneg)
|
||||
self.setLengthField(self.form.stockExtYpos, obj.Stock.ExtYpos)
|
||||
self.setLengthField(self.form.stockExtZneg, obj.Stock.ExtZneg)
|
||||
self.setLengthField(self.form.stockExtZpos, obj.Stock.ExtZpos)
|
||||
|
||||
def setupUi(self, obj):
|
||||
self.setFields(obj)
|
||||
self.checkXpos()
|
||||
self.checkYpos()
|
||||
self.checkZpos()
|
||||
self.form.stockExtXneg.editingFinished.connect(self.updateXpos)
|
||||
self.form.stockExtYneg.editingFinished.connect(self.updateYpos)
|
||||
self.form.stockExtZneg.editingFinished.connect(self.updateZpos)
|
||||
self.form.stockExtXpos.editingFinished.connect(self.checkXpos)
|
||||
self.form.stockExtYpos.editingFinished.connect(self.checkYpos)
|
||||
self.form.stockExtZpos.editingFinished.connect(self.checkZpos)
|
||||
|
||||
def checkXpos(self):
|
||||
self.trackXpos = self.form.stockExtXneg.text() == self.form.stockExtXpos.text()
|
||||
self.getFields(self.obj, ['xpos'])
|
||||
def checkYpos(self):
|
||||
self.trackYpos = self.form.stockExtYneg.text() == self.form.stockExtYpos.text()
|
||||
self.getFields(self.obj, ['ypos'])
|
||||
def checkZpos(self):
|
||||
self.trackZpos = self.form.stockExtZneg.text() == self.form.stockExtZpos.text()
|
||||
self.getFields(self.obj, ['zpos'])
|
||||
|
||||
def updateXpos(self):
|
||||
fields = ['xneg']
|
||||
if self.trackXpos:
|
||||
self.form.stockExtXpos.setText(self.form.stockExtXneg.text())
|
||||
fields.append('xpos')
|
||||
self.getFields(self.obj, fields)
|
||||
def updateYpos(self):
|
||||
fields = ['yneg']
|
||||
if self.trackYpos:
|
||||
self.form.stockExtYpos.setText(self.form.stockExtYneg.text())
|
||||
fields.append('ypos')
|
||||
self.getFields(self.obj, fields)
|
||||
def updateZpos(self):
|
||||
fields = ['zneg']
|
||||
if self.trackZpos:
|
||||
self.form.stockExtZpos.setText(self.form.stockExtZneg.text())
|
||||
fields.append('zpos')
|
||||
self.getFields(self.obj, fields)
|
||||
|
||||
class StockCreateBoxEdit(StockEdit):
|
||||
Index = 0
|
||||
StockType = 'CreateBox'
|
||||
|
||||
@classmethod
|
||||
def IsStock(cls, obj):
|
||||
return hasattr(obj.Stock, 'Length') and hasattr(obj.Stock, 'Width') and hasattr(obj.Stock, 'Height') and not StockFromBaseBoundBoxEdit.IsStock(obj)
|
||||
|
||||
def editorFrame(self):
|
||||
return self.form.stockCreateBox
|
||||
|
||||
def getFields(self, obj, fields = ['length', 'widht', 'height']):
|
||||
if self.IsStock(obj):
|
||||
if 'length' in fields:
|
||||
obj.Stock.Length = FreeCAD.Units.Quantity(self.form.stockBoxLength.text())
|
||||
if 'width' in fields:
|
||||
obj.Stock.Width = FreeCAD.Units.Quantity(self.form.stockBoxWidth.text())
|
||||
if 'height' in fields:
|
||||
obj.Stock.Height = FreeCAD.Units.Quantity(self.form.stockBoxHeight.text())
|
||||
else:
|
||||
PathLog.error(translate('PathJob', 'Stock not a box!'))
|
||||
|
||||
def setFields(self, obj):
|
||||
if not self.IsStock(obj):
|
||||
self.setStock(obj, PathStock.CreateBox(obj))
|
||||
self.setLengthField(self.form.stockBoxLength, obj.Stock.Length)
|
||||
self.setLengthField(self.form.stockBoxWidth, obj.Stock.Width)
|
||||
self.setLengthField(self.form.stockBoxHeight, obj.Stock.Height)
|
||||
|
||||
def setupUi(self, obj):
|
||||
self.setFields(obj)
|
||||
self.form.stockBoxLength.editingFinished.connect(lambda: self.getFields(obj, ['length']))
|
||||
self.form.stockBoxWidth.editingFinished.connect(lambda: self.getFields(obj, ['width']))
|
||||
self.form.stockBoxHeight.editingFinished.connect(lambda: self.getFields(obj, ['height']))
|
||||
|
||||
class StockCreateCylinderEdit(StockEdit):
|
||||
Index = 1
|
||||
|
||||
@classmethod
|
||||
def IsStock(cls, obj):
|
||||
return hasattr(obj.Stock, 'Radius') and hasattr(obj.Stock, 'Height')
|
||||
|
||||
def editorFrame(self):
|
||||
return self.form.stockCreateCylinder
|
||||
|
||||
def getFields(self, obj, fields = ['radius', 'height']):
|
||||
if self.IsStock(obj):
|
||||
if 'radius' in fields:
|
||||
obj.Stock.Radius = FreeCAD.Units.Quantity(self.form.stockCylinderRadius.text())
|
||||
if 'height' in fields:
|
||||
obj.Stock.Height = FreeCAD.Units.Quantity(self.form.stockCylinderHeight.text())
|
||||
else:
|
||||
PathLog.error(translate('PathJob', 'Stock not a cylinder!'))
|
||||
|
||||
def setFields(self, obj):
|
||||
if not self.IsStock(obj):
|
||||
self.setStock(obj, PathStock.CreateCylinder(obj))
|
||||
self.setLengthField(self.form.stockCylinderRadius, obj.Stock.Radius)
|
||||
self.setLengthField(self.form.stockCylinderHeight, obj.Stock.Height)
|
||||
|
||||
def setupUi(self, obj):
|
||||
self.setFields(obj)
|
||||
self.form.stockCylinderRadius.editingFinished.connect(lambda: self.getFields(obj, ['radius']))
|
||||
self.form.stockCylinderHeight.editingFinished.connect(lambda: self.getFields(obj, ['height']))
|
||||
|
||||
class StockFromExistingEdit(StockEdit):
|
||||
Index = 3
|
||||
|
||||
def IsStock(cls, obj):
|
||||
return PathJob.isResourceClone(obj, 'Stock', 'Stock')
|
||||
|
||||
def editorFrame(self):
|
||||
return self.form.stockFromExisting
|
||||
|
||||
def getFields(self, obj):
|
||||
stock = self.form.stockExisting.itemData(self.form.stockExisting.currentIndex())
|
||||
if not (hasattr(obj.Stock, 'Objects') and len(obj.Stock.Objects) == 1 and obj.Stock.Objects[0] == stock):
|
||||
if stock:
|
||||
stock = PathJob.createResourceClone(obj, stock, 'Stock', 'Stock')
|
||||
stock.ViewObject.Visibility = True
|
||||
PathStock.SetupStockObject(stock, False)
|
||||
stock.Proxy.execute(stock)
|
||||
self.setStock(obj, stock)
|
||||
|
||||
def setFields(self, obj):
|
||||
candidates = [o for o in obj.Document.Objects if PathUtil.isSolid(o)]
|
||||
candidates.remove(obj.Base)
|
||||
if PathJob.isResourceClone(obj, 'Stock', 'Stock'):
|
||||
candidates.remove(obj.Stock)
|
||||
stockName = obj.Stock.Label if obj.Stock else None
|
||||
|
||||
self.form.stockExisting.clear()
|
||||
index = -1
|
||||
for i, c in enumerate(candidates):
|
||||
self.form.stockExisting.addItem(c.Label, c)
|
||||
if c.Label == stockName:
|
||||
index = i
|
||||
self.form.stockExisting.setCurrentIndex(index if index != -1 else 0)
|
||||
|
||||
if not self.IsStock(obj):
|
||||
self.getFields(obj)
|
||||
|
||||
def setupUi(self, obj):
|
||||
self.setFields(obj)
|
||||
self.form.stockExisting.currentIndexChanged.connect(lambda: self.getFields(obj))
|
||||
|
||||
class TaskPanel:
|
||||
DataObject = QtCore.Qt.ItemDataRole.UserRole
|
||||
DataProperty = QtCore.Qt.ItemDataRole.UserRole + 1
|
||||
@@ -144,6 +363,17 @@ class TaskPanel:
|
||||
self.baseVisibility = self.obj.Base.ViewObject.Visibility
|
||||
self.baseObjectSaveVisibility(self.obj)
|
||||
|
||||
self.stockVisibility = False
|
||||
if self.obj.Stock and self.obj.Stock.ViewObject:
|
||||
self.stockVisibility = self.obj.Stock.ViewObject.Visibility
|
||||
self.obj.Stock.ViewObject.Visibility = True
|
||||
|
||||
self.stockFromBase = None
|
||||
self.stockFromExisting = None
|
||||
self.stockCreateBox = None
|
||||
self.stockCreateCylinder = None
|
||||
self.stockEdit = None
|
||||
|
||||
def baseObjectViewObject(self, obj):
|
||||
base = obj.Proxy.baseObject(obj)
|
||||
body = base.getParentGeoFeatureGroup()
|
||||
@@ -165,6 +395,8 @@ class TaskPanel:
|
||||
if self.obj.Base and self.obj.Base.ViewObject:
|
||||
self.obj.Base.ViewObject.Visibility = self.baseVisibility
|
||||
self.baseObjectRestoreVisibility(self.obj)
|
||||
if self.obj.Stock and self.obj.Stock.ViewObject:
|
||||
self.obj.Stock.ViewObject.Visibility = self.stockVisibility
|
||||
|
||||
def accept(self, resetEdit=True):
|
||||
PathLog.track()
|
||||
@@ -222,8 +454,8 @@ class TaskPanel:
|
||||
self.baseObjectSaveVisibility(self.obj)
|
||||
|
||||
self.updateTooltips()
|
||||
|
||||
self.obj.Proxy.execute(self.obj)
|
||||
self.stockEdit.getFields(self.obj)
|
||||
self.obj.Proxy.execute(self.obj)
|
||||
|
||||
def selectComboBoxText(self, widget, text):
|
||||
index = widget.findText(text, QtCore.Qt.MatchFixedString)
|
||||
@@ -316,6 +548,8 @@ class TaskPanel:
|
||||
self.form.infoModel.setCurrentIndex(baseindex)
|
||||
|
||||
self.updateToolController()
|
||||
self.stockEdit.setFields(self.obj)
|
||||
|
||||
|
||||
def setPostProcessorOutputFile(self):
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self.form, translate("Path_Job", "Select Output File"), None, translate("Path_Job", "All Files (*.*)"))
|
||||
@@ -501,7 +735,58 @@ class TaskPanel:
|
||||
self.form.orientGroup.setEnabled(False)
|
||||
self.form.alignGroup.setEnabled(False)
|
||||
|
||||
def updateStockEditor(self, index):
|
||||
PathLog.track(self.obj.Label, index)
|
||||
def setupFromBaseEdit():
|
||||
PathLog.track()
|
||||
if not self.stockFromBase:
|
||||
self.stockFromBase = StockFromBaseBoundBoxEdit(self.obj, self.form)
|
||||
self.stockEdit = self.stockFromBase
|
||||
def setupCreateBoxEdit():
|
||||
PathLog.track()
|
||||
if not self.stockCreateBox:
|
||||
self.stockCreateBox = StockCreateBoxEdit(self.obj, self.form)
|
||||
self.stockEdit = self.stockCreateBox
|
||||
def setupCreateCylinderEdit():
|
||||
PathLog.track()
|
||||
if not self.stockCreateCylinder:
|
||||
self.stockCreateCylinder = StockCreateCylinderEdit(self.obj, self.form)
|
||||
self.stockEdit = self.stockCreateCylinder
|
||||
def setupFromExisting():
|
||||
PathLog.track()
|
||||
if not self.stockFromExisting:
|
||||
self.stockFromExisting = StockFromExistingEdit(self.obj, self.form)
|
||||
self.stockEdit = self.stockFromExisting
|
||||
|
||||
if index == -1:
|
||||
PathLog.track('wtf')
|
||||
if self.obj.Stock is None or StockFromBaseBoundBoxEdit.IsStock(self.obj):
|
||||
setupFromBaseEdit()
|
||||
elif StockCreateBoxEdit.IsStock(self.obj):
|
||||
setupCreateBoxEdit()
|
||||
elif StockCreateCylinderEdit.IsStock(self.obj):
|
||||
setupCreateCylinderEdit()
|
||||
elif StockFromExistingEdit.IsStock(self.obj):
|
||||
setupFromExisting()
|
||||
else:
|
||||
PathLog.error(translate('PathJob', "Unsupported stock object %s") % self.obj.Stock.Label)
|
||||
else:
|
||||
PathLog.track(self.obj.Label, index)
|
||||
if index == StockFromBaseBoundBoxEdit.Index:
|
||||
setupFromBaseEdit()
|
||||
elif index == StockCreateBoxEdit.Index:
|
||||
setupCreateBoxEdit()
|
||||
elif index == StockCreateCylinderEdit.Index:
|
||||
setupCreateCylinderEdit()
|
||||
elif index == StockFromExistingEdit.Index:
|
||||
setupFromExisting()
|
||||
else:
|
||||
PathLog.error(translate('PathJob', "Unsupported stock type %s (%d)") % (self.form.stock.currentText(), index))
|
||||
self.stockEdit.activate(self.obj, index == -1)
|
||||
|
||||
|
||||
def setupUi(self):
|
||||
self.updateStockEditor(-1)
|
||||
self.setFields()
|
||||
|
||||
# Info
|
||||
@@ -528,10 +813,11 @@ class TaskPanel:
|
||||
self.toolControllerSelect()
|
||||
|
||||
# Stock, Orientation and Alignment
|
||||
self.form.stockGroup.hide()
|
||||
self.form.centerInStock.hide()
|
||||
self.form.centerInStockXY.hide()
|
||||
|
||||
self.form.stock.currentIndexChanged.connect(self.updateStockEditor)
|
||||
|
||||
self.form.orientXAxis.clicked.connect(lambda: self.orientSelected(FreeCAD.Vector(1, 0, 0)))
|
||||
self.form.orientYAxis.clicked.connect(lambda: self.orientSelected(FreeCAD.Vector(0, 1, 0)))
|
||||
self.form.orientZAxis.clicked.connect(lambda: self.orientSelected(FreeCAD.Vector(0, 0, 1)))
|
||||
|
||||
@@ -24,23 +24,36 @@
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from FreeCAD import Vector
|
||||
from PySide import QtCore, QtGui
|
||||
import Part
|
||||
import PathIconViewProvider
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
# Qt tanslation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
|
||||
class Stock:
|
||||
class StockFromBase:
|
||||
|
||||
def __init__(self, obj):
|
||||
def __init__(self, obj, base):
|
||||
"Make stock"
|
||||
obj.addProperty("App::PropertyFloat","Length_Allowance","Stock",QtCore.QT_TRANSLATE_NOOP("App::Property","extra allowance from part width")).Length_Allowance = 1.0
|
||||
obj.addProperty("App::PropertyFloat","Width_Allowance","Stock",QtCore.QT_TRANSLATE_NOOP("App::Property","extra allowance from part width")).Width_Allowance = 1.0
|
||||
obj.addProperty("App::PropertyFloat","Height_Allowance","Stock",QtCore.QT_TRANSLATE_NOOP("App::Property","extra allowance from part width")).Height_Allowance = 1.0
|
||||
obj.addProperty("App::PropertyLink","Base","Base",QtCore.QT_TRANSLATE_NOOP("App::Property","The base object this represents"))
|
||||
obj.addProperty("App::PropertyLink", "Base", "Base", QtCore.QT_TRANSLATE_NOOP("PathStock", "The base object this stock is derived from"))
|
||||
obj.addProperty("App::PropertyLength", "ExtXneg", "Stock", QtCore.QT_TRANSLATE_NOOP("PathStock", "Extra allowance from part bound box in negative X direction"))
|
||||
obj.addProperty("App::PropertyLength", "ExtXpos", "Stock", QtCore.QT_TRANSLATE_NOOP("PathStock", "Extra allowance from part bound box in positive X direction"))
|
||||
obj.addProperty("App::PropertyLength", "ExtYneg", "Stock", QtCore.QT_TRANSLATE_NOOP("PathStock", "Extra allowance from part bound box in negative Y direction"))
|
||||
obj.addProperty("App::PropertyLength", "ExtYpos", "Stock", QtCore.QT_TRANSLATE_NOOP("PathStock", "Extra allowance from part bound box in positive Y direction"))
|
||||
obj.addProperty("App::PropertyLength", "ExtZneg", "Stock", QtCore.QT_TRANSLATE_NOOP("PathStock", "Extra allowance from part bound box in negative Z direction"))
|
||||
obj.addProperty("App::PropertyLength", "ExtZpos", "Stock", QtCore.QT_TRANSLATE_NOOP("PathStock", "Extra allowance from part bound box in positive Z direction"))
|
||||
|
||||
obj.Base = base
|
||||
obj.ExtXneg= 1.0
|
||||
obj.ExtXpos= 1.0
|
||||
obj.ExtYneg= 1.0
|
||||
obj.ExtYpos= 1.0
|
||||
obj.ExtZneg= 1.0
|
||||
obj.ExtZpos= 1.0
|
||||
|
||||
obj.Proxy = self
|
||||
|
||||
def __getstate__(self):
|
||||
@@ -50,23 +63,70 @@ class Stock:
|
||||
return None
|
||||
|
||||
def execute(self, obj):
|
||||
self.Xmin = obj.Base.Shape.BoundBox.XMin
|
||||
self.Xmax = obj.Base.Shape.BoundBox.XMax
|
||||
bb = obj.Base.Shape.BoundBox
|
||||
|
||||
self.Ymin = obj.Base.Shape.BoundBox.YMin
|
||||
self.Ymax = obj.Base.Shape.BoundBox.YMax
|
||||
origin = FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin)
|
||||
self.origin = origin - FreeCAD.Vector(obj.ExtXneg.Value, obj.ExtYneg.Value, obj.ExtZneg.Value)
|
||||
|
||||
self.Zmin = obj.Base.Shape.BoundBox.ZMin
|
||||
self.Zmax = obj.Base.Shape.BoundBox.ZMax
|
||||
self.length = bb.XLength + obj.ExtXneg.Value + obj.ExtXpos.Value
|
||||
self.width = bb.YLength + obj.ExtYneg.Value + obj.ExtYpos.Value
|
||||
self.height = bb.ZLength + obj.ExtZneg.Value + obj.ExtZpos.Value
|
||||
|
||||
self.length = self.Xmax - self.Xmin + obj.Length_Allowance * 2.0
|
||||
self.width = self.Ymax - self.Ymin + obj.Width_Allowance * 2.0
|
||||
self.height = self.Zmax - self.Zmin + obj.Height_Allowance * 2.0
|
||||
self.pnt = Vector(self.Xmin - obj.Length_Allowance, self.Ymin -
|
||||
obj.Width_Allowance, self.Zmin - obj.Height_Allowance)
|
||||
obj.Shape = Part.makeBox(self.length, self.width, self.height, self.origin)
|
||||
|
||||
obj.Shape = Part.makeBox(
|
||||
self.length, self.width, self.height, self.pnt)
|
||||
def SetupStockObject(obj, addVPProxy):
|
||||
if FreeCAD.GuiUp and obj.ViewObject:
|
||||
if addVPProxy:
|
||||
PathIconViewProvider.ViewProvider(obj.ViewObject, 'Stock')
|
||||
obj.ViewObject.Transparency = 90
|
||||
obj.ViewObject.DisplayMode = 'Wireframe'
|
||||
|
||||
def CreateFromBase(job):
|
||||
obj = FreeCAD.ActiveDocument.addObject('Part::FeaturePython', 'Stock')
|
||||
proxy = StockFromBase(obj, job.Base)
|
||||
SetupStockObject(obj, True)
|
||||
proxy.execute(obj)
|
||||
obj.purgeTouched()
|
||||
return obj
|
||||
|
||||
def CreateBox(job, extent=None, at=None):
|
||||
obj = FreeCAD.ActiveDocument.addObject('Part::Box', 'Stock')
|
||||
if extent:
|
||||
obj.Length = extent.x
|
||||
obj.Width = extent.y
|
||||
obj.Height = extent.z
|
||||
elif job.Base:
|
||||
bb = job.Base.Shape.BoundBox
|
||||
obj.Length = bb.XLength
|
||||
obj.Width = bb.YLength
|
||||
obj.Height = bb.ZLength
|
||||
if at:
|
||||
obj.Placement = FreeCAD.Placement(at, FreeCAD.Vector(), 0)
|
||||
else:
|
||||
bb = job.Base.Shape.BoundBox
|
||||
origin = FreeCAD.Vector(bb.XMin, bb.YMin, bb.ZMin)
|
||||
obj.Placement = FreeCAD.Placement(origin, FreeCAD.Vector(), 0)
|
||||
SetupStockObject(obj, False)
|
||||
return obj
|
||||
|
||||
def CreateCylinder(job, radius=None, height=None, at=None):
|
||||
obj = FreeCAD.ActiveDocument.addObject('Part::Cylinder', 'Stock')
|
||||
if radius:
|
||||
obj.Radius = radius
|
||||
if height:
|
||||
obj.Height = height
|
||||
elif job.Base:
|
||||
bb = job.Base.Shape.BoundBox
|
||||
obj.Radius = max(bb.XLength, bb.YLength) * 0.7072 # 1/sqrt(2)
|
||||
obj.Height = bb.ZLength
|
||||
if at:
|
||||
obj.Placement = FreeCAD.Placement(at, FreeCAD.Vector(), 0)
|
||||
else:
|
||||
bb = job.Base.Shape.BoundBox
|
||||
origin = FreeCAD.Vector((bb.XMin + bb.XMax)/2, (bb.YMin + bb.YMax)/2, bb.ZMin)
|
||||
obj.Placement = FreeCAD.Placement(origin, FreeCAD.Vector(), 0)
|
||||
SetupStockObject(obj, False)
|
||||
return obj
|
||||
|
||||
|
||||
class _ViewProviderStock:
|
||||
|
||||
@@ -37,9 +37,9 @@ import PathScripts.PathLog as PathLog
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
|
||||
NotValidBaseTypeIds = ['Sketcher::SketchObject']
|
||||
def isValidBaseObject(obj):
|
||||
'''isSolid(obj) ... returns true if an object represents a solid.'''
|
||||
|
||||
def isValidBaseObject(obj):
|
||||
'''isValidBaseObject(obj) ... returns true if the object can be used as a base for a job.'''
|
||||
if not hasattr(obj, 'Shape'):
|
||||
return False
|
||||
if obj.TypeId in NotValidBaseTypeIds:
|
||||
@@ -48,9 +48,23 @@ def isValidBaseObject(obj):
|
||||
return False
|
||||
return True
|
||||
|
||||
def isSolid(obj):
|
||||
'''isSolid(obj) ... return True if the object is a valid solid.'''
|
||||
if hasattr(obj, 'Tip'):
|
||||
return isSolid(obj.Tip)
|
||||
if hasattr(obj, 'Shape'):
|
||||
if obj.Shape.ShapeType == 'Solid' and obj.Shape.isClosed():
|
||||
return True
|
||||
if obj.Shape.ShapeType == 'Compound':
|
||||
if hasattr(obj, 'Base') and hasattr(obj, 'Tool'):
|
||||
return isSolid(obj.Base) and isSolid(obj.Tool)
|
||||
return False
|
||||
|
||||
def toolControllerForOp(op):
|
||||
if hasattr(op, 'ToolController'):
|
||||
return op.ToolController
|
||||
if hasattr(op, 'Base'):
|
||||
return toolControllerForOp(op.Base)
|
||||
return None
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user