-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmultimesh_task_exec.py
156 lines (130 loc) · 6.8 KB
/
multimesh_task_exec.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
import os
import bpy
import matplotlib
import pymeshlab
import numpy as np
from scipy.ndimage import median
from optim.beam_recycle_net_optimizer import BeamRecycleNetOptimizer
from options.multimeshing_recycle_optimizer_options import MultimeshingRecycleOptimizerOptions
from utils.figure_utils import draw_curves, draw_histograms, find_min_max_deflections_energy, render_models, draw_structural_hists, render_all, render_all_wireframe, jpg_convert, scatter_plot
matplotlib.use('TKAgg')
# First stock: uniform
stock_u = [0, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 2, 2.5, 3]
stock_capacities_u = [float('inf'), 400, 400, 400, 400, 400, 400, 400, 400, 400]
stock_name_u = 'stock_uniform'
# Second stock: non-uniform 1
stock_nu1 = [0, 1.59, 1.93, 1.95, 1.99, 2.22, 2.77, 2.80, 2.94, 2.98, 3]
stock_capacities_nu1 = [float('inf'), 540, 54, 54, 180, 270, 252, 180, 117, 27, 90]
stock_name_nu1 = 'stock_nonuniform1'
# Third stock: non-uniform 2
stock_nu2 = [0, 1.59, 1.93, 1.95, 1.99, 2.22, 2.77, 2.80, 2.94, 2.98, 3]
stock_capacities_nu2 = [float('inf'), 200, 20, 20, 60, 110, 100, 65, 45, 5, 40]
stock_name_nu2 = 'stock_nonuniform2'
step = 0.1
no_steps = 5
# *** Auxiliary function for remeshing ***
def isotropic_remesh(input_mesh, target_lengths, save_prefix, mesh_name):
case_labels = []
for target_length in target_lengths:
ms = pymeshlab.MeshSet()
ms.load_new_mesh(input_mesh)
ms.meshing_isotropic_explicit_remeshing(iterations=30, targetlen=pymeshlab.PureValue(target_length), reprojectflag=False)
case_name = f"{mesh_name}_{target_length:.2f}"
output_mesh = case_name + ".ply"
case_labels.append(case_name)
ms.save_current_mesh(os.path.join(save_prefix, output_mesh))
print(f"Remeshing with target length {target_length:.1f} completed. Output saved as {output_mesh}")
return case_labels
#
#
#
#
#
### MAIN FUNCTION ###
if __name__ == '__main__':
# Parse optimizer options.
parser = MultimeshingRecycleOptimizerOptions()
options = parser.parse()
# Creating output folder (if it does not exist).
os.makedirs(options.output_name, exist_ok=True)
# Selecting stock.
if options.stock == 'uniform':
stock = stock_u
stock_capacities = stock_capacities_u
stock_name = stock_name_u
elif options.stock == 'nonuniform1':
stock = stock_nu1
stock_capacities = stock_capacities_nu1
stock_name = stock_name_nu1
elif options.stock == 'nonuniform2':
stock = stock_nu2
stock_capacities = stock_capacities_nu2
stock_name = stock_name_nu2
else:
raise ValueError("Invalid stock name. Choose 'uniform', 'nonuniform1', or 'nonuniform2'.")
# *** Creating different remeshing cases for the same shape. ***
# Isotropic remeshes with target lengths [stock_median - no_steps*step, ..., stock_median + no_steps*step]
#
# Step 1: computing the median of the stock.
stock_with_repetitions = []
for i in range(1, len(stock)):
stock_with_repetitions += stock_capacities[i] * [stock[i]]
stock_median = median(stock_with_repetitions)
# Step 2: making remeshing cases directory.
remeshing_cases_path = os.path.join(options.output_name, 'remeshing_cases')
os.makedirs(remeshing_cases_path)
# Step 3: creating remeshing cases.
input_mesh_path = options.path
mesh_name = os.path.splitext(os.path.basename(input_mesh_path))[0]
target_lengths = [stock_median + i * step for i in range(-no_steps, no_steps+1)]
case_labels = isotropic_remesh(input_mesh_path, target_lengths, remeshing_cases_path, mesh_name)
# else:
# case_labels = single_mesh_loading(input_mesh_path, remeshing_cases_path, mesh_name)
# *** Running the optimizer for each remeshing case. ***
matching_percentages = []
wastages = []
for label in case_labels:
# Creating a directory for the current remeshing case.
current_label_path = os.path.join(options.output_name, label) + '_' + stock_name
os.makedirs(current_label_path)
# Running the optimizer for the current remeshing case.
input_mesh_path = os.path.join(remeshing_cases_path, label + '.ply')
save_prefix = current_label_path + '/'
lo = BeamRecycleNetOptimizer(input_mesh_path, options.lr, options.device, options.reproducible, options.seed, stock, stock_capacities, times=options.times)
matching_percentage, waste = lo.optimize(options.n_iter, options.save, options.save_interval, label, save_prefix)
# Saving the peformane metrics.
matching_percentages.append(matching_percentage)
wastages.append(waste)
# *** Finding best cases according to the performance. ***
best_matching_idxs = np.flatnonzero(matching_percentages == np.max(matching_percentages))
wastages_of_best_matching = np.take(wastages, best_matching_idxs)
best_wastages_idx = np.flatnonzero(wastages_of_best_matching == np.min(wastages_of_best_matching))
best_matching_idxs = np.take(best_matching_idxs, best_wastages_idx)
result_string = f"Best matching cases: {', '.join([case_labels[idx] for idx in best_matching_idxs])} with matching percentages {', '.join([str(matching_percentages[idx]) for idx in best_matching_idxs])} and wastages {', '.join([str(wastages[idx]) for idx in best_matching_idxs])}"
f = open(os.path.join(options.output_name, 'performance_results.txt'), 'w')
f.write(result_string)
f.close()
# *** Plotting performance curves. ***
if options.curves:
draw_curves(options.output_name)
# *** Plotting the matching results through histograms. ***
if options.hists:
draw_histograms(options.output_name)
if options.hists and options.render_models:
# Finding min and max deflections and displacements for the color mapping.
vmin_energy, vmax_energy, cmax_energy, vmin_deflections, vmax_deflections, vmin_displacements, vmax_displacements, displacements_list, start_energy_list, end_energy_list, start_deflections_list, end_deflections_list = find_min_max_deflections_energy(options.output_name, options.device)
# ** Building ply models for rendering. **
if options.render_models:
render_models(options.output_name, vmin_deflections, vmax_deflections, vmin_displacements, vmax_displacements, displacements_list)
if options.struct_hists:
draw_structural_hists(options.output_name, options.device, vmin_energy, vmax_energy, cmax_energy, vmin_deflections, vmax_deflections, vmin_displacements, vmax_displacements)
# *** Rendering the results. ***
if options.render:
render_all(options.output_name)
if options.renderw:
render_all_wireframe(options.output_name)
if options.jpg:
jpg_convert(options.output_name)
# *** Scatter plot for the results. ***
if options.scatter:
scatter_plot(options.output_name, options.device)