Youen Toupin
3 years ago
7 changed files with 267 additions and 11 deletions
@ -0,0 +1,58 @@ |
|||||||
|
import os |
||||||
|
|
||||||
|
import FreeCADGui as Gui |
||||||
|
import FreeCAD as App |
||||||
|
|
||||||
|
class AHB_ExportCsv: |
||||||
|
def GetResources(self): |
||||||
|
return {"MenuText": "CSV export", |
||||||
|
"ToolTip": "Export part list as a CSV file", |
||||||
|
"Pixmap": "" |
||||||
|
} |
||||||
|
|
||||||
|
def IsActive(self): |
||||||
|
return True |
||||||
|
|
||||||
|
def Activated(self): |
||||||
|
doc = App.activeDocument() |
||||||
|
|
||||||
|
fileName: str = doc.FileName |
||||||
|
if fileName is None: |
||||||
|
raise BaseException("You must save your FreeCAD document before exporting to CSV") |
||||||
|
|
||||||
|
csvFileName = os.path.splitext(fileName)[0] + ".csv" |
||||||
|
|
||||||
|
print("Exporting parts to CSV file " + csvFileName + "...") |
||||||
|
|
||||||
|
def readProp(obj, prop, default): |
||||||
|
if prop in obj.PropertiesList: |
||||||
|
return obj.getPropertyByName(prop) |
||||||
|
else: |
||||||
|
return default |
||||||
|
|
||||||
|
parts = [] |
||||||
|
obj: App.DocumentObject |
||||||
|
for obj in doc.Objects: |
||||||
|
if obj.TypeId == 'Part::Feature': |
||||||
|
parts.append((readProp(obj, 'Base_Layer', '').replace(',', '-') + "," + readProp(obj, 'Base_Reference', '').replace(',', '-'), "=\"" + obj.Label.replace(',', '-') + "\"")) |
||||||
|
|
||||||
|
parts.sort() |
||||||
|
|
||||||
|
with open(csvFileName, 'w', encoding='utf8') as csvFile: |
||||||
|
csvFile.write("Group, Reference, Name, Quantity\n") |
||||||
|
|
||||||
|
quantity = 0 |
||||||
|
prevPart = parts[0] |
||||||
|
for partIdx in range(len(parts) + 1): |
||||||
|
part = parts[partIdx] if partIdx < len(parts) else ("eof", "eof") |
||||||
|
if part[0] == prevPart[0]: |
||||||
|
quantity += 1 |
||||||
|
else: |
||||||
|
csvFile.write(prevPart[0] + "," + prevPart[1] + "," + str(quantity) + "\n") |
||||||
|
quantity = 1 |
||||||
|
prevPart = part |
||||||
|
|
||||||
|
print("CSV file exported") |
||||||
|
|
||||||
|
from ahb_command import AHB_CommandWrapper |
||||||
|
AHB_CommandWrapper.addGuiCommand('AHB_exportCsv', AHB_ExportCsv()) |
@ -0,0 +1,20 @@ |
|||||||
|
import FreeCADGui as Gui |
||||||
|
import FreeCAD as App |
||||||
|
|
||||||
|
class AHB_Reload: |
||||||
|
def GetResources(self): |
||||||
|
return {"MenuText": "[dev] Reload workbench", |
||||||
|
"ToolTip": "Reload the workbench without restarting FreeCAD (development tool)", |
||||||
|
"Pixmap": "" |
||||||
|
} |
||||||
|
|
||||||
|
def IsActive(self): |
||||||
|
return True |
||||||
|
|
||||||
|
def Activated(self): |
||||||
|
print("Reloading AssemblyHandbookWorkbench") |
||||||
|
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") |
||||||
|
workbench.reload() |
||||||
|
|
||||||
|
from ahb_command import AHB_CommandWrapper |
||||||
|
AHB_CommandWrapper.addGuiCommand('AHB_reload', AHB_Reload()) |
@ -0,0 +1,29 @@ |
|||||||
|
import FreeCADGui as Gui |
||||||
|
import FreeCAD as App |
||||||
|
from PySide import QtGui |
||||||
|
|
||||||
|
|
||||||
|
class AHB_SetActiveStage: |
||||||
|
def GetResources(self): |
||||||
|
return {"MenuText": "Set active stage", |
||||||
|
"ToolTip": "Sets the stage which is the active stage, or creates a new stage if it doesn't exist", |
||||||
|
"Pixmap": "" |
||||||
|
} |
||||||
|
|
||||||
|
def IsActive(self): |
||||||
|
return True |
||||||
|
|
||||||
|
def Activated(self, stageId = None): |
||||||
|
if stageId is None: |
||||||
|
reply = QtGui.QInputDialog.getText(None, "Set Active Stage", "Enter the stage number:") |
||||||
|
if reply[1]: |
||||||
|
# user clicked OK |
||||||
|
stageId = int(reply[0]) |
||||||
|
else: |
||||||
|
return |
||||||
|
|
||||||
|
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") |
||||||
|
workbench.context.setActiveStage(stageId) |
||||||
|
|
||||||
|
from ahb_command import AHB_CommandWrapper |
||||||
|
AHB_CommandWrapper.addGuiCommand('AHB_setActiveStage', AHB_SetActiveStage()) |
@ -0,0 +1,33 @@ |
|||||||
|
from typing import Optional |
||||||
|
|
||||||
|
import FreeCADGui as Gui |
||||||
|
import FreeCAD as App |
||||||
|
|
||||||
|
class AHB_SetPartStage: |
||||||
|
def GetResources(self): |
||||||
|
return {"MenuText": "Set part stage", |
||||||
|
"ToolTip": "Sets the stage for this part to the currently active stage", |
||||||
|
"Pixmap": "" |
||||||
|
} |
||||||
|
|
||||||
|
def IsActive(self): |
||||||
|
return True |
||||||
|
|
||||||
|
def Activated(self, stageId: Optional[int] = None): |
||||||
|
workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") |
||||||
|
if stageId is None: |
||||||
|
stageId = workbench.context.getActiveStage() |
||||||
|
if stageId is None: |
||||||
|
raise BaseException("You must activate a stage before using this command") |
||||||
|
|
||||||
|
obj: App.DocumentObject |
||||||
|
for obj in Gui.Selection.getSelection(): |
||||||
|
if obj is not None and obj.TypeId == 'Part::Feature': |
||||||
|
if not "AssemblyHandbook_Stage" in obj.PropertiesList: |
||||||
|
obj.addProperty("App::PropertyInteger", "AssemblyHandbook_Stage", "AssemblyHandbook") |
||||||
|
if obj.AssemblyHandbook_Stage != stageId: |
||||||
|
obj.AssemblyHandbook_Stage = stageId |
||||||
|
workbench.context.onPartStageChanged(obj) |
||||||
|
|
||||||
|
from ahb_command import AHB_CommandWrapper |
||||||
|
AHB_CommandWrapper.addGuiCommand('AHB_setPartStage', AHB_SetPartStage()) |
@ -0,0 +1,28 @@ |
|||||||
|
import FreeCADGui as Gui |
||||||
|
|
||||||
|
global ahb_commands |
||||||
|
ahb_commands = {} |
||||||
|
|
||||||
|
class AHB_CommandWrapper: |
||||||
|
def __init__(self, command_name): |
||||||
|
self.command_name = command_name |
||||||
|
|
||||||
|
def __getattr__(self, attrName): |
||||||
|
instance = ahb_commands[self.command_name] |
||||||
|
result = getattr(instance, attrName) |
||||||
|
if callable(result): |
||||||
|
# replace self |
||||||
|
def f(*args, **kwargs): return result.__func__(instance, *args, **kwargs) |
||||||
|
return f |
||||||
|
else: |
||||||
|
return result |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def addGuiCommand(command_name, command_instance): |
||||||
|
#print(("adding" if not command_name in ahb_commands else "updating") + " command " + command_name) |
||||||
|
ahb_commands.update({ command_name: command_instance }) |
||||||
|
Gui.addCommand(command_name, AHB_CommandWrapper(command_name)) |
||||||
|
|
||||||
|
@staticmethod |
||||||
|
def listGuiCommands(): |
||||||
|
return ahb_commands.keys() |
@ -0,0 +1,49 @@ |
|||||||
|
import FreeCADGui as Gui |
||||||
|
import FreeCAD as App |
||||||
|
import random |
||||||
|
|
||||||
|
def _rgb(r, g, b): |
||||||
|
return r/255.0, g/255.0, b/255.0, 0.0 |
||||||
|
|
||||||
|
_colors = [ |
||||||
|
_rgb(94, 224, 174), |
||||||
|
_rgb(223, 234, 70), |
||||||
|
_rgb(35, 120, 200), |
||||||
|
_rgb(188, 80, 33), |
||||||
|
_rgb(26, 242, 69), |
||||||
|
_rgb(13, 41, 107), |
||||||
|
_rgb(153, 9, 52), |
||||||
|
_rgb(211, 119, 0), |
||||||
|
_rgb(34, 130, 7), |
||||||
|
_rgb(221, 79, 249) |
||||||
|
] |
||||||
|
|
||||||
|
class AHB_Context: |
||||||
|
_activeStageId: int = None |
||||||
|
|
||||||
|
def setActiveStage(self, stageId): |
||||||
|
self._activeStageId = stageId |
||||||
|
|
||||||
|
def getActiveStage(self): |
||||||
|
return self._activeStageId |
||||||
|
|
||||||
|
def onPartStageChanged(self, part: App.DocumentObject): |
||||||
|
allStages = set() |
||||||
|
|
||||||
|
doc = App.ActiveDocument |
||||||
|
for obj in doc.Objects: |
||||||
|
if obj.TypeId == 'Part::Feature': |
||||||
|
if 'AssemblyHandbook_Stage' in obj.PropertiesList: |
||||||
|
allStages.add(obj.AssemblyHandbook_Stage) |
||||||
|
|
||||||
|
allStages = list(allStages) |
||||||
|
allStages.sort() |
||||||
|
|
||||||
|
if not 'AssemblyHandbook_Stage' in part.PropertiesList: |
||||||
|
part.ViewObject.ShapeColor = (0.8,0.8,0.8,0.0) |
||||||
|
|
||||||
|
for obj in doc.Objects: |
||||||
|
if obj.TypeId == 'Part::Feature': |
||||||
|
if 'AssemblyHandbook_Stage' in obj.PropertiesList: |
||||||
|
stageIndex = allStages.index(obj.AssemblyHandbook_Stage) |
||||||
|
obj.ViewObject.ShapeColor = _colors[stageIndex % len(_colors)] |
Loading…
Reference in new issue