-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathImage2Surface.py
More file actions
220 lines (178 loc) · 8.87 KB
/
Image2Surface.py
File metadata and controls
220 lines (178 loc) · 8.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#Author-Hans Kellner
#Description-This is an Autodesk Fusion 360 script that's used for generating surfaces from images.
#Copyright (C) 2015-2018 Hans Kellner: https://github.com/hanskellner/Fusion360Image2Surface
#MIT License: See https://github.com/hanskellner/Fusion360Image2Surface/LICENSE.md
import adsk.core, adsk.fusion, adsk.cam, traceback
import json, tempfile, platform
# global set of event handlers to keep them referenced for the duration of the command
handlers = []
_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)
# Event handler for the commandExecuted event.
class ShowPaletteCommandExecuteHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
global _app, _ui
# Verify that in parametric design mode
design = _app.activeProduct
if design.designType != adsk.fusion.DesignTypes.ParametricDesignType:
_ui.messageBox('The "Image2Surface" command must be run in parametric modeling mode.\n\nPlease enable "Capture design history" for your document.')
return
# Create and display the palette.
palette = _ui.palettes.itemById('Image2SurfacePalette')
if not palette:
palette = _ui.palettes.add('Image2SurfacePalette', 'Image2Surface', 'image2surface.html', True, True, True, 1200, 800)
# Float the palette.
palette.dockingState = adsk.core.PaletteDockingStates.PaletteDockStateFloating
# Add handler to HTMLEvent of the palette.
onHTMLEvent = MyHTMLEventHandler()
palette.incomingFromHTML.add(onHTMLEvent)
handlers.append(onHTMLEvent)
# Add handler to CloseEvent of the palette.
onClosed = MyCloseEventHandler()
palette.closed.add(onClosed)
handlers.append(onClosed)
else:
palette.isVisible = True
except:
_ui.messageBox('Command executed failed: {}'.format(traceback.format_exc()))
# Event handler for the commandCreated event.
class ShowPaletteCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
command = args.command
onExecute = ShowPaletteCommandExecuteHandler()
command.execute.add(onExecute)
handlers.append(onExecute)
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# Event handler for the commandExecuted event.
class SendInfoCommandExecuteHandler(adsk.core.CommandEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
# Send information to the palette. This will trigger an event in the javascript
# within the html so that it can be handled.
palette = _ui.palettes.itemById('Image2SurfacePalette')
if palette:
palette.sendInfoToHTML('send', 'This is a message sent to the palette from Fusion.')
except:
_ui.messageBox('Command executed failed: {}'.format(traceback.format_exc()))
# Event handler for the commandCreated event.
class SendInfoCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
command = args.command
onExecute = SendInfoCommandExecuteHandler()
command.execute.add(onExecute)
handlers.append(onExecute)
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# Event handler for the palette close event.
class MyCloseEventHandler(adsk.core.UserInterfaceGeneralEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
# _ui.messageBox('Close button is clicked.')
foo = 1
if foo == 2:
foo = 2
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
# Event handler for the palette HTML event.
class MyHTMLEventHandler(adsk.core.HTMLEventHandler):
def __init__(self):
super().__init__()
def notify(self, args):
try:
htmlArgs = adsk.core.HTMLEventArgs.cast(args)
data = json.loads(htmlArgs.data)
objStr = data['obj']
objStrLen = len(data['obj'])
if objStrLen > 0:
fp = tempfile.NamedTemporaryFile(mode='w', suffix='.obj', delete=False)
fp.writelines(objStr)
fp.close()
objFilePath = fp.name
print ("Generated OBJ File: " + objFilePath)
global _app
# Get the current document, otherwise create a new one.
doc = _app.activeDocument
if not doc:
doc = _app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
design = _app.activeProduct
# Get the root component of the active design.
rootComp = design.rootComponent
# Need to place the mesh in a BaseFeature (non-parametric)
baseFeats = rootComp.features.baseFeatures
baseFeat = baseFeats.add()
baseFeat.startEdit()
# Add a mesh body by importing this data (OBJ) file.
meshList = rootComp.meshBodies.add(objFilePath, adsk.fusion.MeshUnits.MillimeterMeshUnit, baseFeat)
# Need to finish the base feature edit
baseFeat.finishEdit()
if meshList.count > 0:
# Success - close palette
palette = _ui.palettes.itemById('Image2SurfacePalette')
if palette:
palette.isVisible = False
# HACK: bug causes mesh to be placed away from origin
# therefore zoom to fit so mesh appears to user
vp = _app.activeViewport
vp.fit()
else:
_ui.messageBox('Failed to generate mesh body from file: {}'.format(objFilePath))
else:
_ui.messageBox('Failed to generate mesh OBJ')
except:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def run(context):
try:
global _ui, _app
_app = adsk.core.Application.get()
_ui = _app.userInterface
# Add a command that displays the panel.
showPaletteCmdDef = _ui.commandDefinitions.itemById('showImage2SurfacePalette')
if not showPaletteCmdDef:
#strTooltip = '<div style=\'font-family:"Calibri";color:#e0e0e0; padding-top:-10px; padding-bottom:10px;\'><span style=\'font-size:20px;\'><b>Image 2 Surface</b></span></div>Use this add-in to convert an image into a surface (mesh).'
showPaletteCmdDef = _ui.commandDefinitions.addButtonDefinition('showImage2SurfacePalette', 'Show Image 2 Surface', '', './/Resources//image2surface')
showPaletteCmdDef.toolClipFilename = './/Resources//image2surface//image2surface-tooltip.png'
# Connect to Command Created event.
onCommandCreated = ShowPaletteCommandCreatedHandler()
showPaletteCmdDef.commandCreated.add(onCommandCreated)
handlers.append(onCommandCreated)
# Add the command to the toolbar.
panel = _ui.allToolbarPanels.itemById('SolidScriptsAddinsPanel')
cntrl = panel.controls.itemById('showImage2SurfacePalette')
if not cntrl:
panel.controls.addCommand(showPaletteCmdDef)
if context['IsApplicationStartup'] is False:
_ui.messageBox('The "Image2Surface" command has been added\nto the ADD-INS panel dropdown of the MODEL workspace.\n\nTo run the command, select the ADD-INS dropdown\nthen select "Show Image 2 Surface".')
except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def stop(context):
try:
# Delete the palette created by this add-in.
palette = _ui.palettes.itemById('Image2SurfacePalette')
if palette:
palette.deleteMe()
# Delete controls and associated command definitions created by this add-ins
panel = _ui.allToolbarPanels.itemById('SolidScriptsAddinsPanel')
cmd = panel.controls.itemById('showImage2SurfacePalette')
if cmd:
cmd.deleteMe()
cmdDef = _ui.commandDefinitions.itemById('showImage2SurfacePalette')
if cmdDef:
cmdDef.deleteMe()
except:
if _ui:
_ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))