PathSurface now uses base object from job.

This means Surface won't work on Meshes directly.
They should be converted so FreeCAD solids first.
Surface still needs lots of work.
This commit is contained in:
sliptonic 2016-09-19 15:27:54 -05:00 committed by Yorik van Havre
parent df38242063
commit 8d0af8fcbf
8 changed files with 445 additions and 52 deletions

View File

@ -14,6 +14,7 @@ INSTALL(
) )
SET(PathScripts_SRCS SET(PathScripts_SRCS
PathCommands.py
PathScripts/__init__.py PathScripts/__init__.py
PathScripts/PostUtils.py PathScripts/PostUtils.py
PathScripts/example_pre.py PathScripts/example_pre.py
@ -27,6 +28,7 @@ SET(PathScripts_SRCS
PathScripts/rml_post.py PathScripts/rml_post.py
PathScripts/TooltableEditor.py PathScripts/TooltableEditor.py
PathScripts/PathProfile.py PathScripts/PathProfile.py
PathScripts/PathProfileEdges.py
PathScripts/PathContour.py PathScripts/PathContour.py
PathScripts/PathPocket.py PathScripts/PathPocket.py
PathScripts/PathDrilling.py PathScripts/PathDrilling.py

View File

@ -5,7 +5,7 @@
<file>icons/Path-Compound.svg</file> <file>icons/Path-Compound.svg</file>
<file>icons/Path-Shape.svg</file> <file>icons/Path-Shape.svg</file>
<file>icons/Path-Profile.svg</file> <file>icons/Path-Profile.svg</file>
<file>icons/Path-Contour.svg</file> <file>icons/Path-Contour.svg</file>
<file>icons/Path-Pocket.svg</file> <file>icons/Path-Pocket.svg</file>
<file>icons/Path-Drilling.svg</file> <file>icons/Path-Drilling.svg</file>
<file>icons/Path-Job.svg</file> <file>icons/Path-Job.svg</file>
@ -80,5 +80,7 @@
<file>panels/DlgToolCopy.ui</file> <file>panels/DlgToolCopy.ui</file>
<file>panels/ToolEdit.ui</file> <file>panels/ToolEdit.ui</file>
<file>panels/DlgJobChooser.ui</file> <file>panels/DlgJobChooser.ui</file>
<file>panels/ContourEdit.ui</file>
<file>panels/ProfileEdgesEdit.ui</file>
</qresource> </qresource>
</RCC> </RCC>

View File

@ -0,0 +1,365 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskPanel</class>
<widget class="QWidget" name="TaskPanel">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>352</width>
<height>455</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>400</height>
</size>
</property>
<property name="windowTitle">
<string>Contour</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QToolBox" name="toolBox">
<property name="currentIndex">
<number>4</number>
</property>
<widget class="QWidget" name="Geometry">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
</rect>
</property>
<property name="toolTip">
<string>Contour works on shape outer loop but maybe could work on something else</string>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<normaloff>:/icons/Path-BaseGeometry.svg</normaloff>:/icons/Path-BaseGeometry.svg</iconset>
</attribute>
<attribute name="label">
<string>Base Geometry</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2"/>
</widget>
<widget class="QWidget" name="Depths">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<normaloff>:/icons/Path-Depths.svg</normaloff>:/icons/Path-Depths.svg</iconset>
</attribute>
<attribute name="label">
<string>Depths</string>
</attribute>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="Gui::InputField" name="startDepth">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Start Depth</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::InputField" name="finalDepth">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Final Depth</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QDoubleSpinBox" name="stepDown">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Step Down</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="Heights">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<normaloff>:/icons/Path-Heights.svg</normaloff>:/icons/Path-Heights.svg</iconset>
</attribute>
<attribute name="label">
<string>Heights</string>
</attribute>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0">
<widget class="Gui::InputField" name="safeHeight">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Safe Height</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="Gui::InputField" name="clearanceHeight">
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Clearance Height</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="Holding">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
</rect>
</property>
<attribute name="label">
<string>Holding</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="0">
<widget class="QPushButton" name="addTag">
<property name="text">
<string>Add New</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="deleteTag">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item row="0" column="0" rowspan="2" colspan="2">
<widget class="QTreeWidget" name="tagTree">
<column>
<property name="text">
<string>Tag</string>
</property>
</column>
<column>
<property name="text">
<string>Location</string>
</property>
</column>
<column>
<property name="text">
<string>Height</string>
</property>
</column>
<column>
<property name="text">
<string>Length</string>
</property>
</column>
<column>
<property name="text">
<string>Angle</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>288</height>
</rect>
</property>
<attribute name="icon">
<iconset resource="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc">
<normaloff>:/icons/Path-OperationB.svg</normaloff>:/icons/Path-OperationB.svg</iconset>
</attribute>
<attribute name="label">
<string>Operation</string>
</attribute>
<layout class="QFormLayout" name="formLayout_2">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="1">
<widget class="QWidget" name="widget_3" native="true">
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Direction</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="direction">
<item>
<property name="text">
<string>CW</string>
</property>
</item>
<item>
<property name="text">
<string>CCW</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QWidget" name="widget_2" native="true">
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QCheckBox" name="useStartPoint">
<property name="text">
<string>Use Start Point</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="useCompensation">
<property name="text">
<string>Use Compensation</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="useEndPoint">
<property name="text">
<string>Use End Point</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="3" column="1">
<widget class="QWidget" name="widget_4" native="true">
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Extra Offset</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="extraOffset"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>Segment Length</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="segLen"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Roll Radius</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="rollRadius"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_13">
<property name="text">
<string>Plunge Angle</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="plungeAngle"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::InputField</class>
<extends>QLineEdit</extends>
<header>Gui/InputField.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc"/>
<include location="../../../FreeCAD/src/Mod/Path/Gui/Resources/Path.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -248,7 +248,10 @@ class ObjectContour:
edgelist = contourwire.Edges edgelist = contourwire.Edges
edgelist = Part.__sortEdges__(edgelist) edgelist = Part.__sortEdges__(edgelist)
output += self._buildPathLibarea(obj, edgelist) try:
output += self._buildPathLibarea(obj, edgelist)
except:
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
if obj.Active: if obj.Active:
path = Path.Path(output) path = Path.Path(output)
obj.Path = path obj.Path = path
@ -408,22 +411,24 @@ class CommandPathContour:
class TaskPanel: class TaskPanel:
def __init__(self): def __init__(self):
#self.form = FreeCADGui.PySideUic.loadUi(":/panels/ContourEdit.ui") self.form = FreeCADGui.PySideUic.loadUi(":/panels/ContourEdit.ui")
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ContourEdit.ui") #self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ContourEdit.ui")
self.updating = False self.updating = False
def accept(self): def accept(self):
print "removed"
self.getFields() self.getFields()
FreeCADGui.ActiveDocument.resetEdit() FreeCADGui.ActiveDocument.resetEdit()
FreeCADGui.Control.closeDialog() FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
FreeCADGui.Selection.removeObserver(self.s) FreeCADGui.Selection.removeObserver(self.s)
FreeCAD.ActiveDocument.recompute()
def reject(self): def reject(self):
print "removed1"
FreeCADGui.Control.closeDialog() FreeCADGui.Control.closeDialog()
FreeCAD.ActiveDocument.recompute()
FreeCADGui.Selection.removeObserver(self.s) FreeCADGui.Selection.removeObserver(self.s)
FreeCAD.ActiveDocument.recompute()
def getFields(self): def getFields(self):
if self.obj: if self.obj:

View File

@ -226,8 +226,8 @@ tl.ToolNumber = 1
class TaskPanel: class TaskPanel:
def __init__(self): def __init__(self):
#self.form = FreeCADGui.PySideUic.loadUi(":/panels/JobEdit.ui") self.form = FreeCADGui.PySideUic.loadUi(":/panels/JobEdit.ui")
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/JobEdit.ui") #self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/JobEdit.ui")
path = FreeCAD.getHomePath() + ("Mod/Path/PathScripts/") path = FreeCAD.getHomePath() + ("Mod/Path/PathScripts/")
posts = glob.glob(path + '/*_post.py') posts = glob.glob(path + '/*_post.py')
allposts = [ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in posts] allposts = [ str(os.path.split(os.path.splitext(p)[0])[1][:-5]) for p in posts]
@ -259,6 +259,7 @@ class TaskPanel:
FreeCAD.ActiveDocument.recompute() FreeCAD.ActiveDocument.recompute()
def getFields(self): def getFields(self):
'''sets properties in the object to match the form'''
if self.obj: if self.obj:
if hasattr(self.obj, "PostProcessor"): if hasattr(self.obj, "PostProcessor"):
self.obj.PostProcessor = str(self.form.cboPostProcessor.currentText()) self.obj.PostProcessor = str(self.form.cboPostProcessor.currentText())
@ -283,26 +284,31 @@ class TaskPanel:
selObj = Draft.clone(selObj) selObj = Draft.clone(selObj)
self.obj.Base = selObj self.obj.Base = selObj
self.obj.Proxy.execute(self.obj) self.obj.Proxy.execute(self.obj)
def setFields(self): def setFields(self):
'''sets fields in the form to match the object'''
self.form.leLabel.setText(self.obj.Label) self.form.leLabel.setText(self.obj.Label)
self.form.leOutputFile.setText(self.obj.OutputFile) self.form.leOutputFile.setText(self.obj.OutputFile)
index = self.form.cboPostProcessor.findText( postindex = self.form.cboPostProcessor.findText(
self.obj.PostProcessor, QtCore.Qt.MatchFixedString) self.obj.PostProcessor, QtCore.Qt.MatchFixedString)
if index >= 0: if postindex >= 0:
self.form.cboPostProcessor.setCurrentIndex(index) self.form.cboPostProcessor.blockSignals(True)
self.form.cboPostProcessor.setCurrentIndex(postindex)
self.form.cboPostProcessor.blockSignals(False)
for child in self.obj.Group: for child in self.obj.Group:
self.form.PathsList.addItem(child.Name) self.form.PathsList.addItem(child.Name)
if self.obj.Base is not None: if self.obj.Base is not None:
index = self.form.cboBaseObject.findText(self.obj.Base.Name, QtCore.Qt.MatchFixedString) baseindex = self.form.cboBaseObject.findText(self.obj.Base.Name, QtCore.Qt.MatchFixedString)
if index >= 0: print baseindex
self.form.cboBaseObject.setCurrentIndex(index) if baseindex >= 0:
self.form.cboBaseObject.blockSignals(True)
self.form.cboBaseObject.setCurrentIndex(baseindex)
self.form.cboBaseObject.blockSignals(False)
def open(self): def open(self):

View File

@ -453,8 +453,8 @@ class CommandPathProfileEdges:
class TaskPanel: class TaskPanel:
def __init__(self): def __init__(self):
#self.form = FreeCADGui.PySideUic.loadUi(":/panels/ProfileEdgesEdit.ui") self.form = FreeCADGui.PySideUic.loadUi(":/panels/ProfileEdgesEdit.ui")
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ProfileEdgesEdit.ui") #self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ProfileEdgesEdit.ui")
self.updating = False self.updating = False

View File

@ -287,38 +287,48 @@ class ObjectSurface:
output += "(" + obj.Label + ")" output += "(" + obj.Label + ")"
output += "(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")" output += "(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"
if obj.Base: # if obj.Base:
for b in obj.Base: # for b in obj.Base:
if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']: parentJob = PathUtils.findParentJob(obj)
try: if parentJob is None:
import ocl return
except: mesh = parentJob.Base
FreeCAD.Console.PrintError(translate( if mesh is None:
"PathSurface", "This operation requires OpenCamLib to be installed.\n")) return
return print "base object: " + mesh.Name
mesh = b[0]
if mesh.TypeId.startswith('Mesh'):
mesh = mesh.Mesh
bb = mesh.BoundBox
else:
bb = mesh.Shape.BoundBox
mesh = MeshPart.meshFromShape(mesh.Shape, MaxLength=2)
s = ocl.STLSurf()
for f in mesh.Facets:
p = f.Points[0]
q = f.Points[1]
r = f.Points[2]
t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point(
q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2]))
s.addTriangle(t)
if obj.Algorithm == 'OCL Dropcutter': if obj.Algorithm in ['OCL Dropcutter', 'OCL Waterline']:
output = self._dropcutter(obj, s, bb) try:
elif obj.Algorithm == 'OCL Waterline': import ocl
output = self._waterline(obj, s, bb) except:
FreeCAD.Console.PrintError(translate(
"PathSurface", "This operation requires OpenCamLib to be installed.\n"))
return
#mesh = b[0]
if mesh.TypeId.startswith('Mesh'):
mesh = mesh.Mesh
bb = mesh.BoundBox
else:
bb = mesh.Shape.BoundBox
mesh = MeshPart.meshFromShape(mesh.Shape, MaxLength=2)
s = ocl.STLSurf()
for f in mesh.Facets:
p = f.Points[0]
q = f.Points[1]
r = f.Points[2]
t = ocl.Triangle(ocl.Point(p[0], p[1], p[2]), ocl.Point(
q[0], q[1], q[2]), ocl.Point(r[0], r[1], r[2]))
s.addTriangle(t)
if obj.Algorithm == 'OCL Dropcutter':
output = self._dropcutter(obj, s, bb)
elif obj.Algorithm == 'OCL Waterline':
output = self._waterline(obj, s, bb)
if obj.Active: if obj.Active:
path = Path.Path(output) path = Path.Path(output)

View File

@ -248,6 +248,7 @@ class ToolLibraryManager():
def addnew(self, listname, tool, position = None): def addnew(self, listname, tool, position = None):
"adds a new tool at the end of the table" "adds a new tool at the end of the table"
print listname, tool, position
tt = self._findList(listname) tt = self._findList(listname)
if position is None: if position is None:
tt.addTools(tool) tt.addTools(tool)
@ -326,7 +327,6 @@ class ToolLibraryManager():
pass pass
class EditorPanel(): class EditorPanel():
def __init__(self): def __init__(self):
#self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolLibraryEditor.ui") #self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolLibraryEditor.ui")
self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolLibraryEditor.ui") self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolLibraryEditor.ui")
@ -441,14 +441,17 @@ class EditorPanel():
def delete(self): def delete(self):
'''deletes a tool''' '''deletes a tool'''
item = self.form.ToolsList.selectedIndexes()[1].data() listname = self.form.listView.selectedIndexes()[0].data()
if item: model = self.form.ToolsList.model()
number = int(item) for i in range(model.rowCount()):
listname = self.form.listView.selectedIndexes()[0].data() item = model.item(i, 0)
if self.TLM.delete(number, listname) is True: if item.checkState():
self.loadTable(self.form.listView.selectedIndexes()[0]) t = model.index(i, 1)
self.TLM.delete(int(t.data()) ,listname)
self.loadTable(self.form.listView.selectedIndexes()[0])
def editTool(self, currItem): def editTool(self, currItem):
row = currItem.row() row = currItem.row()
value = currItem.sibling(row, 1).data() value = currItem.sibling(row, 1).data()
listname = self.form.listView.selectedIndexes()[0].data() listname = self.form.listView.selectedIndexes()[0].data()