Skip to content

Commit 7e0c61c

Browse files
committed
WIP-ADD restructure valuetype input and add all options
1 parent 32a1c94 commit 7e0c61c

File tree

6 files changed

+2789
-444
lines changed

6 files changed

+2789
-444
lines changed

src/gh/components/DF_cvs_exporter/code.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ def RunScript(self,
3333
# Define the CSV file path
3434
file_path = os.path.join(i_export_dir, 'exported_values.csv')
3535

36-
print(file_path)
37-
3836
# Write the values to the CSV file
3937
with open(file_path, mode='w', newline='') as file:
4038
writer = csv.writer(file)

src/gh/components/DF_vizualization/code.py

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,56 +20,31 @@ def RunScript(self,
2020
i_results,
2121
i_viz_settings):
2222
"""
23-
sth sth
23+
Adds color to the mesh or point cloud and generates a corresponding legend and histogram
2424
"""
2525

26-
27-
28-
distances_flattened = [item for sublist in i_results.distances for item in sublist]
29-
30-
if i_viz_settings.lower_threshold is not None:
31-
min_value = i_viz_settings.lower_threshold
32-
else:
33-
# filter min,max value based on type
34-
if i_viz_settings.valueType == "Dist":
35-
min_value = min(min(sublist) for sublist in i_results.distances)
36-
elif i_viz_settings.valueType == "MSE":
37-
min_value = min(i_results.distances_mse)
38-
39-
if i_viz_settings.upper_threshold is not None:
40-
max_value = i_viz_settings.upper_threshold
41-
else:
42-
if i_viz_settings.valueType == "Dist":
43-
max_value = max(max(sublist) for sublist in i_results.distances)
44-
elif i_viz_settings.valueType == "MSE":
45-
max_value = max(i_results.distances_mse)
26+
values, min_value, max_value = df_vizualization.filter_values_based_on_valuetype(i_results, i_viz_settings)
4627

4728
# check if i_results.source is a list of pointclouds or a mesh
4829
if type(i_results.source[0]) is diffcheck_bindings.dfb_geometry.DFPointCloud:
4930

5031
# convert to Rhino PCD
5132
o_source = [df_cvt_bindings.cvt_dfcloud_2_rhcloud(src) for src in i_results.source]
5233

53-
5434
# color geometry
55-
if i_viz_settings.valueType == "Dist":
56-
o_colored_geo = [df_vizualization.color_pcd(src, dist, min_value, max_value, i_viz_settings) for src, dist in zip(o_source, i_results.distances)]
57-
elif i_viz_settings.valueType == "MSE":
58-
o_colored_geo = [df_vizualization.color_pcd(src, [dist], min_value, max_value, i_viz_settings) for src, dist in zip(o_source, i_results.distances_mse)]
35+
o_colored_geo = [df_vizualization.color_pcd(src, dist, min_value, max_value, i_viz_settings) for src, dist in zip(o_source, values)]
36+
5937

6038
elif type(i_results.source[0]) is rg.Mesh:
6139
# convert to Rhino Mesh
6240
o_source = i_results.source
6341

6442
# color geometry
65-
if i_viz_settings.valueType == "Dist":
66-
o_colored_geo = [df_vizualization.color_mesh(src, dist, min_value, max_value, i_viz_settings) for src, dist in zip(o_source, i_results.distances)]
67-
elif i_viz_settings.valueType == "MSE":
68-
o_colored_geo = [df_vizualization.color_mesh(src, [dist], min_value, max_value, i_viz_settings) for src, dist in zip(o_source, i_results.distances_mse)]
43+
o_colored_geo = [df_vizualization.color_mesh(src, dist, min_value, max_value, i_viz_settings) for src, dist in zip(o_source, values)]
6944

7045
o_legend = df_vizualization.create_legend(min_value, max_value, i_viz_settings)
7146

72-
o_histogram = df_vizualization.create_histogram(distances_flattened, min_value, max_value)
47+
o_histogram = df_vizualization.create_histogram(values, min_value, max_value)
7348

7449
return o_source, o_colored_geo, o_legend, o_histogram
7550

src/gh/components/DF_vizualization_settings/code.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,24 @@ def RunScript(self,
2121
i_value_type,
2222
i_upper_threshold,
2323
i_lower_threshold,
24-
i_palette):
24+
i_palette,
25+
i_legend_height,
26+
i_legend_width,
27+
i_legend_plane,
28+
i_histogram_scale_factor):
2529
"""
2630
sth
2731
"""
2832

2933
# pack settings
30-
o_viz_settings = df_vizualization.DFVizSettings(i_value_type, i_upper_threshold, i_lower_threshold, i_palette)
34+
o_viz_settings = df_vizualization.DFVizSettings(i_value_type,
35+
i_upper_threshold,
36+
i_lower_threshold,
37+
i_palette,
38+
i_legend_height,
39+
i_legend_width,
40+
i_legend_plane,
41+
i_histogram_scale_factor)
3142

3243
return o_viz_settings
3344

@@ -37,5 +48,9 @@ def RunScript(self,
3748
i_value_type,
3849
i_upper_threshold,
3950
i_lower_threshold,
40-
i_palette
51+
i_palette,
52+
i_legend_height,
53+
i_legend_width,
54+
i_legend_plane,
55+
i_histogram_scale_factor
4156
)

src/gh/diffCheck/diffCheck/df_error_estimation.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def rhino_mesh_2_cloud_distance(source, target, signed=False):
7777
distances = np.asarray(df_pcd_from_mesh_vertices.compute_distance(target))
7878

7979
if signed:
80-
for p in target.points:
80+
for idx, p in enumerate(source.Vertices):
8181

8282
rhp = rg.Point3d(p[0], p[1], p[2])
8383
closest_meshPoint = source.ClosestMeshPoint(rhp, 1000)
@@ -89,7 +89,7 @@ def rhino_mesh_2_cloud_distance(source, target, signed=False):
8989
normal = source.NormalAt(closest_meshPoint)
9090
dot_product = direction * normal
9191
if dot_product < 0:
92-
distance = - distance
92+
distances[idx] = - distance
9393

9494
return np.asarray(distances)
9595

src/gh/diffCheck/diffCheck/df_vizualization.py

Lines changed: 96 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,23 @@ class DFVizSettings:
1212
This class compiles the settings for the vizualization into one object
1313
"""
1414

15-
def __init__(self, valueType, upper_threshold, lower_threshold, palette):
15+
def __init__(self, valueType, upper_threshold, lower_threshold, palette, legend_height, legend_width, legend_plane, histogram_scale_factor):
1616

1717
self.valueType = valueType
1818

1919
self.upper_threshold = upper_threshold
2020
self.lower_threshold = lower_threshold
2121
self.palette = df_vizualization.DFColorMap(palette)
22+
self.legend_height = legend_height
23+
self.legend_width = legend_width
24+
self.legend_plane = legend_plane
25+
self.histogram_scale_factor = histogram_scale_factor
2226

2327

2428
class DFColorMap:
2529
"""
26-
This class compiles the settings for the vizualization into one object
30+
This class defines different colormaps for visualization purposes
31+
It allows selection of a colormap by name and initializes the corresponding color values.
2732
"""
2833

2934
def __init__(self, name):
@@ -62,7 +67,9 @@ def __init__(self, name):
6267
]
6368

6469
def interpolate_color(color1, color2, t):
65-
"""Interpolate between two colors."""
70+
"""
71+
Interpolate between two colors.
72+
"""
6673

6774
r = int(color1.R + (color2.R - color1.R) * t)
6875
g = int(color1.G + (color2.G - color1.G) * t)
@@ -71,14 +78,15 @@ def interpolate_color(color1, color2, t):
7178

7279

7380
def value_to_color(value, min_value, max_value, settings):
74-
"""Map a value to a color based on a spectral colormap."""
81+
"""
82+
Map a value to a color based on a colormap.
83+
"""
7584

7685
if value < min_value:
7786
value = min_value
7887
elif value > max_value:
7988
value = max_value
8089

81-
# Define the spectral colormap (simplified)
8290
colormap = settings.palette.colors
8391

8492
# Normalize the value within the range
@@ -88,7 +96,7 @@ def value_to_color(value, min_value, max_value, settings):
8896
t = (value - min_value) / (max_value - min_value)
8997

9098
# Determine the segment in the colormap
91-
n = len(colormap)-1
99+
n = len(colormap)- 1
92100
idx = int(t * n)
93101
if idx >= n:
94102
idx = n - 1
@@ -102,45 +110,47 @@ def value_to_color(value, min_value, max_value, settings):
102110

103111

104112
def color_pcd(pcd, values, min_value, max_value, settings):
113+
"""
114+
Colors a point cloud data based on given values and palette.
115+
"""
105116

106117
for i, p in enumerate(pcd):
107-
if len(values) > 1:
118+
# check if values is a list
119+
if isinstance(values, list):
108120
mapped_color = value_to_color(values[i], min_value, max_value, settings)
109121
else:
110-
mapped_color = value_to_color(values[0], min_value, max_value, settings)
122+
mapped_color = value_to_color(values, min_value, max_value, settings)
111123

112124
p.Color = mapped_color
125+
113126
return pcd
114127

115128

116129
def color_mesh(mesh, values, min_value, max_value, settings):
130+
"""
131+
Colors a mesh based on given values and palette.
132+
"""
133+
117134
mesh.VertexColors.Clear()
135+
118136
for i, vertex in enumerate(mesh.Vertices):
119-
# check the settings.
120-
if len(values) > 1:
137+
# check if values is a list
138+
if isinstance(values, list):
121139
mapped_color = value_to_color(values[i], min_value, max_value, settings)
122140
else:
123-
mapped_color = value_to_color(values[i], min_value, max_value, settings)
141+
mapped_color = value_to_color(values, min_value, max_value, settings)
124142
mesh.VertexColors.Add(mapped_color.R, mapped_color.G, mapped_color.B)
125143

126144
return mesh
127145

128146

129-
def create_legend(min_value, max_value, settings, steps=10, base_point=rg.Point3d(0, 0, 0),
130-
width=0.5, height=1, spacing=0):
147+
def create_legend(min_value, max_value, settings, steps=10, plane = rg.Plane.WorldXY,
148+
width=0.5, total_height=10, spacing=0):
131149
"""
132150
Create a legend in Rhino with colored hatches and text labels.
133-
134-
Parameters:
135-
min_value (float): Minimum value for the legend.
136-
max_value (float): Maximum value for the legend.
137-
steps (int): Number of steps in the legend.
138-
base_point (rg.Point3d): The base point where the legend starts.
139-
width (float): Width of each rectangle.
140-
height (float): Height of each rectangle.
141-
spacing (float): Spacing between rectangles.
142151
"""
143-
x, y, z = base_point.X, base_point.Y, base_point.Z
152+
153+
height = total_height/steps
144154

145155
legend_geometry = []
146156

@@ -166,38 +176,35 @@ def create_legend(min_value, max_value, settings, steps=10, base_point=rg.Point3
166176
legend_geometry.append(mesh)
167177
legend_geometry.append(polyline.ToPolylineCurve())
168178

169-
text_pt = rg.Point3d(x + 1.25 * width + spacing, y + i * (height + spacing) + height / 10, z)
179+
text_pt = rg.Point3d(1.25 * width + spacing, i * (height + spacing) + height / 10, 0)
170180
text_entity = rg.TextEntity()
171181
text_entity.Plane = rg.Plane(text_pt, rg.Vector3d.ZAxis)
172182
text_entity.Text = f"{value:.2f}"
173183
text_entity.TextHeight = height / 5
174184
legend_geometry.append(text_entity)
175185

176186
rect_pts = [
177-
rg.Point3d(x, y + i * (height + spacing), z),
178-
rg.Point3d(x + width, y + i * (height + spacing), z),
179-
rg.Point3d(x + width, y + (i + 1) * height + i * spacing, z),
180-
rg.Point3d(x, y + (i + 1) * height + i * spacing, z),
187+
rg.Point3d(0, i * (height + spacing), 0),
188+
rg.Point3d(0 + width, i * (height + spacing), 0),
189+
rg.Point3d(0 + width, (i + 1) * height + i * spacing, 0),
190+
rg.Point3d(0, (i + 1) * height + i * spacing, 0),
181191
]
182192

183193
previous_color = color
184194

195+
if plane != rg.Plane.WorldXY:
196+
trans = rg.Transform.PlaneToPlane(rg.Plane.WorldXY,plane)
197+
for geo in legend_geometry:
198+
geo.Transform(trans)
199+
185200
return legend_geometry
186201

187202

188-
def create_histogram(values, min_value, max_value, steps=100, base_point=rg.Point3d(0, 0, 0), height=0.1, spacing=0):
203+
def create_histogram(values, min_value, max_value, steps=100, plane=rg.Plane.WorldXY, height=0.1, spacing=0):
189204
"""
190205
Create a histogram in Rhino with a polyline representing value frequencies.
191-
192-
Parameters:
193-
values (list of float): List of values to calculate the histogram.
194-
min_value (float): Minimum value for the histogram.
195-
max_value (float): Maximum value for the histogram.
196-
steps (int): Number of steps in the histogram.
197-
base_point (rg.Point3d): The base point where the histogram starts.
198-
height (float): Height of each bin in the histogram.
199-
spacing (float): Spacing between bins.
200206
"""
207+
201208
histogram_geometry = []
202209

203210
# Calculate the size of each bin
@@ -206,6 +213,10 @@ def create_histogram(values, min_value, max_value, steps=100, base_point=rg.Poin
206213
# Initialize the frequency counts for each bin
207214
frequencies = [0] * (steps + 1)
208215

216+
# if values is nested list, flatten it
217+
if isinstance(values[0], list):
218+
values = [item for sublist in values for item in sublist]
219+
209220
# Count the frequencies of values in each bin
210221
for value in values:
211222
if value < min_value:
@@ -216,17 +227,61 @@ def create_histogram(values, min_value, max_value, steps=100, base_point=rg.Poin
216227
bin_index = int(bin_index)
217228
frequencies[bin_index] += 1
218229

219-
x, y, z = base_point.X, base_point.Y, base_point.Z
220-
221230
# Create points for the polyline representing the histogram
222231
points = []
223232
for i in range(steps+1):
224233

225234
bar_height = frequencies[i] * 0.01 * height
226-
points.append(rg.Point3d(x - bar_height - 0.15 , y + i * (spacing + height), z))
235+
points.append(rg.Point3d(- bar_height - (1.5 * height), i * (spacing + height), 0))
227236

228237
# Create the polyline and add it to the histogram geometry
229238
polyline = rg.Curve.CreateInterpolatedCurve(points, 1)
230239
histogram_geometry.append(polyline)
231240

241+
if plane != rg.Plane.WorldXY:
242+
trans = rg.Transform.PlaneToPlane(rg.Plane.WorldXY, plane)
243+
for geo in histogram_geometry:
244+
geo.Transform(trans)
245+
232246
return histogram_geometry
247+
248+
249+
def filter_values_based_on_valuetype(results, settings):
250+
251+
if settings.valueType == "Dist":
252+
253+
min_value = min(min(sublist) for sublist in results.distances)
254+
max_value = max(max(sublist) for sublist in results.distances)
255+
values = results.distances
256+
257+
elif settings.valueType == "MSE":
258+
259+
values = results.distances_mse
260+
min_value = min(values)
261+
max_value = max(values)
262+
263+
elif settings.valueType == "MAX":
264+
265+
values = results.distances_max_deviation
266+
min_value = min(values)
267+
max_value = max(values)
268+
269+
elif settings.valueType == "MIN":
270+
values = results.distances_min_deviation
271+
min_value = min(values)
272+
max_value = max(values)
273+
274+
elif settings.valueType == "STD":
275+
276+
values = results.distances_sd_deviation
277+
min_value = min(values)
278+
max_value = max(values)
279+
280+
281+
# threshold values
282+
if settings.lower_threshold is not None:
283+
min_value = settings.lower_threshold
284+
if settings.upper_threshold is not None:
285+
max_value = settings.upper_threshold
286+
287+
return values, min_value, max_value

0 commit comments

Comments
 (0)