mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-02 04:59:52 +00:00
seems to be working
This commit is contained in:
committed by
Dion Moult
parent
2912580087
commit
3eb29af496
@@ -52,6 +52,8 @@ class LoadGroupDecorationData:
|
|||||||
}
|
}
|
||||||
models = tool.Ifc.get().by_type("IfcStructuralAnalysisModel")
|
models = tool.Ifc.get().by_type("IfcStructuralAnalysisModel")
|
||||||
m = models[0]
|
m = models[0]
|
||||||
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
|
if props.activity_type == "Action":
|
||||||
groups = m.LoadedBy or []
|
groups = m.LoadedBy or []
|
||||||
for g in groups:
|
for g in groups:
|
||||||
ret.append((str(g.id()),". "+abrv[g.PredefinedType]+" "+g.Name,""))
|
ret.append((str(g.id()),". "+abrv[g.PredefinedType]+" "+g.Name,""))
|
||||||
@@ -59,6 +61,14 @@ class LoadGroupDecorationData:
|
|||||||
for item in related_objects:
|
for item in related_objects:
|
||||||
for subgoup in [sg for sg in item if sg.is_a("IfcStructuralLoadGroup")]:
|
for subgoup in [sg for sg in item if sg.is_a("IfcStructuralLoadGroup")]:
|
||||||
ret.append((str(subgoup.id()),". "+abrv[subgoup.PredefinedType]+subgoup.Name,""))
|
ret.append((str(subgoup.id()),". "+abrv[subgoup.PredefinedType]+subgoup.Name,""))
|
||||||
|
|
||||||
|
if props.activity_type == "External Reaction":
|
||||||
|
groups = m.HasResults or []
|
||||||
|
for g in groups:
|
||||||
|
result_name = g.ResultForLoadGroup.Name or ""
|
||||||
|
group_name = g.Name or ""
|
||||||
|
ret.append((str(g.id()), group_name + " " + result_name,""))
|
||||||
|
|
||||||
if len(ret) == 0:
|
if len(ret) == 0:
|
||||||
ret.append(("","",""))
|
ret.append(("","",""))
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -108,6 +108,8 @@ class LoadsDecorator:
|
|||||||
|
|
||||||
def location_3d_to_region_2d(self, coord, normal, context):
|
def location_3d_to_region_2d(self, coord, normal, context):
|
||||||
"""Convert from 3D space to 2D screen space"""
|
"""Convert from 3D space to 2D screen space"""
|
||||||
|
coord = Vector(coord)
|
||||||
|
normal = Vector(normal)
|
||||||
rv3d = context.region_data
|
rv3d = context.region_data
|
||||||
perspective = rv3d.view_perspective
|
perspective = rv3d.view_perspective
|
||||||
view_matrix = rv3d.view_matrix
|
view_matrix = rv3d.view_matrix
|
||||||
|
|||||||
@@ -52,7 +52,11 @@ class ShowLoads(bpy.types.Operator):
|
|||||||
collection = bpy.data.collections["IfcStructuralItem"]
|
collection = bpy.data.collections["IfcStructuralItem"]
|
||||||
collection.hide_viewport = False
|
collection.hide_viewport = False
|
||||||
context.window.cursor_modal_set("WAIT")
|
context.window.cursor_modal_set("WAIT")
|
||||||
|
try:
|
||||||
LoadsDecorator.install(context)
|
LoadsDecorator.install(context)
|
||||||
|
except Exception as exc:
|
||||||
|
context.window.cursor_modal_restore()
|
||||||
|
raise exc
|
||||||
context.window.cursor_modal_restore()
|
context.window.cursor_modal_restore()
|
||||||
context.window_manager.modal_handler_add(self)
|
context.window_manager.modal_handler_add(self)
|
||||||
for area in context.screen.areas:
|
for area in context.screen.areas:
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ def get_load_groups_to_show(self, context):
|
|||||||
LoadGroupDecorationData.load()
|
LoadGroupDecorationData.load()
|
||||||
return LoadGroupDecorationData.data["load groups to show"]
|
return LoadGroupDecorationData.data["load groups to show"]
|
||||||
|
|
||||||
|
def update_activity_type(self, context):
|
||||||
|
LoadGroupDecorationData.is_loaded = False
|
||||||
|
|
||||||
def get_applicable_structural_load_types(self, context):
|
def get_applicable_structural_load_types(self, context):
|
||||||
if not StructuralLoadCasesData.is_loaded:
|
if not StructuralLoadCasesData.is_loaded:
|
||||||
StructuralLoadCasesData.load()
|
StructuralLoadCasesData.load()
|
||||||
@@ -164,7 +167,8 @@ class BIMStructuralProperties(PropertyGroup):
|
|||||||
activity_type: EnumProperty(items=[("Action","Actions","Show actions loads"),
|
activity_type: EnumProperty(items=[("Action","Actions","Show actions loads"),
|
||||||
("External Reaction","External Reactions","Show reactions on boundary conditions"),
|
("External Reaction","External Reactions","Show reactions on boundary conditions"),
|
||||||
("Internal Reactions","Internal Reactions","Show internal reactions on members")],
|
("Internal Reactions","Internal Reactions","Show internal reactions on members")],
|
||||||
name="Activity Type")
|
name="Activity Type",
|
||||||
|
update=update_activity_type)
|
||||||
load_group_to_show: EnumProperty(items=get_load_groups_to_show, name="Load Groups")
|
load_group_to_show: EnumProperty(items=get_load_groups_to_show, name="Load Groups")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ class ShaderInfo:
|
|||||||
#self.shader_type = shader_type
|
#self.shader_type = shader_type
|
||||||
#self.args = {}
|
#self.args = {}
|
||||||
#self.indices = []
|
#self.indices = []
|
||||||
self.curve_members = []
|
self.curve_members = {}
|
||||||
self.point_members = []
|
self.point_members = {}
|
||||||
self.surface_members = {}
|
self.surface_members = {}
|
||||||
self.text_info = []
|
self.text_info = []
|
||||||
self.info = []
|
self.info = []
|
||||||
@@ -29,6 +29,10 @@ class ShaderInfo:
|
|||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.info = []
|
self.info = []
|
||||||
|
self.text_info = []
|
||||||
|
self.curve_members = {}
|
||||||
|
self.point_members = {}
|
||||||
|
self.surface_members = {}
|
||||||
self.get_force_units()
|
self.get_force_units()
|
||||||
self.get_strucutural_elements_and_activities()
|
self.get_strucutural_elements_and_activities()
|
||||||
self.get_linear_loads()
|
self.get_linear_loads()
|
||||||
@@ -160,14 +164,15 @@ class ShaderInfo:
|
|||||||
else:
|
else:
|
||||||
member["activities"].append((activity,factor))
|
member["activities"].append((activity,factor))
|
||||||
|
|
||||||
def recursive_subgroups(groups, rec_limit, factor = 1):
|
def recursive_subgroups(groups, rec_limit, activity_type, factor = 1):
|
||||||
if len(groups) == 0 or rec_limit == 0:
|
if len(groups) == 0 or rec_limit == 0:
|
||||||
return None
|
return None
|
||||||
for group in groups:
|
for group in groups:
|
||||||
subgorups = []
|
subgorups = []
|
||||||
activities = []
|
activities = []
|
||||||
relationship = [rel for rel in group.IsGroupedBy]
|
relationship = [rel for rel in group.IsGroupedBy]
|
||||||
group_coef = group.Coefficient if group.Coefficient is not None else 1.0
|
coef = getattr(group, 'Coefficient', 1.0)
|
||||||
|
group_coef = coef if coef is not None else 1.0
|
||||||
rel_factor = 1.0
|
rel_factor = 1.0
|
||||||
|
|
||||||
for rel in relationship:
|
for rel in relationship:
|
||||||
@@ -181,19 +186,28 @@ class ShaderInfo:
|
|||||||
if len(activity.AssignedToStructuralItem):
|
if len(activity.AssignedToStructuralItem):
|
||||||
element = activity.AssignedToStructuralItem[0].RelatingElement
|
element = activity.AssignedToStructuralItem[0].RelatingElement
|
||||||
if element is not None:
|
if element is not None:
|
||||||
|
if activity_type == "Action":
|
||||||
if element.is_a("IfcStructuralCurveMember"):
|
if element.is_a("IfcStructuralCurveMember"):
|
||||||
self.curve_members.append(element)
|
populate_members_dict("curve_members",element,activity,factor)
|
||||||
elif element.is_a("IfcStructuralPoinConnection"):
|
elif element.is_a("IfcStructuralPointConnection"):
|
||||||
self.point_members.append(element)
|
populate_members_dict("point_members",element,activity,factor)
|
||||||
elif element.is_a("IfcStructuralSurfaceMember"):
|
elif element.is_a("IfcStructuralSurfaceMember"):
|
||||||
populate_members_dict("surface_members",element,activity,factor)
|
populate_members_dict("surface_members",element,activity,factor)
|
||||||
recursive_subgroups(subgorups,rec_limit-1,factor=factor)
|
|
||||||
|
elif activity_type == "External Reaction" and getattr(element,"AppliedCondition",None) is not None:
|
||||||
|
if element.is_a("IfcStructuralCurveMember"):
|
||||||
|
populate_members_dict("curve_members",element,activity,factor)
|
||||||
|
elif element.is_a("IfcStructuralPointConnection"):
|
||||||
|
populate_members_dict("point_members",element,activity,factor)
|
||||||
|
elif element.is_a("IfcStructuralSurfaceMember"):
|
||||||
|
populate_members_dict("surface_members",element,activity,factor)
|
||||||
|
recursive_subgroups(subgorups,rec_limit-1,activity_type,factor=factor)
|
||||||
|
|
||||||
props = bpy.context.scene.BIMStructuralProperties
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
group_definition_id = int(props.load_group_to_show)
|
group_definition_id = int(props.load_group_to_show)
|
||||||
file = IfcStore.get_file()
|
file = IfcStore.get_file()
|
||||||
groups = [file.by_id(group_definition_id)]
|
groups = [file.by_id(group_definition_id)]
|
||||||
recursive_subgroups(groups,10)
|
recursive_subgroups(groups,10,props.activity_type)
|
||||||
|
|
||||||
|
|
||||||
def get_shader(self, pattern):
|
def get_shader(self, pattern):
|
||||||
@@ -432,56 +446,6 @@ class ShaderInfo:
|
|||||||
del shader_info
|
del shader_info
|
||||||
return shader
|
return shader
|
||||||
|
|
||||||
def get_planar_loads(self):
|
|
||||||
list_of_surfaces = self.surface_members
|
|
||||||
shader = self.get_planar_shader()
|
|
||||||
for value in list_of_surfaces.values():
|
|
||||||
surf = value["element"]
|
|
||||||
activity_list = [getattr(a, 'RelatedStructuralActivity', None) for a in getattr(surf, 'AssignedStructuralActivity', None)
|
|
||||||
if getattr(a, 'RelatedStructuralActivity', None).is_a() in ['IfcStructuralPlanarAction','IfcStructuralSurfaceAction']]
|
|
||||||
if len(activity_list) == 0:
|
|
||||||
continue
|
|
||||||
blender_object: bpy.types.Object = IfcStore.get_element(getattr(surf, 'GlobalId', None))
|
|
||||||
mat = blender_object.matrix_world
|
|
||||||
mesh: bpy.types.Mesh = blender_object.data
|
|
||||||
z = Vector((0,0,1))
|
|
||||||
positions = []
|
|
||||||
indices = []
|
|
||||||
coord = []
|
|
||||||
for p in mesh.polygons:
|
|
||||||
add_index = len(positions)
|
|
||||||
for i, v in enumerate(p.vertices):
|
|
||||||
p1 = mesh.vertices[v].co
|
|
||||||
positions.append(p1)
|
|
||||||
p2 = p1 + z
|
|
||||||
positions.append(p2)
|
|
||||||
if i == 0:
|
|
||||||
coord.append((0,0,1))
|
|
||||||
coord.append((0,1,1))
|
|
||||||
else:
|
|
||||||
vec = positions[-1] - positions [-3]
|
|
||||||
l = vec.length
|
|
||||||
coord.append((l,0,1))
|
|
||||||
coord.append((l,1,1))
|
|
||||||
add = add_index+2*i
|
|
||||||
indices.append((0+add,2+add,1+add))
|
|
||||||
indices.append((1+add,2+add,3+add))
|
|
||||||
length = len(p.vertices)-1
|
|
||||||
indices.append((length+add_index-1,length+add_index,0+add_index))
|
|
||||||
indices.append((length+add_index,0+add_index,1+add_index))
|
|
||||||
indices.append((1+add_index,3+add_index,5+add_index))
|
|
||||||
if len(p.vertices) > 3:
|
|
||||||
indices.append((1+add_index,5+add_index,7+add_index))
|
|
||||||
|
|
||||||
self.info.append(
|
|
||||||
{
|
|
||||||
"shader": shader,
|
|
||||||
"args": {"position": positions, "coord": coord},
|
|
||||||
"indices": indices,
|
|
||||||
"uniforms": [["color", (0.2,0,1,1)],["spacing", 0.2]]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_planar_loads_2(self):
|
def get_planar_loads_2(self):
|
||||||
list_of_surfaces = self.surface_members
|
list_of_surfaces = self.surface_members
|
||||||
shader = self.get_planar_shader()
|
shader = self.get_planar_shader()
|
||||||
@@ -493,18 +457,20 @@ class ShaderInfo:
|
|||||||
activity_list = value["activities"]
|
activity_list = value["activities"]
|
||||||
if len(activity_list) == 0:
|
if len(activity_list) == 0:
|
||||||
continue
|
continue
|
||||||
values = self.get_planar_loads_values(activity_list)
|
rotation = self.get_surface_member_rotation(surf)
|
||||||
|
values = self.get_planar_loads_values(activity_list,rotation)
|
||||||
if maximum == 0:
|
if maximum == 0:
|
||||||
maximum = max([abs(float(i)) for i in values])
|
maximum = max([abs(float(i)) for i in values])
|
||||||
if maximum == 0:
|
if maximum == 0:
|
||||||
continue
|
continue
|
||||||
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
|
reference_frame = props.reference_frame
|
||||||
|
orientation = np.eye(3)
|
||||||
|
if reference_frame == "LOCAL_COORDS":
|
||||||
|
orientation = rotation
|
||||||
blender_object: bpy.types.Object = IfcStore.get_element(getattr(surf, 'GlobalId', None))
|
blender_object: bpy.types.Object = IfcStore.get_element(getattr(surf, 'GlobalId', None))
|
||||||
mat = blender_object.matrix_world
|
mat = blender_object.matrix_world
|
||||||
mesh: bpy.types.Mesh = blender_object.data
|
mesh: bpy.types.Mesh = blender_object.data
|
||||||
rotation = self.get_surface_member_rotation(surf)
|
|
||||||
x = rotation @ (np.array((1,0,0))*0.2)
|
|
||||||
y = rotation @ (np.array((0,1,0))*0.2)
|
|
||||||
z = rotation @ (np.array((0,0,1))*0.2)
|
|
||||||
|
|
||||||
positions = []
|
positions = []
|
||||||
indices = []
|
indices = []
|
||||||
@@ -520,7 +486,7 @@ class ShaderInfo:
|
|||||||
for v in bm.verts:
|
for v in bm.verts:
|
||||||
p1 = np.array(mat @ v.co)
|
p1 = np.array(mat @ v.co)
|
||||||
positions.append(p1)
|
positions.append(p1)
|
||||||
p2 = p1 - (rotation@values)*0.2/maximum
|
p2 = p1 - (orientation@values)*0.2/maximum
|
||||||
positions.append(p2)
|
positions.append(p2)
|
||||||
coord.append((float(p1[0]+p1[1]),0,1))
|
coord.append((float(p1[0]+p1[1]),0,1))
|
||||||
coord.append((float(p1[0]+p1[1]),1,1))
|
coord.append((float(p1[0]+p1[1]),1,1))
|
||||||
@@ -542,7 +508,7 @@ class ShaderInfo:
|
|||||||
center = bm.faces[0].calc_center_bounds()
|
center = bm.faces[0].calc_center_bounds()
|
||||||
|
|
||||||
self.text_info.append(
|
self.text_info.append(
|
||||||
{"position": mat @ center - Vector((rotation@values)*0.2/maximum),
|
{"position": mat @ center - Vector((orientation@values)*0.2/maximum),
|
||||||
"normal": Vector(mesh.polygons[0].normal),
|
"normal": Vector(mesh.polygons[0].normal),
|
||||||
"text": f'{values[2]:.5f} {self.planar_force_unit}'}
|
"text": f'{values[2]:.5f} {self.planar_force_unit}'}
|
||||||
)
|
)
|
||||||
@@ -555,7 +521,7 @@ class ShaderInfo:
|
|||||||
"uniforms": [["color", (0.2,0,1,1)],["spacing", 0.2]]
|
"uniforms": [["color", (0.2,0,1,1)],["spacing", 0.2]]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
def get_planar_loads_values(self, activity_list):
|
def get_planar_loads_values(self, activity_list,element_rotation_matrix):
|
||||||
values = np.zeros((3))
|
values = np.zeros((3))
|
||||||
for item in activity_list:
|
for item in activity_list:
|
||||||
activity = item[0]
|
activity = item[0]
|
||||||
@@ -567,7 +533,8 @@ class ShaderInfo:
|
|||||||
temp[1] = load.PlanarForceY if load.PlanarForceY is not None else 0
|
temp[1] = load.PlanarForceY if load.PlanarForceY is not None else 0
|
||||||
temp[2] = load.PlanarForceZ if load.PlanarForceZ is not None else 0
|
temp[2] = load.PlanarForceZ if load.PlanarForceZ is not None else 0
|
||||||
temp = temp*factor
|
temp = temp*factor
|
||||||
values = values + temp
|
transform = self.get_activity_transform_matrix(activity,element_rotation_matrix)
|
||||||
|
values += transform@temp
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def get_surface_member_rotation(self,surface_member):
|
def get_surface_member_rotation(self,surface_member):
|
||||||
@@ -595,32 +562,59 @@ class ShaderInfo:
|
|||||||
rotation = placement[0:3,0:3]
|
rotation = placement[0:3,0:3]
|
||||||
return rotation
|
return rotation
|
||||||
|
|
||||||
|
def get_activity_transform_matrix(self, activity, element_rotation_matrix):
|
||||||
|
"provides the transformation matrix to convert between reference frames"
|
||||||
|
global_or_local = activity.GlobalOrLocal
|
||||||
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
|
reference_frame = props.reference_frame
|
||||||
|
transform_matrix = np.eye(3)
|
||||||
|
if reference_frame == 'LOCAL_COORDS' and global_or_local != reference_frame:
|
||||||
|
transform_matrix = np.linalg.inv(element_rotation_matrix)
|
||||||
|
elif reference_frame == 'GLOBAL_COORDS' and global_or_local != reference_frame:
|
||||||
|
transform_matrix = element_rotation_matrix
|
||||||
|
return transform_matrix
|
||||||
|
|
||||||
def get_point_loads(self):
|
def get_point_loads(self):
|
||||||
list_of_point_connections = tool.Ifc.get().by_type("IfcStructuralPointConnection")
|
list_of_point_connections = tool.Ifc.get().by_type("IfcStructuralPointConnection")
|
||||||
for conn in list_of_point_connections:
|
list_of_point_connections = self.point_members
|
||||||
|
for value in list_of_point_connections.values():
|
||||||
|
conn = value["member"]
|
||||||
activity_list = [getattr(a, 'RelatedStructuralActivity', None) for a in getattr(conn, 'AssignedStructuralActivity', None)
|
activity_list = [getattr(a, 'RelatedStructuralActivity', None) for a in getattr(conn, 'AssignedStructuralActivity', None)
|
||||||
if getattr(a, 'RelatedStructuralActivity', None).is_a() in ['IfcStructuralPointAction']]
|
if getattr(a, 'RelatedStructuralActivity', None).is_a() in ['IfcStructuralPointAction']]
|
||||||
|
activity_list = value["activities"]
|
||||||
if len(activity_list) == 0:
|
if len(activity_list) == 0:
|
||||||
continue
|
continue
|
||||||
blender_object = IfcStore.get_element(getattr(conn, 'GlobalId', None))
|
blender_object = IfcStore.get_element(getattr(conn, 'GlobalId', None))
|
||||||
if blender_object.type == 'MESH':
|
if blender_object.type == 'MESH':
|
||||||
conn_location = blender_object.matrix_world @ blender_object.data.vertices[0].co
|
conn_location = blender_object.matrix_world @ blender_object.data.vertices[0].co
|
||||||
#get local coordinates of the connection
|
#get local coordinates of the connection
|
||||||
loads = self.get_point_loads_list(activity_list)
|
rotation = self.get_point_connection_rotation(conn)
|
||||||
self.get_point_shader_args(loads, conn_location)
|
loads = self.get_point_loads_values(activity_list, rotation)
|
||||||
|
self.get_point_shader_args(loads, conn_location, rotation)
|
||||||
|
|
||||||
def get_point_shader_args(self,loads, location):
|
def get_point_shader_args(self,loads, location, rotation):
|
||||||
|
location = np.array(location)
|
||||||
indices = []
|
indices = []
|
||||||
text_info = []
|
text_info = []
|
||||||
direction_dict = {
|
direction_dict = {
|
||||||
"fx": (Vector((1,0,0)),Vector((0,1,0)),Vector((0,0,1))),
|
"fx": (np.array((1,0,0)),np.array((0,1,0)),np.array((0,0,1))),
|
||||||
"fy": (Vector((0,1,0)),Vector((1,0,0)),Vector((0,0,1))),
|
"fy": (np.array((0,1,0)),np.array((1,0,0)),np.array((0,0,1))),
|
||||||
"fz": (Vector((0,0,1)),Vector((0,1,0)),Vector((1,0,0))),
|
"fz": (np.array((0,0,1)),np.array((0,1,0)),np.array((1,0,0))),
|
||||||
"mx": (Vector((0,1,0)),Vector((0,0,1))),
|
"mx": (np.array((0,1,0)),np.array((0,0,1))),
|
||||||
"my": (Vector((1,0,0)),Vector((0,0,1))),
|
"my": (np.array((1,0,0)),np.array((0,0,1))),
|
||||||
"mz": (Vector((1,0,0)),Vector((0,1,0))),
|
"mz": (np.array((1,0,0)),np.array((0,1,0))),
|
||||||
}
|
}
|
||||||
keys = ["fx","fy","fz","mx","my","mz"]
|
keys = ["fx","fy","fz","mx","my","mz"]
|
||||||
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
|
reference_frame = props.reference_frame
|
||||||
|
if reference_frame == "LOCAL_COORDS":
|
||||||
|
for key in keys:
|
||||||
|
tup = direction_dict[key]
|
||||||
|
li = []
|
||||||
|
for item in tup:
|
||||||
|
li.append(rotation@item)
|
||||||
|
direction_dict[key] = li
|
||||||
|
|
||||||
for i, key in enumerate(keys):
|
for i, key in enumerate(keys):
|
||||||
if loads[i] == 0:
|
if loads[i] == 0:
|
||||||
continue
|
continue
|
||||||
@@ -629,7 +623,8 @@ class ShaderInfo:
|
|||||||
color = (0,1,0,1)
|
color = (0,1,0,1)
|
||||||
elif i in [2,5]:
|
elif i in [2,5]:
|
||||||
color = (0,0,1,1)
|
color = (0,0,1,1)
|
||||||
d1 = -(direction_dict[key][0]*loads[i]).normalized()
|
d1 = -(direction_dict[key][0]*loads[i])
|
||||||
|
d1 = d1/np.linalg.norm(d1)
|
||||||
if i < 3:
|
if i < 3:
|
||||||
d2 = direction_dict[key][1]
|
d2 = direction_dict[key][1]
|
||||||
d3 = direction_dict[key][2]
|
d3 = direction_dict[key][2]
|
||||||
@@ -653,6 +648,11 @@ class ShaderInfo:
|
|||||||
"uniforms": [["color", color],["spacing", 0.2]]
|
"uniforms": [["color", color],["spacing", 0.2]]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
self.text_info.append(
|
||||||
|
{"position": location + d1,
|
||||||
|
"normal": d2/np.linalg.norm(d2),
|
||||||
|
"text": f'{loads[i]:.2f} {self.force_unit}'}
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
d2 = d2 = direction_dict[key][1]
|
d2 = d2 = direction_dict[key][1]
|
||||||
p1 = location - d2
|
p1 = location - d2
|
||||||
@@ -673,17 +673,29 @@ class ShaderInfo:
|
|||||||
"uniforms": [["color", color]]
|
"uniforms": [["color", color]]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
self.text_info.append(
|
||||||
|
{"position": location +0.25*(d1 + d2),
|
||||||
|
"normal": d2/np.linalg.norm(d2),
|
||||||
|
"text": f'{loads[i]:.2f} {self.force_unit}'}#change to moment unit
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_point_loads_values(self,activity_list,element_rotation_matrix):
|
||||||
|
result_list = np.zeros(6)
|
||||||
def get_point_loads_list(self,activity_list):
|
|
||||||
result_list = [0,0,0,0,0,0]
|
|
||||||
attr_list = ['ForceX','ForceY','ForceZ','MomentX','MomentY','MomentZ']
|
attr_list = ['ForceX','ForceY','ForceZ','MomentX','MomentY','MomentZ']
|
||||||
for activity in activity_list:
|
for item in activity_list:
|
||||||
|
activity = item[0]
|
||||||
|
factor = item[1]
|
||||||
load = activity.AppliedLoad
|
load = activity.AppliedLoad
|
||||||
|
temp = np.zeros(6)
|
||||||
for i, attr in enumerate(attr_list):
|
for i, attr in enumerate(attr_list):
|
||||||
value = 0 if getattr(load, attr, 0) is None else getattr(load, attr, 0)
|
value = 0 if getattr(load, attr, 0) is None else getattr(load, attr, 0)
|
||||||
result_list[i] += value
|
temp[i] += value*factor
|
||||||
|
transform_3 = self.get_activity_transform_matrix(activity,element_rotation_matrix)
|
||||||
|
transform_6 = np.zeros((6,6))
|
||||||
|
transform_6[0:3,0:3] = transform_3
|
||||||
|
transform_6[3:6,3:6] = transform_3
|
||||||
|
result_list += transform_6@temp
|
||||||
|
|
||||||
return result_list
|
return result_list
|
||||||
|
|
||||||
|
|
||||||
@@ -699,9 +711,11 @@ class ShaderInfo:
|
|||||||
|
|
||||||
list_of_curve_members = tool.Ifc.get().by_type("IfcStructuralCurveMember")
|
list_of_curve_members = tool.Ifc.get().by_type("IfcStructuralCurveMember")
|
||||||
list_of_curve_members = self.curve_members
|
list_of_curve_members = self.curve_members
|
||||||
for member in list_of_curve_members:
|
for value in list_of_curve_members.values():
|
||||||
|
member = value["member"]
|
||||||
activity_list = [getattr(a, 'RelatedStructuralActivity', None) for a in getattr(member, 'AssignedStructuralActivity', None)
|
activity_list = [getattr(a, 'RelatedStructuralActivity', None) for a in getattr(member, 'AssignedStructuralActivity', None)
|
||||||
if getattr(a, 'RelatedStructuralActivity', None).is_a() in ['IfcStructuralCurveAction','IfcStructuralLinearAction']]
|
if getattr(a, 'RelatedStructuralActivity', None).is_a() in ['IfcStructuralCurveAction','IfcStructuralLinearAction']]
|
||||||
|
activity_list = value["activities"]
|
||||||
if len(activity_list) == 0:
|
if len(activity_list) == 0:
|
||||||
continue
|
continue
|
||||||
# member is a structural curve member
|
# member is a structural curve member
|
||||||
@@ -714,7 +728,7 @@ class ShaderInfo:
|
|||||||
# using blender just get the global coordinates of the first and second vertex in the mesh
|
# using blender just get the global coordinates of the first and second vertex in the mesh
|
||||||
|
|
||||||
blender_object = IfcStore.get_element(getattr(member, 'GlobalId', None))
|
blender_object = IfcStore.get_element(getattr(member, 'GlobalId', None))
|
||||||
if blender_object.type == 'MESH':
|
|
||||||
start_co = blender_object.matrix_world @ blender_object.data.vertices[0].co
|
start_co = blender_object.matrix_world @ blender_object.data.vertices[0].co
|
||||||
end_co = blender_object.matrix_world @ blender_object.data.vertices[1].co
|
end_co = blender_object.matrix_world @ blender_object.data.vertices[1].co
|
||||||
x_axis = Vector(end_co-start_co).normalized()
|
x_axis = Vector(end_co-start_co).normalized()
|
||||||
@@ -723,13 +737,16 @@ class ShaderInfo:
|
|||||||
z_axis = Vector(getattr(z_direction, 'DirectionRatios', None)).normalized()
|
z_axis = Vector(getattr(z_direction, 'DirectionRatios', None)).normalized()
|
||||||
y_axis = z_axis.cross(x_axis).normalized()
|
y_axis = z_axis.cross(x_axis).normalized()
|
||||||
z_axis = x_axis.cross(y_axis).normalized()
|
z_axis = x_axis.cross(y_axis).normalized()
|
||||||
global_to_local = Matrix(((x_axis.x,y_axis.x,z_axis.x,0),
|
rot = self.get_curve_member_rotation(member)
|
||||||
(x_axis.y,y_axis.y,z_axis.y,0),
|
global_to_local = Matrix(((x_axis.x,y_axis.x,z_axis.x),
|
||||||
(x_axis.z,y_axis.z,z_axis.z,0),
|
(x_axis.y,y_axis.y,z_axis.y),
|
||||||
(0,0,0,1)))
|
(x_axis.z,y_axis.z,z_axis.z),
|
||||||
|
))
|
||||||
|
global_to_local = Matrix(rot)
|
||||||
|
|
||||||
#get shader args for each direction
|
#get shader args for each direction
|
||||||
reference_frame = 'GLOBAL_COORDS' #make it a scene property so it can be changed in a panel
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
|
reference_frame = props.reference_frame #make it a scene property so it can be changed in a panel
|
||||||
is_local = reference_frame == 'LOCAL_COORDS'
|
is_local = reference_frame == 'LOCAL_COORDS'
|
||||||
x_match = abs(Vector((1,0,0)).dot(x_axis)) > 0.99
|
x_match = abs(Vector((1,0,0)).dot(x_axis)) > 0.99
|
||||||
y_match = abs(Vector((0,1,0)).dot(x_axis)) > 0.99
|
y_match = abs(Vector((0,1,0)).dot(x_axis)) > 0.99
|
||||||
@@ -742,9 +759,18 @@ class ShaderInfo:
|
|||||||
"my": z_axis if is_local else Vector((-1,0,1)) if y_match else Vector((0,1,0)).cross(x_axis).normalized(),
|
"my": z_axis if is_local else Vector((-1,0,1)) if y_match else Vector((0,1,0)).cross(x_axis).normalized(),
|
||||||
"mz": y_axis if is_local else Vector((-1,1,0)) if z_match else Vector((0,0,1)).cross(x_axis).normalized()
|
"mz": y_axis if is_local else Vector((-1,1,0)) if z_match else Vector((0,0,1)).cross(x_axis).normalized()
|
||||||
}
|
}
|
||||||
match_dict = {'fx': x_match, 'fy': y_match, 'fz': z_match}
|
match_dict = {'fx': x_match or is_local, 'fy': y_match, 'fz': z_match}
|
||||||
member_length = Vector(end_co-start_co).length
|
member_length = Vector(end_co-start_co).length
|
||||||
loads_dict, maxforce = get_loads_per_direction(activity_list,global_to_local,member_length)
|
loads_dict, maxforce, point_loads = self.get_loads_per_direction(activity_list,global_to_local,member_length)
|
||||||
|
if len(point_loads):
|
||||||
|
for item in point_loads:
|
||||||
|
for sub_item in item:
|
||||||
|
pos = sub_item["pos"]
|
||||||
|
values = sub_item["values"]
|
||||||
|
pos_vector = start_co + x_axis*pos
|
||||||
|
self.get_point_shader_args(values,pos_vector)
|
||||||
|
if loads_dict is None:
|
||||||
|
continue
|
||||||
keys = ["fx","fy","fz","mx","my","mz"]
|
keys = ["fx","fy","fz","mx","my","mz"]
|
||||||
|
|
||||||
for key in keys:
|
for key in keys:
|
||||||
@@ -843,7 +869,7 @@ class ShaderInfo:
|
|||||||
self.text_info = text_info
|
self.text_info = text_info
|
||||||
|
|
||||||
|
|
||||||
def get_loads_per_direction(activity_list,global_to_local,member_length):
|
def get_loads_per_direction(self,activity_list,global_to_local,member_length):
|
||||||
""" returns a dict with values for applied loads in each direction
|
""" returns a dict with values for applied loads in each direction
|
||||||
return = {
|
return = {
|
||||||
"fx": values_in_this_direction
|
"fx": values_in_this_direction
|
||||||
@@ -860,15 +886,17 @@ def get_loads_per_direction(activity_list,global_to_local,member_length):
|
|||||||
"polyline": list[(position: float, load: float),...]
|
"polyline": list[(position: float, load: float),...]
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
loads_dict = get_loads_dict(activity_list,global_to_local)
|
loads_dict = self.get_loads_dict(activity_list,global_to_local)
|
||||||
const = loads_dict["constant force"]
|
const = loads_dict["constant force"]
|
||||||
quad = loads_dict["quadratic force"]
|
quad = loads_dict["quadratic force"]
|
||||||
sinus = loads_dict["sinus force"]
|
sinus = loads_dict["sinus force"]
|
||||||
loads = loads_dict["load configuration"]
|
loads = loads_dict["linear load configuration"]
|
||||||
unique_list = getuniquepositionlist(loads)
|
unique_list = self.getuniquepositionlist(loads)
|
||||||
final_list = []
|
final_list = []
|
||||||
|
return_value = None
|
||||||
|
max_load = 0
|
||||||
for pos in unique_list:
|
for pos in unique_list:
|
||||||
value = get_before_and_after(pos,loads)
|
value = self.get_before_and_after(pos,loads)
|
||||||
if value["before"] == value["after"]:
|
if value["before"] == value["after"]:
|
||||||
final_list.append([pos]+value["before"])
|
final_list.append([pos]+value["before"])
|
||||||
else:
|
else:
|
||||||
@@ -888,7 +916,7 @@ def get_loads_per_direction(activity_list,global_to_local,member_length):
|
|||||||
final_list.append([member_length,0.0,0.0,0.0,0.0,0.0,0.0])
|
final_list.append([member_length,0.0,0.0,0.0,0.0,0.0,0.0])
|
||||||
else:
|
else:
|
||||||
del final_list[-1]
|
del final_list[-1]
|
||||||
|
if len(final_list):
|
||||||
array = np.array(final_list) #7xn -> ["pos","fx","fy","fz","mx","my","mz"]
|
array = np.array(final_list) #7xn -> ["pos","fx","fy","fz","mx","my","mz"]
|
||||||
keys = ["fx","fy","fz","mx","my","mz"]
|
keys = ["fx","fy","fz","mx","my","mz"]
|
||||||
polyline = {
|
polyline = {
|
||||||
@@ -916,7 +944,7 @@ def get_loads_per_direction(activity_list,global_to_local,member_length):
|
|||||||
polyline[key].append([currentitem[0],currentitem[component+1]])
|
polyline[key].append([currentitem[0],currentitem[component+1]])
|
||||||
x = currentitem[0]/member_length
|
x = currentitem[0]/member_length
|
||||||
func = sin(x*3.1416)*sinus[component] + (-4.*x*x+4.*x)*quad[component]+const[component]+currentitem[component+1]
|
func = sin(x*3.1416)*sinus[component] + (-4.*x*x+4.*x)*quad[component]+const[component]+currentitem[component+1]
|
||||||
max_load = max(max_load,abs(func))
|
max_load = max(max_load,abs(sinus[component]+quad[component]+const[component]+currentitem[component+1]))
|
||||||
inner_dict = return_value[key]
|
inner_dict = return_value[key]
|
||||||
inner_dict["constant"] = const[component]
|
inner_dict["constant"] = const[component]
|
||||||
inner_dict["quadratic"] = quad[component]
|
inner_dict["quadratic"] = quad[component]
|
||||||
@@ -924,10 +952,10 @@ def get_loads_per_direction(activity_list,global_to_local,member_length):
|
|||||||
inner_dict["polyline"] = polyline[key]
|
inner_dict["polyline"] = polyline[key]
|
||||||
return_value[key] = inner_dict
|
return_value[key] = inner_dict
|
||||||
|
|
||||||
return return_value, max_load+abs(sinus[component]+quad[component])
|
return return_value, max_load, loads_dict["point load configuration"]
|
||||||
|
|
||||||
|
|
||||||
def getuniquepositionlist(load_config_list):
|
def getuniquepositionlist(self, load_config_list):
|
||||||
"""return an ordereded list of unique locations based on the load configuration list
|
"""return an ordereded list of unique locations based on the load configuration list
|
||||||
ex: load_config_list = [[{"pos":1.0,...},{"pos":3.0,...}],
|
ex: load_config_list = [[{"pos":1.0,...},{"pos":3.0,...}],
|
||||||
[{"pos":2.0,...},{"pos":3.0,...}],
|
[{"pos":2.0,...},{"pos":3.0,...}],
|
||||||
@@ -943,22 +971,22 @@ def getuniquepositionlist(load_config_list):
|
|||||||
unique.sort()
|
unique.sort()
|
||||||
return unique
|
return unique
|
||||||
|
|
||||||
def interp1d(l1,l2, pos):
|
def interp1d(self,l1,l2, pos):
|
||||||
""" 1d linear interpolation for the vector components"""
|
""" 1d linear interpolation for the vector components"""
|
||||||
fac = (l2[1]-l1[1])/(l2[0]-l1[0])
|
fac = (l2[1]-l1[1])/(l2[0]-l1[0])
|
||||||
v = l1[1] + fac*(pos-l1[0])
|
v = l1[1] + fac*(pos-l1[0])
|
||||||
return v
|
return v
|
||||||
|
|
||||||
def interpolate(pos,loadinfo,start,end,key):
|
def interpolate(self,pos,loadinfo,start,end,key):
|
||||||
""" interpolate the result vectors between load poits"""
|
""" interpolate the result vectors between load poits"""
|
||||||
result = Vector((0,0,0))
|
result = Vector((0,0,0))
|
||||||
for i in range(3):
|
for i in range(3):
|
||||||
value1 = [loadinfo[start]["pos"], loadinfo[start][key][i]] #[position, force_component]
|
value1 = [loadinfo[start]["pos"], loadinfo[start][key][i]] #[position, force_component]
|
||||||
value2= [loadinfo[end]["pos"], loadinfo[end][key][i]] # [position, force_component]
|
value2= [loadinfo[end]["pos"], loadinfo[end][key][i]] # [position, force_component]
|
||||||
result[i] = interp1d(value1,value2, pos) # interpolated [position, force_component]
|
result[i] = self.interp1d(value1,value2, pos) # interpolated [position, force_component]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_before_and_after(pos,load_config_list):
|
def get_before_and_after(self,pos,load_config_list):
|
||||||
""" get total values for forces and moments with polilyne distribution
|
""" get total values for forces and moments with polilyne distribution
|
||||||
before and after the position
|
before and after the position
|
||||||
ex: load_config_list = [[{"pos":1.0,...,"forces":(1,0,0),...},{"pos":3.0,...,"forces":(3,0,0),...}],
|
ex: load_config_list = [[{"pos":1.0,...,"forces":(1,0,0),...},{"pos":3.0,...,"forces":(3,0,0),...}],
|
||||||
@@ -1000,10 +1028,10 @@ def get_before_and_after(pos,load_config_list):
|
|||||||
moment_before += config[end]["moments"]
|
moment_before += config[end]["moments"]
|
||||||
|
|
||||||
elif end-start == 1:
|
elif end-start == 1:
|
||||||
force_before += interpolate(pos,config,start,end,"forces")
|
force_before += self.interpolate(pos,config,start,end,"forces")
|
||||||
force_after += interpolate(pos,config,start,end,"forces")
|
force_after += self.interpolate(pos,config,start,end,"forces")
|
||||||
moment_before += interpolate(pos,config,start,end,"moments")
|
moment_before += self.interpolate(pos,config,start,end,"moments")
|
||||||
moment_after += interpolate(pos,config,start,end,"moments")
|
moment_after += self.interpolate(pos,config,start,end,"moments")
|
||||||
start += 1
|
start += 1
|
||||||
end -=1
|
end -=1
|
||||||
return_value = {
|
return_value = {
|
||||||
@@ -1014,7 +1042,7 @@ def get_before_and_after(pos,load_config_list):
|
|||||||
}
|
}
|
||||||
return return_value
|
return return_value
|
||||||
|
|
||||||
def get_loads_dict(activity_list,global_to_local):
|
def get_loads_dict(self,activity_list,element_rotation_matrix):
|
||||||
"""
|
"""
|
||||||
get load list
|
get load list
|
||||||
activity_list: list of IfcStructuralCurveAction or IfcStructuralCurveReaction
|
activity_list: list of IfcStructuralCurveAction or IfcStructuralCurveReaction
|
||||||
@@ -1027,10 +1055,10 @@ def get_loads_dict(activity_list,global_to_local):
|
|||||||
quadratic distribution
|
quadratic distribution
|
||||||
"sinus force": (fx,fy,fz,mx,my,mz), -> sum of linear loads applied with
|
"sinus force": (fx,fy,fz,mx,my,mz), -> sum of linear loads applied with
|
||||||
sinus distribution
|
sinus distribution
|
||||||
"load configuration": list -> list of load configurations for linear
|
"lienar load configuration": list -> list of load configurations for linear
|
||||||
and polyline distributions of linear loads
|
and polyline distributions of linear loads
|
||||||
}
|
}
|
||||||
description of "load configuration":
|
description of "linear load configuration":
|
||||||
list[ -> one item (list)for each IfcStructuralCurveAction applied in the member
|
list[ -> one item (list)for each IfcStructuralCurveAction applied in the member
|
||||||
with IfcStructuralLoadConfiguration as the applied load
|
with IfcStructuralLoadConfiguration as the applied load
|
||||||
list[ -> one item (dict) for each item found in the
|
list[ -> one item (dict) for each item found in the
|
||||||
@@ -1050,31 +1078,36 @@ def get_loads_dict(activity_list,global_to_local):
|
|||||||
quadratic_moment = Vector((0,0,0))
|
quadratic_moment = Vector((0,0,0))
|
||||||
sinus_force = Vector((0,0,0))
|
sinus_force = Vector((0,0,0))
|
||||||
sinus_moment = Vector((0,0,0))
|
sinus_moment = Vector((0,0,0))
|
||||||
load_configurations = []
|
linear_load_configurations = []
|
||||||
|
point_load_configurations = []
|
||||||
|
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get(),"LENGTHUNIT")
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get(),"LENGTHUNIT")
|
||||||
|
|
||||||
def get_force_vector(load,transform_matrix):
|
def get_force_vector(load,transform_matrix,factor = 1.0):
|
||||||
x = 0 if getattr(load, 'LinearForceX', 0) is None else getattr(load, 'LinearForceX', 0)
|
x = 0 if getattr(load, 'LinearForceX', 0) is None else getattr(load, 'LinearForceX', 0)
|
||||||
y = 0 if getattr(load, 'LinearForceY', 0) is None else getattr(load, 'LinearForceY', 0)
|
y = 0 if getattr(load, 'LinearForceY', 0) is None else getattr(load, 'LinearForceY', 0)
|
||||||
z = 0 if getattr(load, 'LinearForceZ', 0) is None else getattr(load, 'LinearForceZ', 0)
|
z = 0 if getattr(load, 'LinearForceZ', 0) is None else getattr(load, 'LinearForceZ', 0)
|
||||||
return transform_matrix @ Vector((x,y,z))
|
return transform_matrix @ (Vector((x,y,z))*factor)
|
||||||
|
|
||||||
def get_moment_vector(load,transform_matrix):
|
def get_moment_vector(load,transform_matrix,factor = 1.0):
|
||||||
x = 0 if getattr(load, 'LinearMomentX', 0) is None else getattr(load, 'LinearMomentX', 0)
|
x = 0 if getattr(load, 'LinearMomentX', 0) is None else getattr(load, 'LinearMomentX', 0)
|
||||||
y = 0 if getattr(load, 'LinearMomentY', 0) is None else getattr(load, 'LinearMomentY', 0)
|
y = 0 if getattr(load, 'LinearMomentY', 0) is None else getattr(load, 'LinearMomentY', 0)
|
||||||
z = 0 if getattr(load, 'LinearMomentZ', 0) is None else getattr(load, 'LinearMomentZ', 0)
|
z = 0 if getattr(load, 'LinearMomentZ', 0) is None else getattr(load, 'LinearMomentZ', 0)
|
||||||
return transform_matrix @ Vector((x,y,z))
|
return transform_matrix @ (Vector((x,y,z))*factor)
|
||||||
|
|
||||||
for activity in activity_list:
|
for item in activity_list:
|
||||||
|
activity = item[0]
|
||||||
|
factor = item[1]
|
||||||
load = activity.AppliedLoad
|
load = activity.AppliedLoad
|
||||||
global_or_local = activity.GlobalOrLocal
|
global_or_local = activity.GlobalOrLocal
|
||||||
reference_frame = 'GLOBAL_COORDS' #make it a scene property so it can be changed in a panel
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
|
reference_frame = props.reference_frame #make it a scene property so it can be changed in a panel
|
||||||
transform_matrix = Matrix()
|
transform_matrix = Matrix()
|
||||||
if reference_frame == 'LOCAL_COORDS' and global_or_local != reference_frame:
|
if reference_frame == 'LOCAL_COORDS' and global_or_local != reference_frame:
|
||||||
transform_matrix = global_to_local
|
transform_matrix = element_rotation_matrix
|
||||||
|
transform_matrix.invert()
|
||||||
elif reference_frame == 'GLOBAL_COORDS' and global_or_local != reference_frame:
|
elif reference_frame == 'GLOBAL_COORDS' and global_or_local != reference_frame:
|
||||||
transform_matrix = global_to_local.invert()
|
transform_matrix = element_rotation_matrix
|
||||||
#values for linear loads
|
#values for linear loads
|
||||||
if load.is_a('IfcStructuralLoadConfiguration'):
|
if load.is_a('IfcStructuralLoadConfiguration'):
|
||||||
locations = getattr(load, 'Locations', [])
|
locations = getattr(load, 'Locations', [])
|
||||||
@@ -1083,8 +1116,8 @@ def get_loads_dict(activity_list,global_to_local):
|
|||||||
]
|
]
|
||||||
config_list = []
|
config_list = []
|
||||||
for i,l in enumerate(values):
|
for i,l in enumerate(values):
|
||||||
forcevalues = get_force_vector(l,transform_matrix)
|
forcevalues = get_force_vector(l,transform_matrix,factor)
|
||||||
momentvalues = get_moment_vector(l,transform_matrix)
|
momentvalues = get_moment_vector(l,transform_matrix,factor)
|
||||||
if i == 0:
|
if i == 0:
|
||||||
descr = 'start'
|
descr = 'start'
|
||||||
elif i == len(values)-1:
|
elif i == len(values)-1:
|
||||||
@@ -1097,10 +1130,27 @@ def get_loads_dict(activity_list,global_to_local):
|
|||||||
"forces":forcevalues,
|
"forces":forcevalues,
|
||||||
"moments":momentvalues}
|
"moments":momentvalues}
|
||||||
)
|
)
|
||||||
load_configurations.append(config_list)
|
linear_load_configurations.append(config_list)
|
||||||
|
#load configurations with point loads
|
||||||
|
values = [l for l in getattr(load, 'Values', None)
|
||||||
|
if l.is_a() == "IfcStructuralLoadSingleForce"
|
||||||
|
]
|
||||||
|
attr_list = ['ForceX','ForceY','ForceZ','MomentX','MomentY','MomentZ']
|
||||||
|
config_list = []
|
||||||
|
for i,load in enumerate(values):
|
||||||
|
result_list = [0,0,0,0,0,0]
|
||||||
|
for j, attr in enumerate(attr_list):
|
||||||
|
value = 0 if getattr(load, attr, 0) is None else getattr(load, attr, 0)
|
||||||
|
result_list[j] += value*factor
|
||||||
|
config_list.append(
|
||||||
|
{"pos": locations[i][0]*unit_scale,
|
||||||
|
"values": result_list}
|
||||||
|
)
|
||||||
|
point_load_configurations.append(config_list)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
forcevalues = get_force_vector(load,transform_matrix)
|
forcevalues = get_force_vector(load,transform_matrix,factor)
|
||||||
momentvalues = get_moment_vector(load,transform_matrix)
|
momentvalues = get_moment_vector(load,transform_matrix,factor)
|
||||||
if 'CONST' == getattr(activity, 'PredefinedType', None) or activity.is_a('IfcStructuralLinearAction'):
|
if 'CONST' == getattr(activity, 'PredefinedType', None) or activity.is_a('IfcStructuralLinearAction'):
|
||||||
constant_force += forcevalues
|
constant_force += forcevalues
|
||||||
constant_moment += momentvalues
|
constant_moment += momentvalues
|
||||||
@@ -1117,6 +1167,7 @@ def get_loads_dict(activity_list,global_to_local):
|
|||||||
quadratic_moment.x,quadratic_moment.y,quadratic_moment.z],
|
quadratic_moment.x,quadratic_moment.y,quadratic_moment.z],
|
||||||
"sinus force": [sinus_force.x,sinus_force.y,sinus_force.z,
|
"sinus force": [sinus_force.x,sinus_force.y,sinus_force.z,
|
||||||
sinus_moment.x,sinus_moment.y,sinus_moment.z],
|
sinus_moment.x,sinus_moment.y,sinus_moment.z],
|
||||||
"load configuration": load_configurations
|
"linear load configuration": linear_load_configurations,
|
||||||
|
"point load configuration": point_load_configurations
|
||||||
}
|
}
|
||||||
return return_value
|
return return_value
|
||||||
|
|||||||
Reference in New Issue
Block a user