mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 18:16:40 +00:00
You can now submit custom geometry for covetool environmental analysis
This commit is contained in:
@@ -213,6 +213,7 @@ if bpy is not None:
|
||||
covetool_ui.BIM_PT_covetool,
|
||||
covetool_operator.Login,
|
||||
covetool_operator.RunSimpleAnalysis,
|
||||
covetool_operator.RunAnalysis,
|
||||
)
|
||||
|
||||
def menu_func_export(self, context):
|
||||
|
||||
@@ -159,7 +159,6 @@ class IfcParser():
|
||||
self.styled_items = self.get_styled_items()
|
||||
self.spatial_structure_elements = self.get_spatial_structure_elements()
|
||||
self.groups = self.get_groups()
|
||||
|
||||
self.libraries = self.get_libraries()
|
||||
self.door_attributes = self.get_door_attributes()
|
||||
self.window_attributes = self.get_window_attributes()
|
||||
|
||||
@@ -15,7 +15,7 @@ class Api:
|
||||
def post_request(self, path, data, use_token=True):
|
||||
url = self._api_url(path)
|
||||
headers = self._headers(use_token)
|
||||
response = requests.post(url, headers=headers, data=data)
|
||||
response = requests.post(url, headers=headers, json=data)
|
||||
return self._handle_response(response)
|
||||
|
||||
def get_request(self, path, use_token=True):
|
||||
|
||||
@@ -61,3 +61,120 @@ class RunSimpleAnalysis(bpy.types.Operator):
|
||||
covetool_results = bpy.data.texts.new('cove.tool Results')
|
||||
covetool_results.write(json.dumps(result, indent=4))
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class RunAnalysis(bpy.types.Operator):
|
||||
bl_idname = 'bim.covetool_run_analysis'
|
||||
bl_label = 'Run Analysis'
|
||||
|
||||
def execute(self, context):
|
||||
self.inputs = {
|
||||
'floors': [],
|
||||
'walls': [],
|
||||
'interior_walls': [],
|
||||
'windows': [],
|
||||
'skylights': [],
|
||||
'roofs': [],
|
||||
'shading_devices': []
|
||||
}
|
||||
self.parse_objects()
|
||||
data = {
|
||||
'run': bpy.context.scene.CoveToolProperties.projects[bpy.context.scene.CoveToolProperties.active_project_index].run_set,
|
||||
'source': 'BlenderBIM',
|
||||
'rotation_angle': 0,
|
||||
**self.inputs
|
||||
}
|
||||
result = api.post_request('run-values', data)
|
||||
covetool_results = bpy.data.texts.new('cove.tool Results')
|
||||
covetool_results.write(json.dumps(result, indent=4))
|
||||
return {'FINISHED'}
|
||||
|
||||
def parse_objects(self):
|
||||
for obj in bpy.context.visible_objects:
|
||||
covetool_category = self.get_covetool_category(obj)
|
||||
if not covetool_category:
|
||||
continue
|
||||
if not self.has_triangulate_modifier(obj):
|
||||
obj.modifiers.new(name='Triangulate', type='TRIANGULATE')
|
||||
mesh = obj.evaluated_get(bpy.context.evaluated_depsgraph_get()).to_mesh()
|
||||
meshes = {}
|
||||
for polygon in mesh.polygons:
|
||||
normal = '{}|{}|{}'.format(
|
||||
round(polygon.normal[0], 2),
|
||||
round(polygon.normal[1], 2),
|
||||
round(polygon.normal[2], 2))
|
||||
meshes.setdefault(normal, {
|
||||
'Mesh': {
|
||||
'vertex_indices': {},
|
||||
'Vertices': [],
|
||||
'Triangles': []
|
||||
},
|
||||
'Center': {},
|
||||
'Normal': {
|
||||
'X': round(polygon.normal[0], 2),
|
||||
'Y': round(polygon.normal[1], 2),
|
||||
'Z': round(polygon.normal[2], 2)
|
||||
}
|
||||
})
|
||||
for vertex in polygon.vertices:
|
||||
global_vertex = obj.matrix_world @ mesh.vertices[vertex].co
|
||||
meshes[normal]['Mesh']['vertex_indices'][vertex] = {
|
||||
'X': global_vertex[0] * 3.28084, # Covetools require feet
|
||||
'Y': global_vertex[1] * 3.28084,
|
||||
'Z': global_vertex[2] * 3.28084
|
||||
}
|
||||
meshes[normal]['Mesh']['Triangles'].append([
|
||||
polygon.vertices[0],
|
||||
polygon.vertices[1],
|
||||
polygon.vertices[2]
|
||||
])
|
||||
for normal, mesh in meshes.items():
|
||||
sorted_keys = sorted(mesh['Mesh']['vertex_indices'])
|
||||
mesh['Mesh']['Vertices'] = [mesh['Mesh']['vertex_indices'][k] for k in sorted_keys]
|
||||
for triangle in mesh['Mesh']['Triangles']:
|
||||
triangle[0] = sorted_keys.index(triangle[0])
|
||||
triangle[1] = sorted_keys.index(triangle[1])
|
||||
triangle[2] = sorted_keys.index(triangle[2])
|
||||
mesh['Center'] = mesh['Mesh']['Vertices'][0] # Not correct, but just for now
|
||||
del mesh['Mesh']['vertex_indices']
|
||||
self.inputs[covetool_category].extend(meshes.values())
|
||||
|
||||
def has_triangulate_modifier(self, obj):
|
||||
for modifier in obj.modifiers:
|
||||
if modifier.type == 'TRIANGULATE':
|
||||
return True
|
||||
|
||||
def get_covetool_category(self, obj):
|
||||
if not hasattr(obj, 'data') or not isinstance(obj.data, bpy.types.Mesh):
|
||||
return
|
||||
if 'IfcSlab' in obj.name:
|
||||
return 'floors'
|
||||
elif 'IfcRoof' in obj.name:
|
||||
return 'roofs'
|
||||
elif 'IfcWall' in obj.name:
|
||||
if self.is_wall_internal(obj):
|
||||
return 'interior_walls'
|
||||
return 'walls'
|
||||
elif 'IfcWindow' in obj.name:
|
||||
if self.is_window_skylight(obj):
|
||||
return 'skylights'
|
||||
return 'windows'
|
||||
elif 'IfcShadingDevice' in obj.name:
|
||||
return 'shading_devices'
|
||||
|
||||
def is_wall_internal(self, obj):
|
||||
pset_wallcommon = obj.BIMObjectProperties.psets.get('Pset_WallCommon')
|
||||
if pset_wallcommon:
|
||||
is_external = pset_wallcommon.properties.get('IsExternal')
|
||||
if is_external:
|
||||
if is_external.string_value == 'True':
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
predefined_type = obj.BIMObjectProperties.attributes.get('PredefinedType')
|
||||
if predefined_type and predefined_type.string_value in ['MOVABLE', 'PARTITIONING', 'PLUMBINGWALL']:
|
||||
return True
|
||||
|
||||
def is_window_skylight(self, obj):
|
||||
predefined_type = obj.BIMObjectProperties.attributes.get('PredefinedType')
|
||||
return predefined_type and predefined_type.string_value == 'SKYLIGHT'
|
||||
|
||||
@@ -26,6 +26,9 @@ class BIM_PT_covetool(bpy.types.Panel):
|
||||
|
||||
layout.template_list('BIM_UL_covetool_projects', '', props, 'projects', props, 'active_project_index')
|
||||
|
||||
row = layout.row()
|
||||
row.operator('bim.covetool_run_analysis')
|
||||
|
||||
prop_names = [ 'si_units', 'building_height', 'roof_area', 'floor_area',
|
||||
'skylight_area', 'wall_area_e', 'wall_area_ne', 'wall_area_n',
|
||||
'wall_area_nw', 'wall_area_w', 'wall_area_sw', 'wall_area_s',
|
||||
|
||||
Reference in New Issue
Block a user