1
1
"""Method to translate a Color Room/Face objects to a VisualizationSet."""
2
2
import math
3
3
4
- from ladybug_geometry .geometry3d import Vector3D , Plane
4
+ from ladybug_geometry .geometry3d import Vector3D , Point3D , Polyline3D , Plane , \
5
+ Face3D , Polyface3D
5
6
from ladybug_display .geometry3d import DisplayLineSegment3D , DisplayText3D
6
7
from ladybug_display .visualization import VisualizationSet , ContextGeometry , \
7
8
AnalysisGeometry , VisualizationData
8
9
10
+ from honeybee .units import conversion_factor_to_meters
11
+ from honeybee .facetype import Floor
9
12
from honeybee .face import Face
10
13
11
14
12
- def color_room_to_vis_set (color_room , include_wireframe = True , text_labels = False ):
15
+ def color_room_to_vis_set (
16
+ color_room , include_wireframe = True , text_labels = False ,
17
+ units = None , tolerance = 0.01 ):
13
18
"""Translate a Honeybee ColorRoom to a VisualizationSet.
14
19
15
20
Args:
@@ -19,6 +24,11 @@ def color_room_to_vis_set(color_room, include_wireframe=True, text_labels=False)
19
24
text_labels: A boolean to note whether the attribute assigned to the
20
25
ColorRoom should be expressed as a colored AnalysisGeometry (False)
21
26
or a ContextGeometry as text labels (True). (Default: False).
27
+ units: Optional text, which will be used to set the default maximum text
28
+ height and the distance of the text to the ground. If None, some
29
+ generic defaults will be used. (Default: None).
30
+ tolerance: Tolerance value, which is used to compute the text
31
+ label point for concave geometries. (Default: 0.01).
22
32
23
33
Returns:
24
34
A VisualizationSet object that represents the ColorRoom with an
@@ -34,19 +44,51 @@ def color_room_to_vis_set(color_room, include_wireframe=True, text_labels=False)
34
44
# use text labels if requested
35
45
if text_labels :
36
46
# set up default variables
47
+ max_txt_h = float ('inf' )
48
+ if units is not None :
49
+ fac_to_m = conversion_factor_to_meters (units )
50
+ max_txt_h = 0.25 / fac_to_m
51
+ max_txt_v = 1.0 / fac_to_m
37
52
label_text = []
38
53
txt_height = None if color_room .legend_parameters .is_text_height_default \
39
54
else color_room .legend_parameters .text_height
40
55
font = color_room .legend_parameters .font
41
56
# loop through the rooms and create the text labels
42
57
for room_prop , room in zip (color_room .attributes , color_room .rooms ):
43
- cent_pt = room .geometry .center # base point for the text
44
- base_plane = Plane (Vector3D (0 , 0 , 1 ), cent_pt )
58
+ # compute the center point for the text
59
+ if units is not None :
60
+ room_h = room .geometry .max .z - room .geometry .min .z
61
+ m_vec = Vector3D (0 , 0 , max_txt_v ) if room_h > max_txt_v * 2 \
62
+ else Vector3D (0 , 0 , room_h / 2 )
63
+ floor_faces = [face .geometry for face in room .faces
64
+ if isinstance (face .type , Floor )]
65
+ if len (floor_faces ) == 1 :
66
+ flr_geo = floor_faces [0 ]
67
+ base_pt = flr_geo .center if flr_geo .is_convex else \
68
+ flr_geo .pole_of_inaccessibility (tolerance )
69
+ elif len (floor_faces ) == 0 :
70
+ c_pt = room .geometry .center
71
+ base_pt = Point3D (c_pt .x , c_pt .y , room .geometry .min .z )
72
+ else :
73
+ floor_p_face = Polyface3D .from_faces (floor_faces , tolerance )
74
+ ne = floor_p_face .naked_edges
75
+ floor_outline = Polyline3D .join_segments (ne , tolerance )[0 ]
76
+ flr_geo = Face3D (floor_outline .vertices [:- 1 ])
77
+ base_pt = flr_geo .center if flr_geo .is_convex else \
78
+ flr_geo .pole_of_inaccessibility (tolerance )
79
+ base_pt = base_pt .move (m_vec )
80
+ base_plane = Plane (Vector3D (0 , 0 , 1 ), base_pt )
81
+ else :
82
+ base_pt = room .geometry .center
83
+ base_plane = Plane (Vector3D (0 , 0 , 1 ), base_pt )
84
+ # get the text height
45
85
if txt_height is None : # auto-calculate default text height
46
86
txt_len = len (room_prop ) if len (room_prop ) > 10 else 10
47
87
txt_h = (room .geometry .max .x - room .geometry .min .x ) / txt_len
48
88
else :
49
89
txt_h = txt_height
90
+ txt_h = max_txt_h if txt_h > max_txt_h else txt_h
91
+ # create the text label
50
92
label = DisplayText3D (
51
93
room_prop , base_plane , txt_h , font = font ,
52
94
horizontal_alignment = 'Center' , vertical_alignment = 'Middle' )
@@ -78,7 +120,9 @@ def color_room_to_vis_set(color_room, include_wireframe=True, text_labels=False)
78
120
return vis_set
79
121
80
122
81
- def color_face_to_vis_set (color_face , include_wireframe = True , text_labels = False ):
123
+ def color_face_to_vis_set (
124
+ color_face , include_wireframe = True , text_labels = False ,
125
+ units = None , tolerance = 0.01 ):
82
126
"""Translate a Honeybee ColorFace to a VisualizationSet.
83
127
84
128
Args:
@@ -88,6 +132,11 @@ def color_face_to_vis_set(color_face, include_wireframe=True, text_labels=False)
88
132
text_labels: A boolean to note whether the attribute assigned to the
89
133
ColorFace should be expressed as a colored AnalysisGeometry (False)
90
134
or a ContextGeometry as text labels (True). (Default: False).
135
+ units: Optional text, which will be used to set the default maximum text
136
+ height and the distance of the text to the ground. If None, some
137
+ generic defaults will be used. (Default: None).
138
+ tolerance: Tolerance value, which is used to eliminate very small
139
+ text. (Default: 0.01).
91
140
92
141
Returns:
93
142
A VisualizationSet object that represents the ColorFace with an
@@ -103,6 +152,10 @@ def color_face_to_vis_set(color_face, include_wireframe=True, text_labels=False)
103
152
# use text labels if requested
104
153
if text_labels :
105
154
# set up default variables
155
+ max_txt_h = float ('inf' )
156
+ if units is not None :
157
+ fac_to_m = conversion_factor_to_meters (units )
158
+ max_txt_h = 0.25 / fac_to_m
106
159
label_text = []
107
160
txt_height = None if color_face .legend_parameters .is_text_height_default \
108
161
else color_face .legend_parameters .text_height
@@ -116,11 +169,17 @@ def color_face_to_vis_set(color_face, include_wireframe=True, text_labels=False)
116
169
base_plane = base_plane .rotate (base_plane .n , math .pi , base_plane .o )
117
170
if txt_height is None : # auto-calculate default text height
118
171
txt_len = len (face_prop ) if len (face_prop ) > 10 else 10
119
- largest_dim = max (
120
- (f_geo .max .x - f_geo .min .x ), (f_geo .max .y - f_geo .min .y ))
121
- txt_h = largest_dim / (txt_len * 2 )
172
+ dims = [
173
+ (f_geo .max .x - f_geo .min .x ),
174
+ (f_geo .max .y - f_geo .min .y ),
175
+ (f_geo .max .z - f_geo .min .z )]
176
+ dims .sort ()
177
+ txt_h = dims [1 ] / (txt_len * 1.5 )
122
178
else :
123
179
txt_h = txt_height
180
+ if txt_h < tolerance :
181
+ continue
182
+ txt_h = max_txt_h if txt_h > max_txt_h else txt_h
124
183
# move base plane origin a little to avoid overlaps of adjacent labels
125
184
if base_plane .n .x != 0 :
126
185
m_vec = base_plane .y if base_plane .n .x < 0 else - base_plane .y
0 commit comments