forked from MPintoSpace/GUIMesh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
GUIMesh.py
438 lines (395 loc) · 21.7 KB
/
GUIMesh.py
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
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
#########################################################################################################
# GUIMesh v1 #
# #
# Copyright (c) 2018 Marco Gui Alves Pinto mail:[email protected] #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <https://www.gnu.org/licenses/> #
# #
#########################################################################################################
#################################################################
##########################Libraries##############################
#################################################################
import sys
try:
import tkinter as tk
from tkinter import simpledialog as tkSimpleDialog
from tkinter import messagebox as tkMessageBox
except:
print("Could not import Tkinter. It might not be installed or the installation might have a different name.")
try:
from libs import LoadOP, WriteGDML
except:
print("Could not load GUIMesh libraries. Please check if the folder GUIMeshLibs exists and if the files are there.")
#################################################################
######################Pressed Find FreeCAD#######################
#################################################################
def Pressed_Find_FreeCAD_Dir():
global FreeCAD_status
print("Pressed Find FreeCAD Dir")
#Import FreeCAD - essential to the whole program
try:
#best guess on freecad install dirs
sys.path.append("/lib/freecad-daily/lib")
sys.path.append("/lib/freecad/lib")
sys.path.append("/usr/lib/freecad-daily/lib")
sys.path.append("/usr/lib/freecad/lib")
import FreeCAD
FreeCAD_status="FreeCAD loaded"
label_FreeCAD_path.configure(text=FreeCAD_status)
tkMessageBox.showinfo("Success", "FreeCAD loaded.")
print("FreeCAD loaded.")
except:
LoadOP.Find_FreeCAD_Dir() #Load FreeCAD path to python - See LoadOP library
try:
import FreeCAD
FreeCAD_status="FreeCAD loaded"
label_FreeCAD_path.configure(text=FreeCAD_status)
tkMessageBox.showinfo("Success", "FreeCAD loaded.")
print("FreeCAD is now loaded")
except:
tkMessageBox.showinfo("Warning", "There was an error loading FreeCAD.")
print("There was an error loading FreeCAD.")
root.update()
#################################################################
#########################Pressed Read STEP#######################
#################################################################
def Pressed_Read_STEP():
global STEP_file_status
global mylist_names
global list_of_objects
global file_status
global step_file_name
global FreeCAD_status
print("Pressed Read STEP")
#Requires FreeCAD to be loaded
if (FreeCAD_status=="FreeCAD loaded"):
STEP_file_status="Opening file..."
label_STEP_path.configure(text=STEP_file_status)
temp_list_of_objects, step_file_name =LoadOP.Load_STEP_File(file_status) #Load STEP with FreeCAD library - See LoadOP library
#Check if loading was done properly
if not temp_list_of_objects:
tkMessageBox.showinfo("Error", "File format or extension is incorrect.")
print("Error: File format or extension is incorrect.")
STEP_file_status="Error opening file"
label_STEP_path.configure(text=STEP_file_status)
file_status=0
#Creates new object list
else:
list_of_objects=temp_list_of_objects #Replace previous object list (if there was one)
temp_list_of_objects=0
file_status=1
tkMessageBox.showinfo("Success", "STEP file loaded.")
print("STEP file loaded.")
STEP_file_status="STEP file loaded"
label_STEP_path.configure(text=STEP_file_status)
mylist_names.delete(0, tk.END)
for i in list_of_objects:
mylist_names.insert(tk.END,i.VolumeCAD.Label)
else:
tkMessageBox.showinfo("Error", "FreeCAD not found.")
#################################################################
#########################Pressed World Size######################
#################################################################
####### Save new world size - default is 1 m * 1 m *1 m
def Save_World_Button(x,y,z,top):
global world_dimensions
print(world_dimensions[0], world_dimensions[1], world_dimensions[2])
try:
float(x.get())
float(y.get())
float(z.get())
except:
tkMessageBox.showinfo("Error", "All variables must be float values larger than 0.")
return 0
world_dimensions[0]=abs(float(x.get()))
world_dimensions[1]=abs(float(y.get()))
world_dimensions[2]=abs(float(z.get()))
top.destroy()
print(world_dimensions[0], world_dimensions[1], world_dimensions[2])
########interface to select new world size
def Pressed_World_Size():
global world_dimensions
print("Pressed_World_Size")
#Create small interface to assign world size values
top = tk.Tk()
top.attributes('-topmost', 'true')
E1_label = tk.Message( top, text="X",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
E1_label.grid(row=0,column=0)
E1 = tk.Entry(top, bd =5)
E1.grid(row=1, column=0)
E2_label = tk.Message( top, text="Y",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
E2_label.grid(row=0,column=1)
E2 = tk.Entry(top, bd =5)
E2.grid(row=1, column=1)
E3_label = tk.Message( top, text="Z",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
E3_label.grid(row=0,column=2)
E3 = tk.Entry(top, bd =5)
E3.grid(row=1, column=2)
units_label = tk.Message( top, text="m3",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
units_label.grid(row=1,column=3)
save_world_button=tk.Button(top, text="Save",bd=5,relief="raised",width=8,height=1,bg="red",command=lambda : Save_World_Button(E1,E2,E3,top))
save_world_button.grid(row=0,column=3)
top.mainloop()
#################################################################
###########################Pressed Offset #######################
#################################################################
####### Save new offset
def Save_offset_Button(x,y,z,top):
global offset
print(offset[0], offset[1], offset[2])
try:
float(x.get())
float(y.get())
float(z.get())
except:
tkMessageBox.showinfo("Error", "All variables must be float values larger than 0.")
return 0
offset[0]=float(x.get())
offset[1]=float(y.get())
offset[2]=float(z.get())
top.destroy()
print(offset[0], offset[1], offset[2])
########interface to select new offset
def Pressed_offset():
global offset
print("Pressed_offset")
#Create small interface to assign offset values
top = tk.Tk()
top.attributes('-topmost', 'true')
E1_label = tk.Message( top, text="X",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
E1_label.grid(row=0,column=0)
E1 = tk.Entry(top, bd =5)
E1.grid(row=1, column=0)
E2_label = tk.Message( top, text="Y",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
E2_label.grid(row=0,column=1)
E2 = tk.Entry(top, bd =5)
E2.grid(row=1, column=1)
E3_label = tk.Message( top, text="Z",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
E3_label.grid(row=0,column=2)
E3 = tk.Entry(top, bd =5)
E3.grid(row=1, column=2)
units_label = tk.Message( top, text="mm",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
units_label.grid(row=1,column=3)
save_offset_button=tk.Button(top, text="Save",bd=5,relief="raised",width=8,height=1,bg="red",command=lambda : Save_offset_Button(E1,E2,E3,top))
save_offset_button.grid(row=0,column=3)
top.mainloop()
#################################################################
############################Write GDML###########################
#################################################################
def Pressed_Write_GDML():
global list_of_objects
global world_dimensions
global step_file_name
print("Pressed_Write_GDML STEP Mesh")
if list_of_objects:
WriteGDML.Write_Files(list_of_objects, world_dimensions, offset ,step_file_name) #See WriteGDML library
else:
tkMessageBox.showinfo("Error", "There are no volumes to mesh.")
#################################################################
#################Selected Volume Operations######################
#################################################################
#Change MMD
def Pressed_Change_MMD():
global list_of_objects
print("Pressed_Change_MMD")
newMMD=tkSimpleDialog.askfloat('MMD ', 'Select new MMD value.')
try:
if float(newMMD)>0:
print("MMD ok")
if set_all_var.get()==0: #Selected volume
global selected_volume_index
list_of_objects[selected_volume_index].VolumeMMD=newMMD
else: #All volumes
for i in list_of_objects:
i.VolumeMMD=newMMD
else:
tkMessageBox.showinfo("Error", "MMD must be greater than 0.")
print("Chosen value <= 0")
except:
tkMessageBox.showinfo("Error", "Value not a float.")
print("Not a float or < 0")
#Change Write GDML option
def Pressed_Change_GDML_Option():
global list_of_objects
print("Pressed_Change_GDML_Option")
newGDMLoption=tkSimpleDialog.askinteger('Write Option', 'Select Write Option.') #>=1 write - <1 do not write
if newGDMLoption<1:
newGDMLoption=0
else:
newGDMLoption=1
if not set_all_var.get(): #Selected volume
global selected_volume_index
list_of_objects[selected_volume_index].VolumeGDMLoption=newGDMLoption
else: #All volumes
for i in list_of_objects:
i.VolumeGDMLoption=newGDMLoption
#Select volume
def vol_info(evt):
global vol_properties_menu
global list_of_objects
global selected_volume_index
#Volume Name
Vol_Name = tk.StringVar(vol_properties_menu)
Vol_Name.set("") # default value
Vol_Name_label = tk.Message( vol_properties_menu, textvariable=Vol_Name, width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
Vol_Name_label.place(relx=0.05,rely=0.05,relwidth=0.9,relheight=0.1)
#Volume Size
Vol_Size = tk.StringVar(vol_properties_menu)
Vol_Size.set("") # default value
Vol_Size_label = tk.Message( vol_properties_menu, textvariable=Vol_Size,width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
Vol_Size_label.place(relx=0.05,rely=0.25,relwidth=0.9,relheight=0.1)
#Volume MMD
Vol_MMD = tk.StringVar(vol_properties_menu)
Vol_MMD.set("") # default value
Vol_MMD_label = tk.Message( vol_properties_menu, textvariable=Vol_MMD,width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
Vol_MMD_label.place(relx=0.05,rely=0.45,relwidth=0.45,relheight=0.1)
#Volume GDML option
Vol_GDML_option = tk.StringVar(vol_properties_menu)
Vol_GDML_option.set("") # default value
Vol_GDML_option_label = tk.Message( vol_properties_menu, textvariable=Vol_GDML_option,width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
Vol_GDML_option_label.place(relx=0.5,rely=0.45,relwidth=0.45,relheight=0.1)
#Set Volume Properties to display
w = evt.widget
selected_volume_index= index = int(w.curselection()[0]) #index
Vol_Name.set("Name: "+list_of_objects[index].VolumeCAD.Label)
Vol_Size.set("Volume: "+str(list_of_objects[index].VolumeCAD.Shape.Volume/1000)+" cm3")
Vol_MMD.set("MMD: "+str(list_of_objects[index].VolumeMMD)+" mm")
if list_of_objects[index].VolumeGDMLoption!=0:
Vol_GDML_option.set("Write GDML: Yes")
else:
Vol_GDML_option.set("Write GDML: No")
#################################################################
#####################Pressed Exit_Program########################
#################################################################
def Pressed_Exit_Program():
root.destroy()
#####################################################################################
##################################Main###############################################
#####################################################################################
##################
#Global variables#
##################
FreeCAD_status="FreeCAD not loaded"
STEP_file_status="No file has been loaded"
file_status=0
step_file_name = ""
world_dimensions=[1.0,1.0,1.0] #in meters
offset=[0,0,0] # in mm
list_of_objects=[]
list_of_names=[]
#####################################################################################
#######################################Canvas########################################
#####################################################################################
#Window
root = tk.Tk()
s_w = root.winfo_screenwidth()
s_h = root.winfo_screenheight()
p_w = s_w/1366.
p_h = s_h/768.
buttons_width=int(18*p_w)
buttons_height=int(2*p_h)
pos_x=0.1
pos_y=0.05
pos_y_os=0.115
font_size=20*p_h*p_w
#root.state("zoomed")
#Draw interface regions
button_menu=tk.Canvas(root,bd=5,bg="black")
button_menu.place(relx=0.01,rely=0.24,relwidth=0.12,relheight=0.59)
button_menu_rectangle=button_menu.create_rectangle(0, 0, 1000, 1000, fill="#ccccb3")
lists_menu=tk.Canvas(root,bd=5,bg="black")
lists_menu.place(relx=0.209,rely=0.24,relwidth=0.4015,relheight=0.59)
lists_menu.create_rectangle(0, 0, s_w, s_h, fill="#ccccb3")
vol_properties_menu=tk.Canvas(root, bd=5,bg="black")
vol_properties_menu.place(relx=0.7,rely=0.24,relwidth=0.295,relheight=0.59)
vol_properties_menu.create_rectangle(0, 0, s_w, s_h, fill="#ccccb3")
vol_properties_menu.create_rectangle(0, 0, s_w, s_h, fill="#ccccb3")
vol_properties_menu.create_rectangle(0, 0, s_w, s_h, fill="#ccccb3")
status_menu=tk.Canvas(root,bd=2,bg="red")
status_menu.place(relx=0.01,rely=0.892,relwidth=0.137, relheight=0.104)
status_menu.create_rectangle(0, 0, s_w, s_h, fill="#ccccb3")
#Draw Interface Labels
button_menu_label = tk.Label(root, text = "Menu",borderwidth=5,relief="solid",font=("Helvetica", int(14*p_w)),bg="#e0e0d1")
button_menu_label.place(relx=0.011 ,rely = 0.19,relwidth=0.118, relheight=0.05)
volume_menu_label = tk.Label(root, text = "Volume List",borderwidth=5,relief="solid",font=("Helvetica", int(14*p_w)),bg="#e0e0d1")
volume_menu_label.place(relx=0.21,rely = 0.19,relwidth=0.4, relheight=0.05)
edit_menu_label = tk.Label(root, text = "Volume Properties",borderwidth=5,relief="solid",font=("Helvetica", int(14*p_w)),bg="#e0e0d1")
edit_menu_label.place(relx=0.701,rely = 0.19,relwidth=0.292, relheight=0.05)
status_label = tk.Label(status_menu, text = "Status:", fg="red",font=("Helvetica", int(12*p_w)),bg="#ccccb3",bd=1)
status_label.place(relx= 0.08,rely = 0.05,relwidth=0.3, relheight=0.2)
label_FreeCAD_path = tk.Label(status_menu, font=("Helvetica", int(11*p_w)),text = FreeCAD_status,anchor="w",bg="#ccccb3",bd=1)
label_FreeCAD_path.place(relx= 0.025,rely = 0.355,relwidth=0.95, relheight=0.2)
label_STEP_path = tk.Label(status_menu, font=("Helvetica", int(11*p_w)),text = STEP_file_status,anchor="w",bg="#ccccb3",bd=1)
label_STEP_path.place(relx= 0.025,rely = 0.65,relwidth=0.9, relheight=0.2)
author_label = tk.Label(root, text = "Copyright (c) 2018 Marco Gui Alves Pinto\nmail: [email protected]",fg="red",font=("Helvetica", int(12*p_w)),bd=1,anchor='e',justify="right")
author_label.place(relx= 0.65,rely = 0.94,relwidth=0.35, relheight=0.05)
logo_label = tk.Label(root, text = "GUI Mesh", fg="red",font=("Helvetica", int(40*p_w)),bd=1)
logo_label.place(relx= 0.25,rely = 0.02,relwidth=0.5, relheight=0.1)
description_label = tk.Label(root, text = "A Graphical User Interface to convert STEP files into GDML", fg="red",font=("Helvetica", int(20*p_w)),bd=1)
description_label.place(relx= 0.25,rely = 0.1,relwidth=0.55, relheight=0.05)
#####################################################################################
###############################Menu Buttons##########################################
#####################################################################################
#FreeCAD button
button_FreeCAD_path = tk.Button(button_menu, text = 'Find FreeCAD',font=("Helvetica", int(12*p_w)), command = Pressed_Find_FreeCAD_Dir,bg="#e0e0d1")
button_FreeCAD_path.place(relx=0.1,rely=pos_y,relwidth=0.8, relheight=0.1)
#Read Step button
button_Read_STEP = tk.Button(button_menu, text = 'Read STEP', font=("Helvetica", int(12*p_w)), command = Pressed_Read_STEP,bg="#e0e0d1")
button_Read_STEP.place(relx=0.1,rely=(pos_y+pos_y_os),relwidth=0.8, relheight=0.1)
#World Size button
button_World_Size = tk.Button(button_menu, text = 'World Size', font=("Helvetica", int(12*p_w)), command = Pressed_World_Size,bg="#e0e0d1")
button_World_Size.place(relx=0.1,rely=(pos_y+pos_y_os*2),relwidth=0.8, relheight=0.1)
#offset button
button_offset = tk.Button(button_menu, text = 'Pos. offset', font=("Helvetica", int(12*p_w)), command = Pressed_offset,bg="#e0e0d1")
button_offset.place(relx=0.1,rely=(pos_y+pos_y_os*2),relwidth=0.8, relheight=0.1)
#Write GDML button
button_Write_GDML = tk.Button(button_menu, text = 'Write GDML',font=("Helvetica", int(12*p_w)), command = Pressed_Write_GDML,bg="#e0e0d1")
button_Write_GDML.place(relx=0.1,rely=(pos_y+pos_y_os*6),relwidth=0.8, relheight=0.1)
#Exit button
button_exit = tk.Button(button_menu, text = 'Exit Program',font=("Helvetica", int(12*p_w)), command = Pressed_Exit_Program,bg="#e0e0d1")
button_exit.place(relx=0.1,rely=(pos_y+pos_y_os*7),relwidth=0.8, relheight=0.1)
#####################################################################################
###################################Volume Lists######################################
#####################################################################################
frame_names = tk.Frame(lists_menu)
frame_names.place(relx=0.01, rely=0.02,relwidth=0.98,relheight=0.96)
scrollbar_names = tk.Scrollbar(frame_names)
scrollbar_names.pack( side = tk.RIGHT, fill = tk.Y )
mylist_names = tk.Listbox(frame_names, yscrollcommand = scrollbar_names.set,width=int(3000*p_w),height=int(3000*p_h),font=("Helvetica", int(12*p_w)))
mylist_names.pack( side = tk.LEFT, fill = tk.BOTH )
for i in range(len(list_of_names)):
mylist_names.insert(tk.END, str(i+1)+". "+str(list_of_names[i]))
scrollbar_names.config( command = mylist_names.yview )
mylist_names.bind('<<ListboxSelect>>', vol_info)
#####################################################################################
###############################Property Buttons######################################
#####################################################################################
#Label
empty_label = tk.Message( vol_properties_menu, text="",width=int(500),font=("Helvetica", 15),anchor='w',fg="black")
empty_label.place(relx=0.05,rely=0.05,relwidth=0.9,relheight=0.5)
#Set all variable
set_all_var = tk.IntVar()
set_all_var.set(0)
set_all_check_button = tk.Checkbutton(vol_properties_menu, text="Set All", font=("Helvetica", 16),variable=set_all_var)
set_all_check_button.place(relx=0.05,rely=0.9,relwidth=0.15,relheight=0.05)
#Change MMD
button_Change_MMD = tk.Button(vol_properties_menu, text = 'Change MMD',font=("Helvetica", int(12*p_w)), command = Pressed_Change_MMD,bg="#e0e0d1")
button_Change_MMD.place(relx=0.05,rely=0.7,relwidth=0.9, relheight=0.1)
#Change GDML Option
button_Change_GDML_Option = tk.Button(vol_properties_menu, text = 'Change GDML Option',font=("Helvetica", int(12*p_w)), command = Pressed_Change_GDML_Option,bg="#e0e0d1")
button_Change_GDML_Option.place(relx=0.05,rely=0.8,relwidth=0.9, relheight=0.1)
#####################################################################################
################################End of main loop#####################################
#####################################################################################
root.mainloop()