Skip to content

Commit b97817a

Browse files
committed
WIP-FIX legend display to smooth. fixed steps to correct number
1 parent 74b2fec commit b97817a

File tree

3 files changed

+6319
-4636
lines changed

3 files changed

+6319
-4636
lines changed

src/gh/components/DF_vizualization/code.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ def RunScript(self,
3434
o_source = [df_cvt_bindings.cvt_dfcloud_2_rhcloud(src) for src in i_results.source]
3535

3636
# by default we color the target
37+
distances_flattened = [item for sublist in i_results.distances for item in sublist]
3738
min_value = min(min(sublist) for sublist in i_results.distances)
3839
max_value = max(max(sublist) for sublist in i_results.distances)
3940

@@ -42,13 +43,15 @@ def RunScript(self,
4243
o_target = [df_cvt_bindings.cvt_dfcloud_2_rhcloud(trg) for trg in i_results.target]
4344

4445
o_legend = df_vizualization.create_legend(min_value, max_value)
46+
47+
o_histogram = df_vizualization.create_histogram(distances_flattened, min_value, max_value)
4548

46-
return o_source, o_target, o_legend
49+
return o_source, o_target, o_legend, o_histogram
4750

4851

4952
if __name__ == "__main__":
5053
com = Vizualization()
51-
o_source, o_target, o_legend, = com.RunScript(
54+
o_source, o_target, o_legend, o_histogram = com.RunScript(
5255
i_results,
5356
i_viz_settings
5457
)

src/gh/diffCheck/diffCheck/df_vizualization.py

Lines changed: 92 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
This module contains the utility functions to vizualize differences
44
"""
55

6-
import numpy as np
7-
import open3d as o3d
8-
from diffCheck import diffcheck_bindings
96
import Rhino.Geometry as rg
10-
import System.Drawing
7+
from System.Drawing import Color
8+
119

1210
class DFVizSettings:
1311
"""
1412
This class compiles the settings for the vizualization into one object
1513
"""
1614

17-
def __init__(self, source_valueType, target_valueType, upper_threshold, lower_threshold, palette):
15+
def __init__(self, source_valueType, target_valueType, upper_threshold,
16+
lower_threshold, palette):
1817

1918
self.source_valueType = source_valueType
2019
self.target_valueType = target_valueType
@@ -30,20 +29,19 @@ def interpolate_color(color1, color2, t):
3029
r = int(color1.R + (color2.R - color1.R) * t)
3130
g = int(color1.G + (color2.G - color1.G) * t)
3231
b = int(color1.B + (color2.B - color1.B) * t)
33-
return System.Drawing.Color.FromArgb(r, g, b)
32+
return Color.FromArgb(r, g, b)
3433

3534

3635
def value_to_color(value, min_value, max_value):
3736
"""Map a value to a color based on a spectral colormap."""
3837

3938
# Define the spectral colormap (simplified)
4039
colormap = [
41-
System.Drawing.Color.FromArgb(0, 0, 255), # Blue
42-
System.Drawing.Color.FromArgb(0, 255, 255), # Cyan
43-
System.Drawing.Color.FromArgb(0, 255, 0), # Green
44-
System.Drawing.Color.FromArgb(255, 255, 0), # Yellow
45-
System.Drawing.Color.FromArgb(255, 0, 0), # Red
46-
System.Drawing.Color.FromArgb(255, 0, 255) # Magenta
40+
Color.FromArgb(0, 0, 255), # Blue
41+
Color.FromArgb(0, 255, 255), # Cyan
42+
Color.FromArgb(0, 255, 0), # Green
43+
Color.FromArgb(255, 255, 0), # Yellow
44+
Color.FromArgb(255, 0, 0), # Red
4745
]
4846

4947
# Normalize the value within the range
@@ -53,7 +51,7 @@ def value_to_color(value, min_value, max_value):
5351
t = (value - min_value) / (max_value - min_value)
5452

5553
# Determine the segment in the colormap
56-
n = len(colormap) - 1
54+
n = len(colormap)-1
5755
idx = int(t * n)
5856
if idx >= n:
5957
idx = n - 1
@@ -74,10 +72,11 @@ def color_pcd(pcd, values, min_value, max_values):
7472
return pcd
7573

7674

77-
def create_legend(min_value, max_value, steps=10, base_point=rg.Point3d(0, 0, 0), width=0.5, height=1, spacing=0):
75+
def create_legend(min_value, max_value, steps=10, base_point=rg.Point3d(0, 0, 0),
76+
width=0.5, height=1, spacing=0):
7877
"""
7978
Create a legend in Rhino with colored hatches and text labels.
80-
79+
8180
Parameters:
8281
min_value (float): Minimum value for the legend.
8382
max_value (float): Maximum value for the legend.
@@ -88,38 +87,93 @@ def create_legend(min_value, max_value, steps=10, base_point=rg.Point3d(0, 0, 0)
8887
spacing (float): Spacing between rectangles.
8988
"""
9089
x, y, z = base_point.X, base_point.Y, base_point.Z
91-
90+
9291
legend_geometry = []
9392

94-
for i in range(steps + 1):
93+
for i in range(steps+1):
94+
9595
value = min_value + (max_value - min_value) * i / steps
9696
color = value_to_color(value, min_value, max_value)
97-
97+
98+
if i > 0:
99+
mesh = rg.Mesh()
100+
for pt in rect_pts:
101+
mesh.Vertices.Add(pt)
102+
# color mesh
103+
mesh.Faces.AddFace(0, 1, 2, 3)
104+
105+
mesh.VertexColors.Add(previous_color.R, previous_color.G, previous_color.B)
106+
mesh.VertexColors.Add(previous_color.R, previous_color.G, previous_color.B)
107+
mesh.VertexColors.Add(color.R, color.G, color.B)
108+
mesh.VertexColors.Add(color.R, color.G, color.B)
109+
mesh.VertexColors.Add(color.R, color.G, color.B)
110+
111+
112+
polyline = rg.Polyline(rect_pts)
113+
114+
legend_geometry.append(mesh)
115+
# legend_geometry.append(polyline.ToPolylineCurve())
116+
117+
text_pt = rg.Point3d(x + 1.25 * width + spacing, y + i * (height + spacing) + height / 10, z)
118+
text_entity = rg.TextEntity()
119+
text_entity.Plane = rg.Plane(text_pt, rg.Vector3d.ZAxis)
120+
text_entity.Text = f"{value:.2f}"
121+
text_entity.TextHeight = height / 5
122+
legend_geometry.append(text_entity)
123+
98124
rect_pts = [
99125
rg.Point3d(x, y + i * (height + spacing), z),
100126
rg.Point3d(x + width, y + i * (height + spacing), z),
101127
rg.Point3d(x + width, y + (i + 1) * height + i * spacing, z),
102128
rg.Point3d(x, y + (i + 1) * height + i * spacing, z),
103-
rg.Point3d(x, y + i * (height + spacing), z)
104129
]
105-
106-
mesh = rg.Mesh()
107-
for pt in rect_pts:
108-
mesh.Vertices.Add(pt)
109-
mesh.Faces.AddFace(0, 1, 2, 3)
110-
mesh.VertexColors.CreateMonotoneMesh(color)
111130

112-
polyline = rg.Polyline(rect_pts)
113-
114-
legend_geometry.append(mesh)
115-
116-
legend_geometry.append(polyline.ToPolylineCurve())
131+
previous_color = color
132+
133+
return legend_geometry
134+
135+
136+
def create_histogram(values, min_value, max_value, steps=10, base_point=rg.Point3d(0,0,0), height=0.1, spacing=0.1):
137+
"""
138+
Create a histogram in Rhino with a polyline representing value frequencies.
139+
140+
Parameters:
141+
values (list of float): List of values to calculate the histogram.
142+
min_value (float): Minimum value for the histogram.
143+
max_value (float): Maximum value for the histogram.
144+
steps (int): Number of steps in the histogram.
145+
base_point (rg.Point3d): The base point where the histogram starts.
146+
height (float): Height of each bin in the histogram.
147+
spacing (float): Spacing between bins.
148+
"""
149+
histogram_geometry = []
150+
151+
# Calculate the size of each bin
152+
bin_size = (max_value - min_value) / steps
153+
154+
# Initialize the frequency counts for each bin
155+
frequencies = [0] * (steps + 1)
156+
157+
# Count the frequencies of values in each bin
158+
for value in values:
159+
if min_value <= value and value <= max_value:
160+
bin_index = (value - min_value) // bin_size
161+
bin_index = int(bin_index)
162+
if bin_index == steps:
163+
bin_index -= 1
164+
frequencies[bin_index] += 1
165+
166+
x, y, z = base_point.X, base_point.Y, base_point.Z
167+
168+
# Create points for the polyline representing the histogram
169+
points = [rg.Point3d(x, y, z)]
170+
for i in range(int(steps)):
117171

118-
text_pt = rg.Point3d(x + width + spacing, y + i * (height + spacing) + height / 2, z)
119-
text_entity = rg.TextEntity()
120-
text_entity.Plane = rg.Plane(text_pt, rg.Vector3d.ZAxis)
121-
text_entity.Text = f"{value:.2f}"
122-
text_entity.TextHeight = height / 2
123-
legend_geometry.append(text_entity)
124-
125-
return legend_geometry
172+
bar_height = frequencies[i] * height
173+
points.append(rg.Point3d(x + bar_height, y + i * (spacing + height), z))
174+
points.append(rg.Point3d(x, y + (i + 1) * (spacing + height), z))
175+
# Create the polyline and add it to the histogram geometry
176+
polyline = rg.Polyline(points)
177+
histogram_geometry.append(points)
178+
179+
return histogram_geometry

0 commit comments

Comments
 (0)