@@ -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
2428class 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
6469def 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
7380def 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
104112def 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
116129def 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