Coverage for bim2sim/plugins/PluginOpenFOAM/bim2sim_openfoam/openfoam_elements/furniture.py: 0%

106 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2025-10-01 10:24 +0000

1import logging 

2import math 

3 

4from OCC.Core.gp import gp_Pnt 

5 

6from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam.openfoam_elements.openfoam_base_boundary_conditions import \ 

7 OpenFOAMBaseBoundaryFields 

8from bim2sim.plugins.PluginOpenFOAM.bim2sim_openfoam.openfoam_elements.openfoam_base_element import \ 

9 OpenFOAMBaseElement 

10from bim2sim.utilities.pyocc_tools import PyOCCTools 

11 

12logger = logging.getLogger(__name__) 

13 

14 

15class Furniture(OpenFOAMBaseBoundaryFields, OpenFOAMBaseElement): 

16 def __init__(self, shape, triSurface_path, furniture_type, 

17 bbox_min_max=None, solid_name='furniture', 

18 increase_small_refinement=0.10, 

19 increase_large_refinement=0.20): 

20 super().__init__() 

21 self.solid_name = solid_name + '_' + furniture_type 

22 self.stl_name = self.solid_name + '.stl' 

23 self.stl_file_path_name = (triSurface_path.as_posix() + '/' + 

24 self.stl_name) 

25 self.bbox_min_max = bbox_min_max 

26 self.patch_info_type = 'wall' 

27 self.refinement_level = [2, 3] 

28 self.tri_geom = PyOCCTools.triangulate_bound_shape(shape) 

29 self.point_in_shape = PyOCCTools.get_center_of_volume(self.tri_geom) 

30 if not bbox_min_max: 

31 self.bbox_min_max = PyOCCTools.simple_bounding_box(shape) 

32 

33 # self.refinement_zone_small = [] 

34 # self.refinement_zone_small.append([c - increase_small_refinement for c 

35 # in self.bbox_min_max[0]]) 

36 # self.refinement_zone_small.append([c + increase_small_refinement for c 

37 # in self.bbox_min_max[1]]) 

38 # self.refinement_zone_level_small = [0, 

39 # self.refinement_level[0]] 

40 # self.refinement_zone_large = [] 

41 # self.refinement_zone_large.append( 

42 # [c - increase_large_refinement for c in 

43 # self.bbox_min_max[0]]) 

44 # self.refinement_zone_large.append( 

45 # [c + increase_large_refinement for c in 

46 # self.bbox_min_max[1]]) 

47 # self.refinement_zone_level_large = [0, 

48 # self.refinement_level[0]-1] 

49 

50 def set_boundary_conditions(self): 

51 pass 

52 

53 

54class Table(Furniture): 

55 def __init__(self, furniture_setting, shape, triSurface_path, 

56 furniture_type, 

57 bbox_min_max=None, solid_name='furniture', 

58 chair_bbox_min_max=None, 

59 increase_small_refinement=0.10, 

60 increase_large_refinement=0.20): 

61 super().__init__(shape, triSurface_path, furniture_type, 

62 bbox_min_max, solid_name, 

63 increase_small_refinement, 

64 increase_large_refinement) 

65 self.furniture_type = furniture_type 

66 self.chair_trsfs = [] 

67 self.chair_locations = [] 

68 self.furniture_setting = furniture_setting 

69 self.width = bbox_min_max[1][0] - bbox_min_max[0][0] 

70 self.depth = bbox_min_max[1][1] - bbox_min_max[0][1] 

71 self.height = bbox_min_max[1][2] - bbox_min_max[0][2] 

72 chair_width = chair_bbox_min_max[1][0] - chair_bbox_min_max[0][0] 

73 chair_depth = chair_bbox_min_max[1][1] - chair_bbox_min_max[0][1] 

74 self.chair_locations, self.chair_trsfs = self.get_local_chair_positions( 

75 self.furniture_setting, self.bbox_min_max, self.width, 

76 self.depth, chair_bbox_min_max, chair_width, chair_depth) 

77 

78 def get_local_chair_positions(self, furniture_setting, table_bbox_min_max, 

79 table_width, table_depth, 

80 chair_bbox_min_max, chair_width, chair_depth): 

81 distance_y_chair_to_table = chair_depth 

82 

83 org_chair_pos = gp_Pnt(*chair_bbox_min_max[0]) 

84 z_pos = table_bbox_min_max[0][2] 

85 chair_pnts = [] 

86 chair_trsfs = [] 

87 

88 if furniture_setting == 'Office': 

89 min_width = 1.20 

90 if table_width < min_width: 

91 logger.warning( 

92 f"Width (={table_width}m of table is too small for " 

93 f"furniture setting {furniture_setting}. " 

94 f"Minimum width of {min_width}m is required. " 

95 f"Resulting position does not comply with " 

96 f"standards.") 

97 x_pos = table_bbox_min_max[0][0] + table_width / 2 - chair_width / 2 

98 y_pos = table_bbox_min_max[0][1] - distance_y_chair_to_table 

99 chair_pnts.append(gp_Pnt(x_pos, y_pos, z_pos)) 

100 chair_trsfs += PyOCCTools.generate_obj_trsfs(chair_pnts, 

101 org_chair_pos) 

102 

103 elif furniture_setting in ['Classroom', 'TwoSideTable', 'GroupTable']: 

104 chair_pnts0 = [] 

105 min_width = 0.6 

106 if table_width < min_width: 

107 logger.warning( 

108 f"Width (={table_width}m of table is too small for " 

109 f"furniture setting {furniture_setting}. " 

110 f"Minimum width of {min_width}m is required. " 

111 f"Resulting position does not comply with " 

112 f"standards.") 

113 num_chairs_long = math.floor(table_width / min_width) 

114 width_per_chair_long = table_width / num_chairs_long 

115 x_pos = table_bbox_min_max[0][0] 

116 y_pos = table_bbox_min_max[0][1] - distance_y_chair_to_table 

117 for i in range(num_chairs_long): 

118 if i == 0: 

119 x_pos += width_per_chair_long / 2 - \ 

120 chair_width / 2 

121 else: 

122 x_pos += width_per_chair_long 

123 chair_pnts0.append(gp_Pnt(x_pos, y_pos, z_pos)) 

124 chair_trsfs += PyOCCTools.generate_obj_trsfs(chair_pnts0, 

125 org_chair_pos) 

126 chair_pnts += chair_pnts0 

127 if furniture_setting in ['TwoSideTable', 'GroupTable']: 

128 chair_pnts180 = [] 

129 min_width = 0.6 

130 if table_depth < min_width: 

131 logger.warning( 

132 f"Depth (={table_depth}m of table is too small for " 

133 f"furniture setting {furniture_setting}. " 

134 f"Minimum depth of {min_width}m is required. " 

135 f"Resulting position does not comply with " 

136 f"standards.") 

137 num_chairs_long = math.floor(table_width / min_width) 

138 width_per_chair_long = table_width / num_chairs_long 

139 x_pos_rot180 = table_bbox_min_max[1][0] 

140 y_pos_rot180 = table_bbox_min_max[1][1] + distance_y_chair_to_table 

141 for i in range(num_chairs_long): 

142 if i == 0: 

143 x_pos_rot180 -= (width_per_chair_long / 2 - chair_width / 2) 

144 else: 

145 x_pos_rot180 -= width_per_chair_long 

146 chair_pnts180.append(gp_Pnt(x_pos_rot180, y_pos_rot180, 

147 z_pos)) 

148 chair_trsfs += PyOCCTools.generate_obj_trsfs(chair_pnts180, 

149 org_chair_pos, 

150 rot_angle=180) 

151 chair_pnts += chair_pnts180 

152 

153 if furniture_setting in ['GroupTable']: 

154 min_width = 0.6 

155 chair_pnts90 = [] 

156 chair_pnts270 = [] 

157 

158 num_chairs_long = math.floor(table_depth / min_width) 

159 width_per_chair_short = table_depth / num_chairs_long 

160 x_pos_rot90 = table_bbox_min_max[1][0] + distance_y_chair_to_table 

161 y_pos_rot90 = table_bbox_min_max[0][1] 

162 for i in range(num_chairs_long): 

163 if i == 0: 

164 y_pos_rot90 += width_per_chair_short / 2 - \ 

165 chair_width / 2 

166 else: 

167 y_pos_rot90 += width_per_chair_short 

168 chair_pnts90.append(gp_Pnt(x_pos_rot90, y_pos_rot90, 

169 z_pos)) 

170 chair_trsfs += PyOCCTools.generate_obj_trsfs(chair_pnts90, 

171 org_chair_pos, 

172 rot_angle=90) 

173 chair_pnts += chair_pnts90 

174 

175 x_pos_rot270 = table_bbox_min_max[0][0] - distance_y_chair_to_table 

176 y_pos_rot270 = table_bbox_min_max[1][1] 

177 for i in range(num_chairs_long): 

178 if i == 0: 

179 y_pos_rot270 -= (width_per_chair_short / 2 - \ 

180 chair_width / 2) 

181 else: 

182 y_pos_rot270 += width_per_chair_short 

183 chair_pnts270.append(gp_Pnt(x_pos_rot270, y_pos_rot270, z_pos)) 

184 chair_trsfs += PyOCCTools.generate_obj_trsfs(chair_pnts270, 

185 org_chair_pos, 

186 rot_angle=270) 

187 chair_pnts += chair_pnts270 

188 

189 return chair_pnts, chair_trsfs