Skip to content

Commit 99e036a

Browse files
author
nuofan
committed
Add FlattenOccs tool
1 parent 95319d0 commit 99e036a

File tree

2 files changed

+161
-0
lines changed

2 files changed

+161
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Script for moving all the bodies in the nested child occurrences into the target occurrence
2+
3+
import adsk.core, adsk.fusion, adsk.cam, traceback
4+
5+
from typing import List
6+
7+
# Global list to keep all event handlers in scope.
8+
# This is only needed with Python.
9+
handlers = []
10+
11+
def run(context):
12+
ui = None
13+
try:
14+
app = adsk.core.Application.get()
15+
ui = app.userInterface
16+
design = adsk.fusion.Design.cast(app.activeProduct)
17+
design.designType = adsk.fusion.DesignTypes.DirectDesignType
18+
19+
# Get the CommandDefinitions collection.
20+
cmdDefs = ui.commandDefinitions
21+
22+
# Create a button command definition.
23+
buttonSample = cmdDefs.addButtonDefinition('ACDC4Robot-Tool-FlattenOccs',
24+
'Flatten Occurrences',
25+
'Move bodies in child occs into the selected occurrence')
26+
27+
# Connect to the command created event.
28+
sampleCommandCreated = FlattenOccCommandCreatedEventHandler()
29+
buttonSample.commandCreated.add(sampleCommandCreated)
30+
handlers.append(sampleCommandCreated)
31+
32+
# Execute the command.
33+
buttonSample.execute()
34+
35+
# Keep the script running.
36+
adsk.autoTerminate(False)
37+
except:
38+
if ui:
39+
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
40+
41+
42+
# Event handler for the commandCreated event.
43+
class FlattenOccCommandCreatedEventHandler(adsk.core.CommandCreatedEventHandler):
44+
def __init__(self):
45+
super().__init__()
46+
self.app = adsk.core.Application.get()
47+
self.des = adsk.fusion.Design.cast(self.app.activeProduct)
48+
self.ui = self.app.userInterface
49+
50+
def notify(self, args):
51+
eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
52+
cmd = eventArgs.command
53+
54+
# Create a command input
55+
inputs = cmd.commandInputs
56+
57+
# Create a SelectionCommandInput, which can only select 1 occurrence
58+
selectInput: adsk.core.SelectionCommandInput = inputs.addSelectionInput(
59+
'selected-1',
60+
'Target Occurrence',
61+
'Selecte one occurrence as input occurrence.'
62+
)
63+
selectInput.addSelectionFilter("Occurrences")
64+
selectInput.setSelectionLimits(minimum=1, maximum=1)
65+
66+
# Connect to the execute event.
67+
onExecute = FlattenOccCommandExecuteHandler()
68+
cmd.execute.add(onExecute)
69+
handlers.append(onExecute)
70+
71+
72+
# Event handler for the execute event.
73+
class FlattenOccCommandExecuteHandler(adsk.core.CommandEventHandler):
74+
def __init__(self):
75+
super().__init__()
76+
self.app = adsk.core.Application.get()
77+
self.des = adsk.fusion.Design.cast(self.app.activeProduct)
78+
self.ui = self.app.userInterface
79+
# self.textPalatte: adsk.core.TextCommandPalette = self.ui.palettes.itemById("TextCommands")
80+
# if not self.textPalatte.isVisible:
81+
# self.textPalatte.isVisible = True
82+
# self.textPalatte.writeText("Start Command Execution")
83+
84+
def flatten_occ(self, targetOcc: adsk.fusion.Occurrence):
85+
"""
86+
Cut all sub occurrences' body into the input occurrence
87+
"""
88+
# get list of all sub occurrences
89+
allSubOcc: List[adsk.fusion.Occurrence] = [] # a list to store the occs waiting for operations
90+
def dfs(node: adsk.fusion.Occurrence):
91+
allSubOcc.append(node)
92+
if node.childOccurrences.count == 0:
93+
return
94+
for child in node.childOccurrences:
95+
dfs(child)
96+
97+
dfs(targetOcc)
98+
99+
allSubOcc = allSubOcc[1:] # remove targetOcc
100+
101+
# move all bodies in child occs into target occ
102+
for occ in allSubOcc:
103+
bodyList: adsk.fusion.BRepBodies = occ.bRepBodies
104+
for body in bodyList:
105+
body.moveToComponent(targetOcc)
106+
107+
# remove occ that has no childOcc and bodies
108+
allSubOcc.reverse()
109+
for occ in allSubOcc:
110+
if occ.childOccurrences.count == 0 and occ.bRepBodies.count == 0:
111+
occ.deleteMe()
112+
113+
def notify(self, args):
114+
eventArgs = adsk.core.CommandEventArgs.cast(args)
115+
116+
# Code to react to the event.
117+
118+
# Get the values from the command inputs
119+
inputs = eventArgs.command.commandInputs
120+
selectInput: adsk.core.SelectionCommandInput = inputs.itemById('selected-1')
121+
selection: adsk.core.Selection = selectInput.selection(0)
122+
entity: adsk.fusion.Occurrence = selection.entity
123+
124+
try:
125+
126+
# if self.des:
127+
self.flatten_occ(entity)
128+
message = self.app.userInterface.messageBox(
129+
"Finished flatten occurrence",
130+
"ACDC4Robot Tool"
131+
)
132+
except:
133+
if self.ui:
134+
self.ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
135+
136+
# Force the termination of the command.
137+
adsk.terminate()
138+
139+
140+
def stop(context):
141+
try:
142+
app = adsk.core.Application.get()
143+
ui = app.userInterface
144+
145+
# Delete the command definition.
146+
cmdDef = ui.commandDefinitions.itemById('ACDC4Robot-Tool-FlattenOccs')
147+
if cmdDef:
148+
cmdDef.deleteMe()
149+
except:
150+
if ui:
151+
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

Add-IN/ACDC4Robot/tools/Readme.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# ACDC4Robot Tools
2+
This folder contains tools that help users to use ACDC4Robot more convenient.
3+
The usage for each tools described below.
4+
5+
## FlattenOcc
6+
Since ACDC4Robot currently does not support nested occurrence, user needs to transfrom nested occurrence into a single occurrence that contains all the geometry bodies in the nested child occurrences.
7+
In simple terms, it means to cut and paste bodies of child occurrences into the target occurrence, and then delete those child occurrences.
8+
So we provide a tool called FlattenOcc to automatically produce this process.
9+
10+
User just run this script and choose the occurrence that you want to flatten.

0 commit comments

Comments
 (0)