Merge pull request #4315 from mlampert/bugfix/vcarve-selection-and-feature-processing
[Path]: Bugfix/vcarve selection and feature processing
This commit is contained in:
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>250</height>
|
||||
<width>476</width>
|
||||
<height>342</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -23,94 +23,28 @@
|
||||
<iconset resource="../Path.qrc">
|
||||
<normaloff>:/icons/Path_BaseGeometry.svg</normaloff>:/icons/Path_BaseGeometry.svg</iconset>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="geometryImportButton">
|
||||
<property name="text">
|
||||
<string>Import</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="deleteBase">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Remove the selected list items from the list of base geometries. The operation will not be applied to them.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QComboBox" name="geometryImportList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>List of operations with Base Geometry in current Job.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<widget class="QListWidget" name="baseList">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select one or more features in the 3d view and press 'Add' to add them as the base items for this operation.</p><p><br/></p><p>Selected features can be deleted entirely.</p></body></html></string>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QPushButton" name="clearBase">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Clears list of base geometries.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="addBase">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Add selected features to the list of base geometries for this operation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>All objects will be processed using the same operation properties</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="addBase">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Add selected features to the list of base geometries for this operation.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QPushButton" name="deleteBase">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Remove the selected list items from the list of base geometries. The operation will not be applied to them.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@@ -123,14 +57,70 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QPushButton" name="clearBase">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Clears list of base geometries.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Clear</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>All objects will be processed using the same operation properties</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QListWidget" name="baseList">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Select one or more features in the 3d view and press 'Add' to add them as the base items for this operation.</p><p><br/></p><p>Selected features can be deleted entirely.</p></body></html></string>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QPushButton" name="geometryImportButton">
|
||||
<property name="text">
|
||||
<string>Import</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QComboBox" name="geometryImportList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>List of operations with Base Geometry in current Job.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>baseList</tabstop>
|
||||
<tabstop>addBase</tabstop>
|
||||
<tabstop>deleteBase</tabstop>
|
||||
<tabstop>clearBase</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../Path.qrc"/>
|
||||
</resources>
|
||||
|
||||
@@ -422,7 +422,10 @@ class ObjectOp(object):
|
||||
zmax = max(zmax, bb.ZMax)
|
||||
for sub in sublist:
|
||||
try:
|
||||
fbb = base.Shape.getElement(sub).BoundBox
|
||||
if sub:
|
||||
fbb = base.Shape.getElement(sub).BoundBox
|
||||
else:
|
||||
fbb = base.Shape.BoundBox
|
||||
zmin = max(zmin, faceZmin(bb, fbb))
|
||||
zmax = max(zmax, fbb.ZMax)
|
||||
except Part.OCCError as e:
|
||||
|
||||
@@ -42,13 +42,8 @@ __author__ = "sliptonic (Brad Collette)"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
__doc__ = "Base classes and framework for Path operation's UI"
|
||||
|
||||
LOGLEVEL = False
|
||||
|
||||
if LOGLEVEL:
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
else:
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
# PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
|
||||
def translate(context, text, disambig=None):
|
||||
@@ -566,6 +561,7 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
return False
|
||||
|
||||
def addBase(self):
|
||||
PathLog.track()
|
||||
if self.addBaseGeometry(FreeCADGui.Selection.getSelectionEx()):
|
||||
# self.obj.Proxy.execute(self.obj)
|
||||
self.setFields(self.obj)
|
||||
@@ -636,11 +632,18 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
|
||||
# Set base geometry list window to resize based on contents
|
||||
# Code reference:
|
||||
# https://stackoverflow.com/questions/6337589/qlistwidget-adjust-size-to-content
|
||||
# ml: disabling this logic because I can't get it to work on HPD monitor.
|
||||
# On my systems the values returned by the list object are also incorrect on
|
||||
# creation, leading to a list object of size 15. count() always returns 0 until
|
||||
# the list is actually displayed. The same is true for sizeHintForRow(0), which
|
||||
# returns -1 until the widget is rendered. The widget claims to have a size of
|
||||
# (100, 30), once it becomes visible the size is (535, 192).
|
||||
# Leaving the framework here in case somebody figures out how to set this up
|
||||
# properly.
|
||||
qList = self.form.baseList
|
||||
# qList.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||
col = qList.width() # 300
|
||||
row = (qList.count() + qList.frameWidth()) * 15
|
||||
qList.setFixedSize(col, row)
|
||||
#qList.setMinimumHeight(row)
|
||||
PathLog.debug("baseList({}, {}) {} * {}".format(qList.size(), row, qList.count(), qList.sizeHintForRow(0)))
|
||||
|
||||
|
||||
class TaskPanelBaseLocationPage(TaskPanelPage):
|
||||
|
||||
@@ -210,11 +210,6 @@ class ObjectVcarve(PathEngraveBase.ObjectOp):
|
||||
QtCore.QT_TRANSLATE_NOOP("PathVcarve",
|
||||
"Additional base objects to be engraved"))
|
||||
obj.setEditorMode('BaseShapes', 2) # hide
|
||||
if not hasattr(obj, 'BaseObject'):
|
||||
obj.addProperty("App::PropertyLink", "BaseObject", "Path",
|
||||
QtCore.QT_TRANSLATE_NOOP("PathVcarve",
|
||||
"Additional base objects to be engraved"))
|
||||
obj.setEditorMode('BaseObject', 2) # hide
|
||||
|
||||
def initOperation(self, obj):
|
||||
'''initOperation(obj) ... create vcarve specific properties.'''
|
||||
@@ -242,7 +237,7 @@ class ObjectVcarve(PathEngraveBase.ObjectOp):
|
||||
edges.append(_getPartEdge(e, geom))
|
||||
return edges
|
||||
|
||||
def buildPathMedial(self, obj, Faces):
|
||||
def buildPathMedial(self, obj, faces):
|
||||
'''constructs a medial axis path using openvoronoi'''
|
||||
|
||||
def insert_many_wires(vd, wires):
|
||||
@@ -271,7 +266,7 @@ class ObjectVcarve(PathEngraveBase.ObjectOp):
|
||||
|
||||
VD.clear()
|
||||
voronoiWires = []
|
||||
for f in Faces:
|
||||
for f in faces:
|
||||
vd = Path.Voronoi()
|
||||
insert_many_wires(vd, f.Wires)
|
||||
|
||||
@@ -311,41 +306,39 @@ class ObjectVcarve(PathEngraveBase.ObjectOp):
|
||||
PathLog.track()
|
||||
|
||||
if not hasattr(obj.ToolController.Tool, "CuttingEdgeAngle"):
|
||||
FreeCAD.Console.PrintError(
|
||||
translate("Path_Vcarve", "VCarve requires an engraving \
|
||||
cutter with CuttingEdgeAngle") + "\n")
|
||||
PathLog.error(translate("Path_Vcarve", "VCarve requires an engraving cutter with CuttingEdgeAngle"))
|
||||
|
||||
if obj.ToolController.Tool.CuttingEdgeAngle >= 180.0:
|
||||
FreeCAD.Console.PrintError(
|
||||
translate("Path_Vcarve",
|
||||
"Engraver Cutting Edge Angle must be < 180 degrees.") + "\n")
|
||||
PathLog.error(translate("Path_Vcarve", "Engraver Cutting Edge Angle must be < 180 degrees."))
|
||||
return
|
||||
|
||||
try:
|
||||
if obj.Base:
|
||||
PathLog.track()
|
||||
for base in obj.Base:
|
||||
faces = []
|
||||
for sub in base[1]:
|
||||
shape = getattr(base[0].Shape, sub)
|
||||
if isinstance(shape, Part.Face):
|
||||
faces.append(shape)
|
||||
faces = []
|
||||
|
||||
modelshape = Part.makeCompound(faces)
|
||||
for base in obj.BaseShapes:
|
||||
faces.extend(base.Shape.Faces)
|
||||
|
||||
elif len(self.model) == 1 and self.model[0].isDerivedFrom('Sketcher::SketchObject') or \
|
||||
self.model[0].isDerivedFrom('Part::Part2DObject'):
|
||||
PathLog.track()
|
||||
for base in obj.Base:
|
||||
for sub in base[1]:
|
||||
shape = getattr(base[0].Shape, sub)
|
||||
if isinstance(shape, Part.Face):
|
||||
faces.append(shape)
|
||||
|
||||
modelshape = self.model[0].Shape
|
||||
self.buildPathMedial(obj, modelshape.Faces)
|
||||
if not faces:
|
||||
for model in self.model:
|
||||
if model.isDerivedFrom('Sketcher::SketchObject') or model.isDerivedFrom('Part::Part2DObject'):
|
||||
faces.extend(model.Shape.Faces)
|
||||
|
||||
if faces:
|
||||
self.buildPathMedial(obj, faces)
|
||||
else:
|
||||
PathLog.error(translate('PathVcarve', 'The Job Base Object has no engraveable element. Engraving operation will produce no output.'))
|
||||
|
||||
except Exception as e:
|
||||
PathLog.error(e)
|
||||
traceback.print_exc()
|
||||
PathLog.error(translate('PathVcarve', 'The Job Base Object has \
|
||||
no engraveable element. Engraving \
|
||||
operation will produce no output.'))
|
||||
raise e
|
||||
#PathLog.error(e)
|
||||
#traceback.print_exc()
|
||||
PathLog.error(translate('PathVcarve', 'Error processing Base object. Engraving operation will produce no output.'))
|
||||
#raise e
|
||||
|
||||
def opUpdateDepths(self, obj, ignoreErrors=False):
|
||||
'''updateDepths(obj) ... engraving is always done at the top most z-value'''
|
||||
|
||||
@@ -53,6 +53,7 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
return super(TaskPanelBaseGeometryPage, self)
|
||||
|
||||
def addBaseGeometry(self, selection):
|
||||
PathLog.track(selection)
|
||||
added = False
|
||||
shapes = self.obj.BaseShapes
|
||||
for sel in selection:
|
||||
@@ -78,10 +79,12 @@ class TaskPanelBaseGeometryPage(PathOpGui.TaskPanelBaseGeometryPage):
|
||||
shapes.append(base)
|
||||
self.obj.BaseShapes = shapes
|
||||
added = True
|
||||
else:
|
||||
# user wants us to engrave an edge of face of a base model
|
||||
base = self.super().addBaseGeometry(selection)
|
||||
added = added or base
|
||||
|
||||
if not added:
|
||||
# user wants us to engrave an edge of face of a base model
|
||||
PathLog.info(" call default")
|
||||
base = self.super().addBaseGeometry(selection)
|
||||
added = added or base
|
||||
|
||||
return added
|
||||
|
||||
|
||||
Reference in New Issue
Block a user