big updates on UI and macro
This commit is contained in:
parent
f6e39d597a
commit
f847a7c91b
|
|
@ -5,6 +5,7 @@ import Draft
|
||||||
import os
|
import os
|
||||||
import Mesh
|
import Mesh
|
||||||
from PySide2.QtWidgets import QWidget, QLabel, QSpinBox, QHBoxLayout, QListWidgetItem
|
from PySide2.QtWidgets import QWidget, QLabel, QSpinBox, QHBoxLayout, QListWidgetItem
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
class ObjectListItem(QWidget):
|
class ObjectListItem(QWidget):
|
||||||
|
|
@ -34,18 +35,21 @@ class WindowDialog():
|
||||||
self.form = FreeCADGui.PySideUic.loadUi(self.ui_file)
|
self.form = FreeCADGui.PySideUic.loadUi(self.ui_file)
|
||||||
self._connect_widgets()
|
self._connect_widgets()
|
||||||
self._populate_selector_list()
|
self._populate_selector_list()
|
||||||
|
|
||||||
|
# Connect the selection change signal to keep the list in sync
|
||||||
|
FreeCADGui.Selection.addObserver(self._on_selection_changed)
|
||||||
|
|
||||||
self.form.show()
|
self.form.show()
|
||||||
|
|
||||||
def _connect_widgets(self):
|
|
||||||
self.form.pushButtonSVG.pressed.connect(lambda: self.exportSVG(False))
|
|
||||||
self.form.pushButtonCalepinage.pressed.connect(lambda: self.exportSVG(True))
|
|
||||||
self.form.pushButtonSTLSingle.pressed.connect(lambda: self.exportSTL(True))
|
|
||||||
self.form.pushButtonSTLMulti.pressed.connect(lambda: self.exportSTL(False))
|
|
||||||
self.form.listWidgetSelector.itemSelectionChanged.connect(self._on_selector_item_changed)
|
|
||||||
|
|
||||||
|
def _connect_widgets(self):
|
||||||
|
self.form.pushButtonExport.pressed.connect(self.export)
|
||||||
|
self.form.listWidgetSelector.itemClicked.connect(self._on_list_item_clicked)
|
||||||
|
|
||||||
def _populate_selector_list(self):
|
def _populate_selector_list(self):
|
||||||
self.form.listWidgetSelector.clear()
|
self.form.listWidgetSelector.clear()
|
||||||
|
FreeCADGui.Selection.clearSelection()
|
||||||
|
|
||||||
for obj in FreeCAD.ActiveDocument.Objects:
|
for obj in FreeCAD.ActiveDocument.Objects:
|
||||||
if obj.Label.startswith("SVG-") or obj.Label.startswith("STL-"):
|
if obj.Label.startswith("SVG-") or obj.Label.startswith("STL-"):
|
||||||
item = QListWidgetItem()
|
item = QListWidgetItem()
|
||||||
|
|
@ -55,19 +59,39 @@ class WindowDialog():
|
||||||
self.form.listWidgetSelector.addItem(item)
|
self.form.listWidgetSelector.addItem(item)
|
||||||
self.form.listWidgetSelector.setItemWidget(item, widget)
|
self.form.listWidgetSelector.setItemWidget(item, widget)
|
||||||
|
|
||||||
def _on_selector_item_changed(self):
|
# Sync selection: add the object to the selection and select the item in the list
|
||||||
self.selectedItems = []
|
item.setSelected(True)
|
||||||
FreeCADGui.Selection.clearSelection()
|
FreeCADGui.Selection.addSelection(obj)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _on_list_item_clicked(self, item):
|
||||||
|
widget = self.form.listWidgetSelector.itemWidget(item)
|
||||||
|
obj = widget.obj
|
||||||
|
if obj in FreeCADGui.Selection.getSelection():
|
||||||
|
FreeCADGui.Selection.removeSelection(obj)
|
||||||
|
else:
|
||||||
|
FreeCADGui.Selection.addSelection(obj)
|
||||||
|
|
||||||
|
def _on_selection_changed(self, doc, objects):
|
||||||
|
# Clear current selection in the list
|
||||||
for index in range(self.form.listWidgetSelector.count()):
|
for index in range(self.form.listWidgetSelector.count()):
|
||||||
item = self.form.listWidgetSelector.item(index)
|
item = self.form.listWidgetSelector.item(index)
|
||||||
widget = self.form.listWidgetSelector.itemWidget(item)
|
widget = self.form.listWidgetSelector.itemWidget(item)
|
||||||
if item.isSelected():
|
item.setSelected(False) # Deselect in the list
|
||||||
FreeCADGui.Selection.addSelection(widget.obj)
|
|
||||||
self.selectedItems.append((widget.obj, widget.get_value()))
|
# Sync the list selection with FreeCAD's current selection
|
||||||
|
for obj in FreeCADGui.Selection.getSelection():
|
||||||
|
for index in range(self.form.listWidgetSelector.count()):
|
||||||
|
item = self.form.listWidgetSelector.item(index)
|
||||||
|
widget = self.form.listWidgetSelector.itemWidget(item)
|
||||||
|
if widget.obj == obj:
|
||||||
|
item.setSelected(True) # Select the corresponding item in the list
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
def _createFolder(self):
|
def _createFolder(self):
|
||||||
folderPath = f"{FreeCAD.activeDocument().getFileName().rpartition('.')[0]}-Exports/"
|
folderPath = f"{FreeCAD.activeDocument().getFileName().rpartition('.')[0]}-{datetime.today().strftime('%Y-%m-%d')}-Exports/"
|
||||||
|
|
||||||
if not os.path.exists(folderPath):
|
if not os.path.exists(folderPath):
|
||||||
os.makedirs(folderPath)
|
os.makedirs(folderPath)
|
||||||
|
|
@ -184,54 +208,64 @@ class WindowDialog():
|
||||||
spacing = self.form.doubleSpinBoxSpacing.value()
|
spacing = self.form.doubleSpinBoxSpacing.value()
|
||||||
sketchList = []
|
sketchList = []
|
||||||
|
|
||||||
# Loop over all selected items in list widget, not GUI selection
|
for obj in FreeCADGui.Selection.getSelection():
|
||||||
for index in range(self.form.listWidgetSelector.count()):
|
if not obj.Label.startswith("SVG-"):
|
||||||
item = self.form.listWidgetSelector.item(index)
|
continue
|
||||||
widget = self.form.listWidgetSelector.itemWidget(item)
|
|
||||||
if item.isSelected():
|
|
||||||
count = widget.get_value()
|
|
||||||
obj = widget.obj
|
|
||||||
|
|
||||||
for _ in range(count):
|
count = 1 # default if not using spinboxes (or fetch from list if desired)
|
||||||
# Create 2D view and sketch for each instance
|
# Optional: match count from list
|
||||||
if hasattr(obj, 'Dir'):
|
for index in range(self.form.listWidgetSelector.count()):
|
||||||
sv0 = Draft.make_shape2dview(obj, FreeCAD.Vector(obj.Dir))
|
item = self.form.listWidgetSelector.item(index)
|
||||||
elif hasattr(obj, 'Objects'):
|
widget = self.form.listWidgetSelector.itemWidget(item)
|
||||||
for child in obj.Objects:
|
if widget.obj == obj:
|
||||||
if hasattr(child, 'Dir'):
|
count = widget.get_value()
|
||||||
sv0 = Draft.make_shape2dview(child, FreeCAD.Vector(child.Dir))
|
break
|
||||||
break
|
|
||||||
|
|
||||||
FreeCAD.ActiveDocument.recompute()
|
for _ in range(count):
|
||||||
sk = Draft.make_sketch(sv0, autoconstraints=True)
|
if hasattr(obj, 'Dir'):
|
||||||
sk.ViewObject.LineColor = (1.0, 0.0, 0.0)
|
sv0 = Draft.make_shape2dview(obj, FreeCAD.Vector(obj.Dir))
|
||||||
FreeCAD.ActiveDocument.recompute()
|
elif hasattr(obj, 'Objects'):
|
||||||
sketchList.append(sk)
|
for child in obj.Objects:
|
||||||
|
if hasattr(child, 'Dir'):
|
||||||
|
sv0 = Draft.make_shape2dview(child, FreeCAD.Vector(child.Dir))
|
||||||
|
break
|
||||||
|
|
||||||
if hasattr(sv0, 'Name'):
|
FreeCAD.ActiveDocument.recompute()
|
||||||
FreeCAD.ActiveDocument.removeObject(sv0.Name)
|
sk = Draft.make_sketch(sv0, autoconstraints=True)
|
||||||
|
sk.ViewObject.LineColor = (1.0, 0.0, 0.0)
|
||||||
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
sketchList.append(sk)
|
||||||
|
|
||||||
|
if hasattr(sv0, 'Name'):
|
||||||
|
FreeCAD.ActiveDocument.removeObject(sv0.Name)
|
||||||
|
|
||||||
if isCalepinage:
|
if isCalepinage:
|
||||||
self._exportSketchCalepinage(sketchList, plateLength, plateWidth, spacing)
|
self._exportSketchCalepinage(sketchList, plateLength, plateWidth, spacing)
|
||||||
else:
|
else:
|
||||||
self._exportSketchBasic(sketchList)
|
self._exportSketchBasic(sketchList)
|
||||||
|
|
||||||
FreeCADGui.Selection.clearSelection()
|
|
||||||
self._populate_selector_list()
|
self._populate_selector_list()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def exportSTL(self, singleMode):
|
def exportSTL(self, singleMode):
|
||||||
objects_to_export = []
|
objects_to_export = []
|
||||||
|
|
||||||
for index in range(self.form.listWidgetSelector.count()):
|
for obj in FreeCADGui.Selection.getSelection():
|
||||||
item = self.form.listWidgetSelector.item(index)
|
if not obj.Label.startswith("STL-"):
|
||||||
widget = self.form.listWidgetSelector.itemWidget(item)
|
continue
|
||||||
if item.isSelected():
|
|
||||||
count = widget.get_value()
|
count = 1
|
||||||
obj = widget.obj
|
for index in range(self.form.listWidgetSelector.count()):
|
||||||
for i in range(count):
|
item = self.form.listWidgetSelector.item(index)
|
||||||
clone = Draft.clone(obj)
|
widget = self.form.listWidgetSelector.itemWidget(item)
|
||||||
objects_to_export.append((clone, obj.Label, i + 1))
|
if widget.obj == obj:
|
||||||
|
count = widget.get_value()
|
||||||
|
break
|
||||||
|
|
||||||
|
for i in range(count):
|
||||||
|
clone = Draft.clone(obj)
|
||||||
|
objects_to_export.append((clone, obj.Label, i + 1))
|
||||||
|
|
||||||
FreeCAD.ActiveDocument.recompute()
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
|
||||||
|
|
@ -242,7 +276,6 @@ class WindowDialog():
|
||||||
print(f"Exported STL: {filename}")
|
print(f"Exported STL: {filename}")
|
||||||
FreeCAD.ActiveDocument.removeObject(obj.Name)
|
FreeCAD.ActiveDocument.removeObject(obj.Name)
|
||||||
else:
|
else:
|
||||||
# Combine all into one STL
|
|
||||||
export_objs = [obj for obj, _, _ in objects_to_export]
|
export_objs = [obj for obj, _, _ in objects_to_export]
|
||||||
if export_objs:
|
if export_objs:
|
||||||
label = FreeCAD.activeDocument().Name
|
label = FreeCAD.activeDocument().Name
|
||||||
|
|
@ -253,12 +286,19 @@ class WindowDialog():
|
||||||
FreeCAD.ActiveDocument.removeObject(obj.Name)
|
FreeCAD.ActiveDocument.removeObject(obj.Name)
|
||||||
|
|
||||||
FreeCAD.ActiveDocument.recompute()
|
FreeCAD.ActiveDocument.recompute()
|
||||||
FreeCADGui.Selection.clearSelection()
|
|
||||||
self._populate_selector_list()
|
self._populate_selector_list()
|
||||||
|
|
||||||
|
|
||||||
|
def export(self):
|
||||||
|
isCalepinage = self.form.checkBoxCalepinage.isChecked()
|
||||||
|
isCombine = self.form.checkBoxCombine.isChecked()
|
||||||
|
|
||||||
|
self.exportSVG(isCalepinage)
|
||||||
|
self.exportSTL(isCombine)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
try:
|
try:
|
||||||
WindowDialog()
|
mainWindow = WindowDialog()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
|
|
@ -9,172 +9,157 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>600</width>
|
<width>500</width>
|
||||||
<height>500</height>
|
<height>400</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">Multi Exporting</string>
|
<string notr="true">Multi Export</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="10" column="0" colspan="3">
|
<item row="0" column="0" colspan="3">
|
||||||
<widget class="QListWidget" name="listWidgetSelector">
|
<widget class="QListWidget" name="listWidgetSelector">
|
||||||
<property name="selectionMode">
|
<property name="selectionMode">
|
||||||
<enum>QAbstractItemView::MultiSelection</enum>
|
<enum>QAbstractItemView::MultiSelection</enum>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="16" column="0" colspan="3">
|
<item row="1" column="0">
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<spacer name="verticalSpacer1">
|
||||||
<property name="currentIndex">
|
<property name="orientation">
|
||||||
<number>0</number>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="tab">
|
<property name="sizeHint" stdset="0">
|
||||||
<attribute name="title">
|
<size>
|
||||||
<string notr="true">Exportation SVG</string>
|
<width>20</width>
|
||||||
</attribute>
|
<height>40</height>
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
</size>
|
||||||
<item row="0" column="0">
|
</property>
|
||||||
<widget class="QLabel" name="label">
|
</spacer>
|
||||||
<property name="locale">
|
</item>
|
||||||
<locale language="French" country="France"/>
|
<item row="2" column="0" colspan="2">
|
||||||
</property>
|
<widget class="QLabel" name="labelDecoupe">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">Longueur du plateau (mm) :</string>
|
<string notr="true">Dimensions du plateau de découpe</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="font">
|
||||||
</item>
|
<font>
|
||||||
<item row="0" column="1">
|
<pointsize>12</pointsize>
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxLength">
|
</font>
|
||||||
<property name="maximum">
|
</property>
|
||||||
<double>999999.0</double>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="value">
|
<item row="3" column="0" colspan="2">
|
||||||
<double>729.0</double>
|
<widget class="QWidget" name="containerWidget">
|
||||||
</property>
|
<layout class="QGridLayout" name="gridLayout2">
|
||||||
</widget>
|
<item row="0" column="0">
|
||||||
</item>
|
<widget class="QLabel" name="label">
|
||||||
<item row="1" column="0">
|
<property name="locale">
|
||||||
<widget class="QLabel" name="label2">
|
<locale language="French" country="France"/>
|
||||||
<property name="text">
|
</property>
|
||||||
<string notr="true">Largeur du plateau (mm) :</string>
|
<property name="text">
|
||||||
</property>
|
<string notr="true">Longueur du plateau (mm) :</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="1" column="1">
|
</item>
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxWidth">
|
<item row="0" column="1">
|
||||||
<property name="maximum">
|
<widget class="QDoubleSpinBox" name="doubleSpinBoxLength">
|
||||||
<double>999999.0</double>
|
<property name="maximum">
|
||||||
</property>
|
<double>999999.0</double>
|
||||||
<property name="value">
|
</property>
|
||||||
<double>430.0</double>
|
<property name="value">
|
||||||
</property>
|
<double>729.0</double>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="2" column="0">
|
</item>
|
||||||
<widget class="QLabel" name="label3">
|
<item row="1" column="0">
|
||||||
<property name="text">
|
<widget class="QLabel" name="label2">
|
||||||
<string notr="true">Espacement (mm) :</string>
|
<property name="text">
|
||||||
</property>
|
<string notr="true">Largeur du plateau (mm) :</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="2" column="1">
|
</item>
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBoxSpacing">
|
<item row="1" column="1">
|
||||||
<property name="maximum">
|
<widget class="QDoubleSpinBox" name="doubleSpinBoxWidth">
|
||||||
<double>999999.0</double>
|
<property name="maximum">
|
||||||
</property>
|
<double>999999.0</double>
|
||||||
<property name="value">
|
</property>
|
||||||
<double>5.0</double>
|
<property name="value">
|
||||||
</property>
|
<double>430.0</double>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item row="4" column="0">
|
</item>
|
||||||
<spacer name="verticalSpacer">
|
<item row="2" column="0">
|
||||||
<property name="orientation">
|
<widget class="QLabel" name="label3">
|
||||||
<enum>Qt::Vertical</enum>
|
<property name="text">
|
||||||
</property>
|
<string notr="true">Espacement (mm) :</string>
|
||||||
<property name="sizeHint" stdset="0">
|
</property>
|
||||||
<size>
|
</widget>
|
||||||
<width>20</width>
|
</item>
|
||||||
<height>40</height>
|
<item row="2" column="1">
|
||||||
</size>
|
<widget class="QDoubleSpinBox" name="doubleSpinBoxSpacing">
|
||||||
</property>
|
<property name="maximum">
|
||||||
</spacer>
|
<double>999999.0</double>
|
||||||
</item>
|
</property>
|
||||||
<item row="5" column="0">
|
<property name="value">
|
||||||
<widget class="QPushButton" name="pushButtonCalepinage">
|
<double>5.0</double>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Export en .svg (calepinage)</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="minimumSize">
|
<item row="3" column="0">
|
||||||
<size>
|
<spacer name="verticalSpacer2">
|
||||||
<width>0</width>
|
<property name="orientation">
|
||||||
<height>50</height>
|
<enum>Qt::Vertical</enum>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="sizeHint" stdset="0">
|
||||||
</widget>
|
<size>
|
||||||
</item>
|
<width>20</width>
|
||||||
<item row="5" column="1">
|
<height>40</height>
|
||||||
<widget class="QPushButton" name="pushButtonSVG">
|
</size>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Export en .svg (sans calepinage)</string>
|
</spacer>
|
||||||
</property>
|
</item>
|
||||||
<property name="minimumSize">
|
<item row="4" column="0">
|
||||||
<size>
|
<widget class="QCheckBox" name="checkBoxCalepinage">
|
||||||
<width>0</width>
|
<property name="text">
|
||||||
<height>50</height>
|
<string notr="true">SVG : Calepinage</string>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="checked">
|
||||||
</widget>
|
<bool>false</bool>
|
||||||
</item>
|
</property>
|
||||||
</layout>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
<widget class="QWidget" name="tab_2">
|
<item row="5" column="0">
|
||||||
<attribute name="title">
|
<widget class="QCheckBox" name="checkBoxCombine">
|
||||||
<string notr="true">Exportation STL</string>
|
<property name="text">
|
||||||
</attribute>
|
<string notr="true">STL : Combiné</string>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
</property>
|
||||||
<item row="1" column="0">
|
<property name="checked">
|
||||||
<widget class="QPushButton" name="pushButtonSTLSingle">
|
<bool>false</bool>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Export en .stl (combiné)</string>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="minimumSize">
|
<item row="5" column="0">
|
||||||
<size>
|
<spacer name="verticalSpacer3">
|
||||||
<width>0</width>
|
<property name="orientation">
|
||||||
<height>50</height>
|
<enum>Qt::Vertical</enum>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
<property name="sizeHint" stdset="0">
|
||||||
</widget>
|
<size>
|
||||||
</item>
|
<width>20</width>
|
||||||
<item row="1" column="1">
|
<height>40</height>
|
||||||
<widget class="QPushButton" name="pushButtonSTLMulti">
|
</size>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Export en .stl (séparé)</string>
|
</spacer>
|
||||||
</property>
|
</item>
|
||||||
<property name="minimumSize">
|
<item row="6" column="1" colspan="2">
|
||||||
<size>
|
<widget class="QPushButton" name="pushButtonExport">
|
||||||
<width>0</width>
|
<property name="text">
|
||||||
<height>50</height>
|
<string notr="true">Exporter</string>
|
||||||
</size>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
</widget>
|
</item>
|
||||||
</item>
|
</layout>
|
||||||
<item row="0" column="0">
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue