mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-10 22:16:41 +00:00
shit ton of changes
This commit is contained in:
committed by
Dion Moult
parent
477725529b
commit
2912580087
@@ -99,3 +99,4 @@ src/ifcopenshell-python/ifcopenshell/ifcopenshell_wrapper.py
|
|||||||
# Brickschema
|
# Brickschema
|
||||||
src/bonsai/bonsai/bim/schema/Brick.ttl
|
src/bonsai/bonsai/bim/schema/Brick.ttl
|
||||||
bonsaiDecoratorForLoads.code-workspace
|
bonsaiDecoratorForLoads.code-workspace
|
||||||
|
dev_environment.bat
|
||||||
|
|||||||
@@ -30,6 +30,38 @@ def refresh():
|
|||||||
StructuralLoadCasesData.is_loaded = False
|
StructuralLoadCasesData.is_loaded = False
|
||||||
StructuralLoadsData.is_loaded = False
|
StructuralLoadsData.is_loaded = False
|
||||||
BoundaryConditionsData.is_loaded = False
|
BoundaryConditionsData.is_loaded = False
|
||||||
|
LoadGroupDecorationData.is_loaded = False
|
||||||
|
|
||||||
|
class LoadGroupDecorationData:
|
||||||
|
data = {}
|
||||||
|
is_loaded = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls):
|
||||||
|
cls.data = {"load groups to show": cls.load_groups_to_show()}
|
||||||
|
cls.is_loaded = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_groups_to_show(cls):
|
||||||
|
ret = []
|
||||||
|
abrv = {"LOAD_CASE": "L.Case: ",
|
||||||
|
"LOAD_COMBINATION": "L.Comb: ",
|
||||||
|
"LOAD_GROUP": "L.Gr: ",
|
||||||
|
"USERDEFINED": "U.Def: ",
|
||||||
|
"NOTDEFINED": "N.Def: "
|
||||||
|
}
|
||||||
|
models = tool.Ifc.get().by_type("IfcStructuralAnalysisModel")
|
||||||
|
m = models[0]
|
||||||
|
groups = m.LoadedBy or []
|
||||||
|
for g in groups:
|
||||||
|
ret.append((str(g.id()),". "+abrv[g.PredefinedType]+" "+g.Name,""))
|
||||||
|
related_objects = [rel.RelatedObjects for rel in g.IsGroupedBy]
|
||||||
|
for item in related_objects:
|
||||||
|
for subgoup in [sg for sg in item if sg.is_a("IfcStructuralLoadGroup")]:
|
||||||
|
ret.append((str(subgoup.id()),". "+abrv[subgoup.PredefinedType]+subgoup.Name,""))
|
||||||
|
if len(ret) == 0:
|
||||||
|
ret.append(("","",""))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class StructuralBoundaryConditionsData:
|
class StructuralBoundaryConditionsData:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from math import pi
|
from math import pi
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
|
import numpy as np
|
||||||
import bpy
|
import bpy
|
||||||
import gpu
|
import gpu
|
||||||
import blf
|
import blf
|
||||||
@@ -14,6 +15,7 @@ class LoadsDecorator:
|
|||||||
linear_load_shader = None
|
linear_load_shader = None
|
||||||
text_info = []
|
text_info = []
|
||||||
shader_info = []
|
shader_info = []
|
||||||
|
depth_array = None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def install(cls, context):
|
def install(cls, context):
|
||||||
@@ -28,7 +30,7 @@ class LoadsDecorator:
|
|||||||
# SpaceView3D.draw_handler_add(handler.draw_curve_loads, (context,), "WINDOW", "POST_VIEW")
|
# SpaceView3D.draw_handler_add(handler.draw_curve_loads, (context,), "WINDOW", "POST_VIEW")
|
||||||
#)
|
#)
|
||||||
cls.handlers.append(SpaceView3D.draw_handler_add(handler, (), "WINDOW", "POST_VIEW"))
|
cls.handlers.append(SpaceView3D.draw_handler_add(handler, (), "WINDOW", "POST_VIEW"))
|
||||||
cls.linear_load_shader = ShaderInfo("DistributedLoad")
|
cls.linear_load_shader = ShaderInfo()
|
||||||
cls.update(context)
|
cls.update(context)
|
||||||
cls.is_installed = True
|
cls.is_installed = True
|
||||||
|
|
||||||
@@ -52,7 +54,7 @@ class LoadsDecorator:
|
|||||||
original_blend = gpu.state.blend_get()
|
original_blend = gpu.state.blend_get()
|
||||||
gpu.state.blend_set('ALPHA')
|
gpu.state.blend_set('ALPHA')
|
||||||
original_depth_mask = gpu.state.depth_mask_get()
|
original_depth_mask = gpu.state.depth_mask_get()
|
||||||
gpu.state.depth_mask_set(True)
|
#gpu.state.depth_mask_set(True)
|
||||||
original_depth_test = gpu.state.depth_test_get()
|
original_depth_test = gpu.state.depth_test_get()
|
||||||
gpu.state.depth_test_set('LESS_EQUAL')
|
gpu.state.depth_test_set('LESS_EQUAL')
|
||||||
|
|
||||||
@@ -82,35 +84,52 @@ class LoadsDecorator:
|
|||||||
batch.draw(shader)
|
batch.draw(shader)
|
||||||
|
|
||||||
def draw_load_values(self, context):
|
def draw_load_values(self, context):
|
||||||
|
framebuffer = gpu.state.active_framebuffer_get()
|
||||||
|
viewport_info = gpu.state.viewport_get()
|
||||||
|
width = viewport_info[2]
|
||||||
|
height = viewport_info[3]
|
||||||
|
depth_buffer = framebuffer.read_depth(0, 0, width, height)
|
||||||
|
depth_array = np.array(depth_buffer.to_list())
|
||||||
|
|
||||||
|
f = context.area.spaces.active.clip_end
|
||||||
|
n = context.area.spaces.active.clip_start
|
||||||
|
|
||||||
|
self.depth_array = n / (f - (f - n) * depth_array) * (f - n)
|
||||||
|
|
||||||
for info in self.text_info:
|
for info in self.text_info:
|
||||||
text_position = location_3d_to_region_2d(info["position"],info["normal"],context)
|
text_position = self.location_3d_to_region_2d(info["position"],info["normal"],context)
|
||||||
if text_position is not None:
|
if text_position is not None:
|
||||||
font_id = 0 # , need to find out how best to get this.
|
font_id = 0 # , need to find out how best to get this.
|
||||||
# draw some text
|
# draw some text
|
||||||
blf.position(font_id, text_position[0], text_position[1], 0)
|
blf.position(font_id, text_position[0], text_position[1], text_position[2])
|
||||||
blf.size(font_id, 20.0)
|
blf.size(font_id, 20.0)
|
||||||
blf.color(font_id, 0.9, 0.9, 0.9, 1.0)
|
blf.color(font_id, 0.9, 0.9, 0.9, 1.0)
|
||||||
blf.draw(font_id, info["text"])
|
blf.draw(font_id, info["text"])
|
||||||
|
|
||||||
def location_3d_to_region_2d(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"""
|
||||||
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
|
||||||
point_view_space = view_matrix @ coord
|
point_view_space = view_matrix @ coord
|
||||||
|
|
||||||
|
|
||||||
if perspective == 'ORTHO' or -10 < point_view_space.z < 0:
|
if perspective == 'ORTHO' or -10 < point_view_space.z < 0:
|
||||||
prj = rv3d.perspective_matrix @ Vector((coord[0], coord[1], coord[2], 1.0))
|
prj = rv3d.perspective_matrix @ Vector((coord[0], coord[1], coord[2], 1.0))
|
||||||
width_half = context.region.width / 2.0
|
width_half = context.region.width / 2.0
|
||||||
height_half = context.region.height / 2.0
|
height_half = context.region.height / 2.0
|
||||||
co = Vector((width_half + width_half * (prj.x / prj.w),
|
co = Vector((width_half + width_half * (prj.x / prj.w),
|
||||||
height_half + height_half * (prj.y / prj.w),
|
height_half + height_half * (prj.y / prj.w),
|
||||||
))
|
point_view_space.z))
|
||||||
view_vector = view3d_utils.region_2d_to_vector_3d(context.region, rv3d, co)
|
if co[0]> context.region.width or co[1] > context.region.height or co[0] < 0 or co[1] < 0:
|
||||||
angle = abs(0.5*pi-normal.angle(view_vector))
|
return None
|
||||||
#if small view angle betwen the load and viewport
|
depth = self.depth_array[int(co[1])][int(co[0])]
|
||||||
if angle<0.05:
|
if -0.98*point_view_space.z > depth:
|
||||||
return None
|
return None
|
||||||
return co
|
view_vector = view3d_utils.region_2d_to_vector_3d(context.region, rv3d, co)
|
||||||
return None
|
angle = abs(0.5*pi-normal.angle(view_vector))
|
||||||
|
#if small view angle betwen the load and viewport
|
||||||
|
if angle<0.05:
|
||||||
|
return None
|
||||||
|
return co
|
||||||
|
return None
|
||||||
|
|||||||
@@ -51,8 +51,9 @@ class ShowLoads(bpy.types.Operator):
|
|||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
collection = bpy.data.collections["IfcStructuralItem"]
|
collection = bpy.data.collections["IfcStructuralItem"]
|
||||||
collection.hide_viewport = False
|
collection.hide_viewport = False
|
||||||
|
context.window.cursor_modal_set("WAIT")
|
||||||
LoadsDecorator.install(context)
|
LoadsDecorator.install(context)
|
||||||
LoadsDecorator.update(context)
|
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:
|
||||||
if area.type == 'VIEW_3D':
|
if area.type == 'VIEW_3D':
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import bpy
|
|||||||
import bonsai.tool as tool
|
import bonsai.tool as tool
|
||||||
from bonsai.bim.ifc import IfcStore
|
from bonsai.bim.ifc import IfcStore
|
||||||
from bonsai.bim.prop import StrProperty, Attribute
|
from bonsai.bim.prop import StrProperty, Attribute
|
||||||
from bonsai.bim.module.structural.data import StructuralLoadCasesData, StructuralLoadsData, BoundaryConditionsData
|
from bonsai.bim.module.structural.data import StructuralLoadCasesData, StructuralLoadsData, BoundaryConditionsData, LoadGroupDecorationData
|
||||||
from bpy.types import PropertyGroup
|
from bpy.types import PropertyGroup
|
||||||
from bpy.props import (
|
from bpy.props import (
|
||||||
PointerProperty,
|
PointerProperty,
|
||||||
@@ -34,6 +34,10 @@ from bpy.props import (
|
|||||||
CollectionProperty,
|
CollectionProperty,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def get_load_groups_to_show(self, context):
|
||||||
|
if not LoadGroupDecorationData.is_loaded:
|
||||||
|
LoadGroupDecorationData.load()
|
||||||
|
return LoadGroupDecorationData.data["load groups to show"]
|
||||||
|
|
||||||
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:
|
||||||
@@ -152,6 +156,17 @@ class BIMStructuralProperties(PropertyGroup):
|
|||||||
boundary_condition_attributes: CollectionProperty(name="Boundary Condition Attributes", type=Attribute)
|
boundary_condition_attributes: CollectionProperty(name="Boundary Condition Attributes", type=Attribute)
|
||||||
filtered_boundary_conditions: BoolProperty(name="Filtered Boundary Conditions", default=False)
|
filtered_boundary_conditions: BoolProperty(name="Filtered Boundary Conditions", default=False)
|
||||||
|
|
||||||
|
show_loads: BoolProperty(name="Show Loads", default=False)
|
||||||
|
update_load_repr: BoolProperty(name="Update Load Representation", default=False)
|
||||||
|
enable_repr_auto_update: BoolProperty(name="Auto Update", default=False)
|
||||||
|
reference_frame: EnumProperty(items=[("GLOBAL_COORDS","Global","Show loads in global reference frame"),
|
||||||
|
("LOCAL_COORDS","Local","Show loads in local reference frame")], name= "Reference Frame")
|
||||||
|
activity_type: EnumProperty(items=[("Action","Actions","Show actions loads"),
|
||||||
|
("External Reaction","External Reactions","Show reactions on boundary conditions"),
|
||||||
|
("Internal Reactions","Internal Reactions","Show internal reactions on members")],
|
||||||
|
name="Activity Type")
|
||||||
|
load_group_to_show: EnumProperty(items=get_load_groups_to_show, name="Load Groups")
|
||||||
|
|
||||||
|
|
||||||
class BIMObjectStructuralProperties(PropertyGroup):
|
class BIMObjectStructuralProperties(PropertyGroup):
|
||||||
boundary_condition_attributes: CollectionProperty(name="Boundary Condition Attributes", type=Attribute)
|
boundary_condition_attributes: CollectionProperty(name="Boundary Condition Attributes", type=Attribute)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import gpu
|
import gpu
|
||||||
|
import bmesh
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from math import sin
|
from math import sin
|
||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
@@ -11,152 +12,319 @@ from bonsai.bim.ifc import IfcStore
|
|||||||
|
|
||||||
|
|
||||||
class ShaderInfo:
|
class ShaderInfo:
|
||||||
def __init__(self,shader_type: str):
|
def __init__(self):
|
||||||
self.is_empty = True
|
self.is_empty = True
|
||||||
self.shader = None
|
#self.shader = None
|
||||||
self.shader_type = shader_type
|
#self.shader_type = shader_type
|
||||||
self.args = {}
|
#self.args = {}
|
||||||
self.indices = []
|
#self.indices = []
|
||||||
|
self.curve_members = []
|
||||||
|
self.point_members = []
|
||||||
|
self.surface_members = {}
|
||||||
self.text_info = []
|
self.text_info = []
|
||||||
self.info = []
|
self.info = []
|
||||||
|
self.force_unit = ""
|
||||||
|
self.linear_force_unit = ""
|
||||||
|
self.planar_force_unit = ""
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
self.info = []
|
self.info = []
|
||||||
|
self.get_force_units()
|
||||||
|
self.get_strucutural_elements_and_activities()
|
||||||
self.get_linear_loads()
|
self.get_linear_loads()
|
||||||
self.get_point_loads()
|
self.get_point_loads()
|
||||||
|
self.get_planar_loads_2()
|
||||||
if len(self.info):
|
if len(self.info):
|
||||||
self.is_empty = False
|
self.is_empty = False
|
||||||
|
|
||||||
|
def get_force_units(self):
|
||||||
|
def get_unit_symbol(unit: ifcopenshell.entity_instance) -> str:
|
||||||
|
prefix_symbols = {
|
||||||
|
"EXA": "E",
|
||||||
|
"PETA": "P",
|
||||||
|
"TERA": "T",
|
||||||
|
"GIGA": "G",
|
||||||
|
"MEGA": "M",
|
||||||
|
"KILO": "k",
|
||||||
|
"HECTO": "h",
|
||||||
|
"DECA": "da",
|
||||||
|
"DECI": "d",
|
||||||
|
"CENTI": "c",
|
||||||
|
"MILLI": "m",
|
||||||
|
"MICRO": "μ",
|
||||||
|
"NANO": "n",
|
||||||
|
"PICO": "p",
|
||||||
|
"FEMTO": "f",
|
||||||
|
"ATTO": "a",
|
||||||
|
}
|
||||||
|
|
||||||
|
unit_symbols = {
|
||||||
|
# si units
|
||||||
|
"CUBIC_METRE": "m3",
|
||||||
|
"GRAM": "g",
|
||||||
|
"SECOND": "s",
|
||||||
|
"SQUARE_METRE": "m2",
|
||||||
|
"METRE": "m",
|
||||||
|
"NEWTON": "N",
|
||||||
|
"PASCAL": "Pa",
|
||||||
|
# conversion based units
|
||||||
|
"pound-force": "lbf",
|
||||||
|
'pound-force per square inch': "psi",
|
||||||
|
"thou": "th",
|
||||||
|
"inch": "in",
|
||||||
|
"foot": "ft",
|
||||||
|
"yard": "yd",
|
||||||
|
"mile": "mi",
|
||||||
|
"square thou": "th2",
|
||||||
|
"square inch": "in2",
|
||||||
|
"square foot": "ft2",
|
||||||
|
"square yard": "yd2",
|
||||||
|
"acre": "ac",
|
||||||
|
"square mile": "mi2",
|
||||||
|
"cubic thou": "th3",
|
||||||
|
"cubic inch": "in3",
|
||||||
|
"cubic foot": "ft3",
|
||||||
|
"cubic yard": "yd3",
|
||||||
|
"cubic mile": "mi3",
|
||||||
|
"litre": "L",
|
||||||
|
"fluid ounce UK": "fl oz",
|
||||||
|
"fluid ounce US": "fl oz",
|
||||||
|
"pint UK": "pt",
|
||||||
|
"pint US": "pt",
|
||||||
|
"gallon UK": "gal",
|
||||||
|
"gallon US": "gal",
|
||||||
|
"degree": "°",
|
||||||
|
"ounce": "oz",
|
||||||
|
"pound": "lb",
|
||||||
|
"ton UK": "ton",
|
||||||
|
"ton US": "ton",
|
||||||
|
"lbf": "lbf",
|
||||||
|
"kip": "kip",
|
||||||
|
"psi": "psi",
|
||||||
|
"ksi": "ksi",
|
||||||
|
"minute": "min",
|
||||||
|
"hour": "hr",
|
||||||
|
"day": "day",
|
||||||
|
"btu": "btu",
|
||||||
|
"fahrenheit": "°F",
|
||||||
|
}
|
||||||
|
symbol = ""
|
||||||
|
if unit.is_a("IfcSIUnit"):
|
||||||
|
symbol += prefix_symbols.get(unit.Prefix, "")
|
||||||
|
symbol += unit_symbols.get(unit.Name.replace("METER", "METRE"), "?")
|
||||||
|
return symbol
|
||||||
|
|
||||||
|
force_units = [u for u in tool.Ifc.get().by_type("IfcNamedUnit")
|
||||||
|
if u.UnitType == "FORCEUNIT"]
|
||||||
|
linear_force_units = [u for u in tool.Ifc.get().by_type("IfcDerivedUnit")
|
||||||
|
if u.UnitType == "LINEARFORCEUNIT"]
|
||||||
|
planar_force_units = [u for u in tool.Ifc.get().by_type("IfcDerivedUnit")
|
||||||
|
if u.UnitType == "PLANARFORCEUNIT"]
|
||||||
|
|
||||||
|
conversion_force_unit = [u for u in force_units if u.is_a("IfcConversionBasedUnit")]
|
||||||
|
if len(conversion_force_unit) == 0:
|
||||||
|
conversion_force_unit.append(force_units[0])
|
||||||
|
self.force_unit = get_unit_symbol(conversion_force_unit[0])
|
||||||
|
first = ""
|
||||||
|
second = ""
|
||||||
|
for e in linear_force_units[0].Elements:
|
||||||
|
if e.Unit.UnitType == "FORCEUNIT":
|
||||||
|
first = get_unit_symbol(e.Unit)
|
||||||
|
if e.Unit.UnitType == "LENGTHUNIT":
|
||||||
|
second = get_unit_symbol(e.Unit)
|
||||||
|
self.linear_force_unit = first + "/" + second
|
||||||
|
first = ""
|
||||||
|
second = ""
|
||||||
|
for e in planar_force_units[0].Elements:
|
||||||
|
if e.Unit.UnitType == "FORCEUNIT":
|
||||||
|
first = get_unit_symbol(e.Unit)
|
||||||
|
if e.Unit.UnitType == "LENGTHUNIT":
|
||||||
|
second = get_unit_symbol(e.Unit)+"2"
|
||||||
|
if e.Unit.UnitType == "AREAUNIT":
|
||||||
|
second = get_unit_symbol(e.Unit)
|
||||||
|
self.planar_force_unit = first + "/" + second
|
||||||
|
|
||||||
|
def get_strucutural_elements_and_activities(self):
|
||||||
|
|
||||||
|
def populate_members_dict(dict_name,element, activity, factor):
|
||||||
|
dic = getattr(self,dict_name,None)
|
||||||
|
if dic is None:
|
||||||
|
return
|
||||||
|
member = dic.get(element.GlobalId)
|
||||||
|
if member is None:
|
||||||
|
dic.update({
|
||||||
|
element.GlobalId: {
|
||||||
|
"member": element,
|
||||||
|
"activities": [(activity,factor)]}
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
member["activities"].append((activity,factor))
|
||||||
|
|
||||||
|
def recursive_subgroups(groups, rec_limit, factor = 1):
|
||||||
|
if len(groups) == 0 or rec_limit == 0:
|
||||||
|
return None
|
||||||
|
for group in groups:
|
||||||
|
subgorups = []
|
||||||
|
activities = []
|
||||||
|
relationship = [rel for rel in group.IsGroupedBy]
|
||||||
|
group_coef = group.Coefficient if group.Coefficient is not None else 1.0
|
||||||
|
rel_factor = 1.0
|
||||||
|
|
||||||
|
for rel in relationship:
|
||||||
|
if rel.is_a("IfcRelAssignsToGroupByFactor"):
|
||||||
|
rel_factor = rel.Factor if rel.Factor is not None else 1.0
|
||||||
|
objects = rel.RelatedObjects
|
||||||
|
subgorups = [sg for sg in objects if sg.is_a("IfcStructuralLoadGroup")]
|
||||||
|
activities = [a for a in objects if a.is_a("IfcStructuralActivity")]
|
||||||
|
factor = factor*group_coef*rel_factor
|
||||||
|
for activity in activities:
|
||||||
|
if len(activity.AssignedToStructuralItem):
|
||||||
|
element = activity.AssignedToStructuralItem[0].RelatingElement
|
||||||
|
if element is not None:
|
||||||
|
if element.is_a("IfcStructuralCurveMember"):
|
||||||
|
self.curve_members.append(element)
|
||||||
|
elif element.is_a("IfcStructuralPoinConnection"):
|
||||||
|
self.point_members.append(element)
|
||||||
|
elif element.is_a("IfcStructuralSurfaceMember"):
|
||||||
|
populate_members_dict("surface_members",element,activity,factor)
|
||||||
|
recursive_subgroups(subgorups,rec_limit-1,factor=factor)
|
||||||
|
|
||||||
|
props = bpy.context.scene.BIMStructuralProperties
|
||||||
|
group_definition_id = int(props.load_group_to_show)
|
||||||
|
file = IfcStore.get_file()
|
||||||
|
groups = [file.by_id(group_definition_id)]
|
||||||
|
recursive_subgroups(groups,10)
|
||||||
|
|
||||||
|
|
||||||
def get_shader(self, pattern):
|
def get_shader(self, pattern):
|
||||||
""" param: pattern: type of pattern in ["force", "force match", "moment"]
|
""" param: pattern: type of pattern in ["force", "force match", "moment"]
|
||||||
return: shader"""
|
return: shader"""
|
||||||
if self.shader_type == "DistributedLoad":
|
#if self.shader_type == "DistributedLoad":
|
||||||
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
|
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
|
||||||
vert_out.smooth('VEC3', "forces")
|
vert_out.smooth('VEC3', "forces")
|
||||||
vert_out.smooth('VEC3', "co")
|
vert_out.smooth('VEC3', "co")
|
||||||
|
|
||||||
shader_info = gpu.types.GPUShaderCreateInfo()
|
shader_info = gpu.types.GPUShaderCreateInfo()
|
||||||
shader_info.push_constant('MAT4', "viewProjectionMatrix")
|
shader_info.push_constant('MAT4', "viewProjectionMatrix")
|
||||||
shader_info.push_constant('VEC4', "color")
|
shader_info.push_constant('VEC4', "color")
|
||||||
shader_info.push_constant('FLOAT', "spacing")
|
shader_info.push_constant('FLOAT', "spacing")
|
||||||
shader_info.push_constant('FLOAT', "maxload")
|
shader_info.push_constant('FLOAT', "maxload")
|
||||||
|
|
||||||
shader_info.vertex_in(0, 'VEC3', "position")
|
shader_info.vertex_in(0, 'VEC3', "position")
|
||||||
shader_info.vertex_in(1, 'VEC3', "sin_quad_lin_forces")
|
shader_info.vertex_in(1, 'VEC3', "sin_quad_lin_forces")
|
||||||
shader_info.vertex_in(2, 'VEC3', "coord")
|
shader_info.vertex_in(2, 'VEC3', "coord")
|
||||||
|
|
||||||
shader_info.vertex_out(vert_out)
|
shader_info.vertex_out(vert_out)
|
||||||
shader_info.fragment_out(0, 'VEC4', "FragColor")
|
shader_info.fragment_out(0, 'VEC4', "FragColor")
|
||||||
|
|
||||||
shader_info.vertex_source(
|
shader_info.vertex_source(
|
||||||
"void main()"
|
|
||||||
"{"
|
|
||||||
" gl_Position = viewProjectionMatrix * vec4(position, 1.0f);"
|
|
||||||
" co = coord;"
|
|
||||||
" forces = sin_quad_lin_forces;"
|
|
||||||
" gl_Position = viewProjectionMatrix * vec4(position, 1.0f);"
|
|
||||||
"}"
|
|
||||||
)
|
|
||||||
|
|
||||||
if pattern == "force":
|
|
||||||
shader_info.fragment_source(
|
|
||||||
"void main()"
|
"void main()"
|
||||||
"{"
|
"{"
|
||||||
"float x = co.x;"
|
" gl_Position = viewProjectionMatrix * vec4(position, 1.0f);"
|
||||||
"float y = co.y;"
|
" co = coord;"
|
||||||
"float abs_y = abs(y);"
|
" forces = sin_quad_lin_forces;"
|
||||||
|
|
||||||
"float a = abs(mod(x,spacing)-0.5*spacing)*5.0;"
|
|
||||||
"float b = step(a,abs_y)*(step(abs_y,1.2*spacing));"
|
|
||||||
"float c = step(0.8*spacing,mod(x+0.4*spacing,spacing))*(step(1.2*spacing,abs_y));"
|
|
||||||
|
|
||||||
"float sinvalue = forces.x;"
|
|
||||||
"float quadraticvalue = forces.y;"
|
|
||||||
"float linearvalue = forces.z;"
|
|
||||||
"x = co.x/co.z;"
|
|
||||||
"float f = (sin(x*3.1416)*sinvalue"
|
|
||||||
"+(-4.*x*x+4.*x)*quadraticvalue"
|
|
||||||
"+linearvalue)/maxload;"
|
|
||||||
"float mask = step(0.,y)*step(y,f)+step(y,0.)*step(f,y);"
|
|
||||||
|
|
||||||
"float top = step(abs(y-f),0.2*1.2*spacing);"
|
|
||||||
"float d = clamp(0.1+top+b+c,0.0,0.5)*mask;"
|
|
||||||
"if (d == 0.0) discard;"
|
|
||||||
"FragColor = vec4(color.xyz,d*color.w);"
|
|
||||||
"}"
|
"}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if pattern == "force match":
|
if pattern == "force":
|
||||||
shader_info.fragment_source(
|
shader_info.fragment_source(
|
||||||
"void main()"
|
"void main()"
|
||||||
"{"
|
"{"
|
||||||
"float y = co.y;"
|
"float x = co.x;"
|
||||||
"float x = step(0.,y)*(co.z-co.x)+step(y,0.)*(co.x);"
|
"float y = co.y;"
|
||||||
"float abs_y = abs(y);"
|
"float abs_y = abs(y);"
|
||||||
|
|
||||||
"float a = abs(mod(abs_y,spacing)-0.5*spacing)*5.0;"
|
"float a = abs(mod(x,spacing)-0.5*spacing)*5.0;"
|
||||||
"float a2 = mod(x,3.0*spacing);"
|
"float b = step(a,abs_y)*(step(abs_y,1.2*spacing));"
|
||||||
"float b = step(a,a2)*step(a2,1.2*spacing);"
|
"float c = step(0.8*spacing,mod(x+0.4*spacing,spacing))*(step(1.2*spacing,abs_y));"
|
||||||
"float c = step(0.8*spacing,mod(abs_y+0.4*spacing,spacing))"
|
|
||||||
"*(step(1.2*spacing,a2))*step(a2,2.5*spacing);"
|
|
||||||
"float sinvalue = forces.x;"
|
|
||||||
"float quadraticvalue = forces.y;"
|
|
||||||
"float linearvalue = forces.z;"
|
|
||||||
"x = co.x/co.z;"
|
|
||||||
"float f = (sin(x*3.1416)*sinvalue"
|
|
||||||
"+(-4.*x*x+4.*x)*quadraticvalue"
|
|
||||||
"+linearvalue)/maxload;"
|
|
||||||
"float mask = step(0.,y)*step(y,f)+step(y,0.)*step(f,y);"
|
|
||||||
|
|
||||||
"float top = step(abs(y-f),0.2*1.2*spacing);"
|
"float sinvalue = forces.x;"
|
||||||
"float d = clamp(0.1+top+b+c,0.0,0.5)*mask;"
|
"float quadraticvalue = forces.y;"
|
||||||
"if (d == 0.0) discard;"
|
"float linearvalue = forces.z;"
|
||||||
"FragColor = vec4(color.xyz,d*color.w);"
|
"x = co.x/co.z;"
|
||||||
"}"
|
"float f = (sin(x*3.1416)*sinvalue"
|
||||||
)
|
"+(-4.*x*x+4.*x)*quadraticvalue"
|
||||||
|
"+linearvalue)/maxload;"
|
||||||
|
"float mask = step(0.,y)*step(y,f)+step(y,0.)*step(f,y);"
|
||||||
|
|
||||||
if pattern == "moment":
|
"float top = step(abs(y-f),0.2*1.2*spacing);"
|
||||||
shader_info.fragment_source(
|
"float d = clamp(top+b+c,0.0,0.9)*mask;"
|
||||||
"void main()"
|
"if (d == 0.0) discard;"
|
||||||
"{"
|
"FragColor = vec4(color.xyz,d*color.w);"
|
||||||
"float x = step(co.y,0.)*(co.x)+step(0.,co.y)*(co.z-co.x);"
|
"}"
|
||||||
"float y = step(co.y,-0.00001)*(co.y)+step(0.,co.y)*(0.-co.y);"
|
)
|
||||||
"x = mod((0.5/spacing)*x,1.4)-0.7;"
|
|
||||||
"y = mod((0.5/spacing)*y,1.4)-0.7;"
|
|
||||||
"float abs_y = abs(y);"
|
|
||||||
"vec2 st = vec2(1.9*x,y);"
|
|
||||||
"vec2 orig = vec2(0.,0.);"
|
|
||||||
|
|
||||||
"float circ = step(distance(st,orig),0.33)*step(0.27,distance(st,orig));"
|
if pattern == "force match":
|
||||||
"float tri_mask = step(st.y,st.x)+step(-st.x,st.y);"
|
shader_info.fragment_source(
|
||||||
"float circ_arrow = step(st.x,4.0*st.y-0.75)*step(0.25*st.y-0.34,st.x)*(1.-tri_mask);"
|
"void main()"
|
||||||
|
"{"
|
||||||
|
"float y = co.y;"
|
||||||
|
"float x = step(0.,y)*(co.z-co.x)+step(y,0.)*(co.x);"
|
||||||
|
"float abs_y = abs(y);"
|
||||||
|
|
||||||
"float circmask = step(distance(st,orig),0.1)+step(0.5,distance(st,orig))+step(st.x,0.);"
|
"float a = abs(mod(abs_y,spacing)-0.5*spacing)*5.0;"
|
||||||
"float body = step(-0.03,st.y)*step(st.y,0.03)*step(-0.3,x)*step(x,0.576);"
|
"float a2 = mod(x,3.0*spacing);"
|
||||||
"float body_arrow = step(-0.5+3.*st.y,x)*step(-0.5-3.*st.y,x)*step(x,-0.3);"
|
"float b = step(a,a2)*step(a2,1.2*spacing);"
|
||||||
"float d = clamp(circmask*(body+body_arrow)+circ_arrow+circ*tri_mask,0.,1.);"
|
"float c = step(0.8*spacing,mod(abs_y+0.4*spacing,spacing))"
|
||||||
|
"*(step(1.2*spacing,a2))*step(a2,2.5*spacing);"
|
||||||
|
"float sinvalue = forces.x;"
|
||||||
|
"float quadraticvalue = forces.y;"
|
||||||
|
"float linearvalue = forces.z;"
|
||||||
|
"x = co.x/co.z;"
|
||||||
|
"float f = (sin(x*3.1416)*sinvalue"
|
||||||
|
"+(-4.*x*x+4.*x)*quadraticvalue"
|
||||||
|
"+linearvalue)/maxload;"
|
||||||
|
"float mask = step(0.,y)*step(y,f)+step(y,0.)*step(f,y);"
|
||||||
|
|
||||||
"float sinvalue = forces.x;"
|
"float top = step(abs(y-f),0.2*1.2*spacing);"
|
||||||
"float quadraticvalue = forces.y;"
|
"float d = clamp(top+b+c,0.0,0.9)*mask;"
|
||||||
"float linearvalue = forces.z;"
|
"if (d == 0.0) discard;"
|
||||||
"x = co.x/co.z;"
|
"FragColor = vec4(color.xyz,d*color.w);"
|
||||||
"float f = (sin(x*3.1416)*sinvalue"
|
"}"
|
||||||
"+(-4.*x*x+4.*x)*quadraticvalue"
|
)
|
||||||
"+linearvalue)/maxload;"
|
|
||||||
"float mask = step(0.,co.y)*step(co.y,f)+step(co.y,0.)*step(f,co.y);"
|
|
||||||
|
|
||||||
"float top = step(abs(co.y-f),0.2*1.2*spacing);"
|
if pattern == "moment":
|
||||||
|
shader_info.fragment_source(
|
||||||
|
"void main()"
|
||||||
|
"{"
|
||||||
|
"float x = step(co.y,0.)*(co.x)+step(0.,co.y)*(co.z-co.x);"
|
||||||
|
"float y = step(co.y,-0.00001)*(co.y)+step(0.,co.y)*(0.-co.y);"
|
||||||
|
"x = mod((0.5/spacing)*x,1.4)-0.7;"
|
||||||
|
"y = mod((0.5/spacing)*y,1.4)-0.7;"
|
||||||
|
"float abs_y = abs(y);"
|
||||||
|
"vec2 st = vec2(1.9*x,y);"
|
||||||
|
"vec2 orig = vec2(0.,0.);"
|
||||||
|
|
||||||
"d = clamp(0.1+top+d,0.0,0.5)*mask;"
|
"float circ = step(distance(st,orig),0.33)*step(0.27,distance(st,orig));"
|
||||||
"if (d == 0.0) discard;"
|
"float tri_mask = step(st.y,st.x)+step(-st.x,st.y);"
|
||||||
"FragColor = vec4(color.xyz,d*color.w);"
|
"float circ_arrow = step(st.x,4.0*st.y-0.75)*step(0.25*st.y-0.34,st.x)*(1.-tri_mask);"
|
||||||
"}"
|
|
||||||
)
|
|
||||||
|
|
||||||
shader = gpu.shader.create_from_info(shader_info)
|
"float circmask = step(distance(st,orig),0.1)+step(0.5,distance(st,orig))+step(st.x,0.);"
|
||||||
del vert_out
|
"float body = step(-0.03,st.y)*step(st.y,0.03)*step(-0.3,x)*step(x,0.576);"
|
||||||
del shader_info
|
"float body_arrow = step(-0.5+3.*st.y,x)*step(-0.5-3.*st.y,x)*step(x,-0.3);"
|
||||||
return shader
|
"float d = clamp(circmask*(body+body_arrow)+circ_arrow+circ*tri_mask,0.,1.);"
|
||||||
|
|
||||||
|
"float sinvalue = forces.x;"
|
||||||
|
"float quadraticvalue = forces.y;"
|
||||||
|
"float linearvalue = forces.z;"
|
||||||
|
"x = co.x/co.z;"
|
||||||
|
"float f = (sin(x*3.1416)*sinvalue"
|
||||||
|
"+(-4.*x*x+4.*x)*quadraticvalue"
|
||||||
|
"+linearvalue)/maxload;"
|
||||||
|
"float mask = step(0.,co.y)*step(co.y,f)+step(co.y,0.)*step(f,co.y);"
|
||||||
|
|
||||||
|
"float top = step(abs(co.y-f),0.2*1.2*spacing);"
|
||||||
|
|
||||||
|
"d = clamp(top+d,0.0,0.9)*mask;"
|
||||||
|
"if (d == 0.0) discard;"
|
||||||
|
"FragColor = vec4(color.xyz,d*color.w);"
|
||||||
|
"}"
|
||||||
|
)
|
||||||
|
|
||||||
|
shader = gpu.shader.create_from_info(shader_info)
|
||||||
|
del vert_out
|
||||||
|
del shader_info
|
||||||
|
return shader
|
||||||
|
|
||||||
def get_point_shader(self, pattern):
|
def get_point_shader(self, pattern):
|
||||||
""" param: pattern: type of pattern in ["arrow", "circ arrow"]
|
""" param: pattern: type of pattern in ["arrow", "circ arrow"]
|
||||||
@@ -213,6 +381,220 @@ class ShaderInfo:
|
|||||||
del shader_info
|
del shader_info
|
||||||
return shader
|
return shader
|
||||||
|
|
||||||
|
def get_planar_shader(self):
|
||||||
|
""" param: pattern: type of pattern in ["force", "force match", "moment"]
|
||||||
|
return: shader"""
|
||||||
|
#if self.shader_type == "DistributedLoad":
|
||||||
|
vert_out = gpu.types.GPUStageInterfaceInfo("my_interface")
|
||||||
|
vert_out.smooth('VEC3', "co")
|
||||||
|
|
||||||
|
shader_info = gpu.types.GPUShaderCreateInfo()
|
||||||
|
shader_info.push_constant('MAT4', "viewProjectionMatrix")
|
||||||
|
shader_info.push_constant('VEC4', "color")
|
||||||
|
shader_info.push_constant('FLOAT', "spacing")
|
||||||
|
|
||||||
|
shader_info.vertex_in(0, 'VEC3', "position")
|
||||||
|
shader_info.vertex_in(1, 'VEC3', "coord")
|
||||||
|
|
||||||
|
shader_info.vertex_out(vert_out)
|
||||||
|
shader_info.fragment_out(0, 'VEC4', "FragColor")
|
||||||
|
|
||||||
|
shader_info.vertex_source(
|
||||||
|
"void main()"
|
||||||
|
"{"
|
||||||
|
" gl_Position = viewProjectionMatrix * vec4(position, 1.0f);"
|
||||||
|
" co = coord;"
|
||||||
|
"}"
|
||||||
|
)
|
||||||
|
|
||||||
|
shader_info.fragment_source(
|
||||||
|
"void main()"
|
||||||
|
"{"
|
||||||
|
"float x = co.x;"
|
||||||
|
"float y = co.y;"
|
||||||
|
"float abs_y = abs(y);"
|
||||||
|
|
||||||
|
"float a = abs(mod(x,spacing)-0.5*spacing)*5.0;"
|
||||||
|
"float b = step(a,abs_y)*(step(abs_y,1.2*spacing));"
|
||||||
|
"float c = step(0.8*spacing,mod(x+0.4*spacing,spacing))*(step(1.2*spacing,abs_y));"
|
||||||
|
|
||||||
|
|
||||||
|
"float mask = step(0.,y)*step(y,0.98)+step(y,0.)*step(0.98,y);"
|
||||||
|
|
||||||
|
"float top = step(abs(y-0.98),0.2*1.2*spacing);"
|
||||||
|
"float d = clamp(0.2*y+(top+b+c)*mask,0.0,0.4);"
|
||||||
|
"FragColor = vec4(color.xyz,d*color.w);"
|
||||||
|
"}"
|
||||||
|
)#"float d = clamp(0.1+top+b+c,0.0,0.4);"
|
||||||
|
|
||||||
|
shader = gpu.shader.create_from_info(shader_info)
|
||||||
|
del vert_out
|
||||||
|
del shader_info
|
||||||
|
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):
|
||||||
|
list_of_surfaces = self.surface_members
|
||||||
|
shader = self.get_planar_shader()
|
||||||
|
maximum = 0
|
||||||
|
for value in list_of_surfaces.values():
|
||||||
|
surf = value["member"]
|
||||||
|
activity_list = [getattr(a, 'RelatedStructuralActivity', None) for a in getattr(surf, 'AssignedStructuralActivity', None)
|
||||||
|
if getattr(a, 'RelatedStructuralActivity', None).is_a() in ['IfcStructuralPlanarAction','IfcStructuralSurfaceAction']]
|
||||||
|
activity_list = value["activities"]
|
||||||
|
if len(activity_list) == 0:
|
||||||
|
continue
|
||||||
|
values = self.get_planar_loads_values(activity_list)
|
||||||
|
if maximum == 0:
|
||||||
|
maximum = max([abs(float(i)) for i in values])
|
||||||
|
if maximum == 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
|
||||||
|
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 = []
|
||||||
|
indices = []
|
||||||
|
coord = []
|
||||||
|
bm = bmesh.new()
|
||||||
|
bm.from_mesh(mesh)
|
||||||
|
bmesh.ops.triangulate(bm, faces = bm.faces)
|
||||||
|
bm.edges.ensure_lookup_table()
|
||||||
|
bm.verts.ensure_lookup_table()
|
||||||
|
bm.faces.ensure_lookup_table()
|
||||||
|
|
||||||
|
add_index = len(positions)
|
||||||
|
for v in bm.verts:
|
||||||
|
p1 = np.array(mat @ v.co)
|
||||||
|
positions.append(p1)
|
||||||
|
p2 = p1 - (rotation@values)*0.2/maximum
|
||||||
|
positions.append(p2)
|
||||||
|
coord.append((float(p1[0]+p1[1]),0,1))
|
||||||
|
coord.append((float(p1[0]+p1[1]),1,1))
|
||||||
|
for e in bm.edges:
|
||||||
|
if len(e.link_faces) > 1:
|
||||||
|
continue
|
||||||
|
indices.append((2*e.verts[0].index,
|
||||||
|
2*e.verts[0].index+1,
|
||||||
|
2*e.verts[1].index))
|
||||||
|
indices.append((2*e.verts[0].index+1,
|
||||||
|
2*e.verts[1].index,
|
||||||
|
2*e.verts[1].index+1))
|
||||||
|
for p in bm.faces:
|
||||||
|
indices.append((2*p.verts[0].index+1,
|
||||||
|
2*p.verts[1].index+1,
|
||||||
|
2*p.verts[2].index+1))
|
||||||
|
bmesh.ops.dissolve_limit(bm, angle_limit = 0.01, verts = bm.verts, edges = bm.edges)
|
||||||
|
bm.faces.ensure_lookup_table()
|
||||||
|
center = bm.faces[0].calc_center_bounds()
|
||||||
|
|
||||||
|
self.text_info.append(
|
||||||
|
{"position": mat @ center - Vector((rotation@values)*0.2/maximum),
|
||||||
|
"normal": Vector(mesh.polygons[0].normal),
|
||||||
|
"text": f'{values[2]:.5f} {self.planar_force_unit}'}
|
||||||
|
)
|
||||||
|
|
||||||
|
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_values(self, activity_list):
|
||||||
|
values = np.zeros((3))
|
||||||
|
for item in activity_list:
|
||||||
|
activity = item[0]
|
||||||
|
factor = item[1]
|
||||||
|
load = activity.AppliedLoad
|
||||||
|
temp = np.zeros((3))
|
||||||
|
if load is not None and load.is_a("IfcStructuralLoadPlanarForce"):
|
||||||
|
temp[0] = load.PlanarForceX if load.PlanarForceX 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 = temp*factor
|
||||||
|
values = values + temp
|
||||||
|
return values
|
||||||
|
|
||||||
|
def get_surface_member_rotation(self,surface_member):
|
||||||
|
representation = ifcopenshell.util.representation.get_representation(surface_member, "Model")
|
||||||
|
repr_item = representation.Items[0]
|
||||||
|
placement = ifcopenshell.util.placement.get_axis2placement(repr_item.FaceSurface.Position)
|
||||||
|
rotation = placement[0:3,0:3]
|
||||||
|
return rotation
|
||||||
|
|
||||||
|
def get_point_connection_rotation(self, point_connection):
|
||||||
|
if point_connection.ConditionCoordinateSystem is not None:
|
||||||
|
placement = ifcopenshell.util.placement.get_axis2placement(point_connection.ConditionCoordinateSystem)
|
||||||
|
else:
|
||||||
|
placement = np.eye(4)
|
||||||
|
rotation = placement[0:3,0:3]
|
||||||
|
return rotation
|
||||||
|
|
||||||
|
def get_curve_member_rotation(self, curve_member):
|
||||||
|
z = curve_member.Axis.DirectionRatios
|
||||||
|
edge = curve_member.Representation.Representations[0].Items[0]
|
||||||
|
origin = edge.EdgeStart.VertexGeometry.Coordinates
|
||||||
|
end = edge.EdgeEnd.VertexGeometry.Coordinates
|
||||||
|
x = [c2 - c1 for c1, c2 in zip(origin, end)]
|
||||||
|
placement = ifcopenshell.util.placement.a2p(origin,z,x)
|
||||||
|
rotation = placement[0:3,0:3]
|
||||||
|
return rotation
|
||||||
|
|
||||||
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:
|
for conn in list_of_point_connections:
|
||||||
@@ -223,9 +605,9 @@ class ShaderInfo:
|
|||||||
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)
|
loads = self.get_point_loads_list(activity_list)
|
||||||
self.get_point_shader_args(loads, conn_location)
|
self.get_point_shader_args(loads, conn_location)
|
||||||
|
|
||||||
def get_point_shader_args(self,loads, location):
|
def get_point_shader_args(self,loads, location):
|
||||||
indices = []
|
indices = []
|
||||||
@@ -288,7 +670,7 @@ class ShaderInfo:
|
|||||||
"shader": shader,
|
"shader": shader,
|
||||||
"args": {"position": position,"coord": coords_for_shader},
|
"args": {"position": position,"coord": coords_for_shader},
|
||||||
"indices": indices,
|
"indices": indices,
|
||||||
"uniforms": [["color", color]]#,["spacing", 0.2]]
|
"uniforms": [["color", color]]
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -316,6 +698,7 @@ class ShaderInfo:
|
|||||||
info = []
|
info = []
|
||||||
|
|
||||||
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
|
||||||
for member in list_of_curve_members:
|
for member in list_of_curve_members:
|
||||||
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']]
|
||||||
@@ -403,7 +786,8 @@ class ShaderInfo:
|
|||||||
if func:
|
if func:
|
||||||
text_info.append(
|
text_info.append(
|
||||||
{"position": -1*direction*func/maxforce + start_co + x_axis*current.x,
|
{"position": -1*direction*func/maxforce + start_co + x_axis*current.x,
|
||||||
"normal": direction.cross(x_axis).normalized(), "text": f'{func:.2f} '}
|
"normal": direction.cross(x_axis).normalized(),
|
||||||
|
"text": f'{func:.2f} {self.linear_force_unit}'}
|
||||||
)
|
)
|
||||||
maxforce = max(maxforce,abs(func))
|
maxforce = max(maxforce,abs(func))
|
||||||
position.append(positive)
|
position.append(positive)
|
||||||
@@ -430,7 +814,8 @@ class ShaderInfo:
|
|||||||
if func:
|
if func:
|
||||||
text_info.append(
|
text_info.append(
|
||||||
{"position": -1*direction*func/maxforce + start_co + x_axis*nextitem.x,
|
{"position": -1*direction*func/maxforce + start_co + x_axis*nextitem.x,
|
||||||
"normal": direction.cross(x_axis).normalized(), "text": f'{func:.2f} '}
|
"normal": direction.cross(x_axis).normalized(),
|
||||||
|
"text": f'{func:.2f} {self.linear_force_unit}'}
|
||||||
)
|
)
|
||||||
maxforce = max(maxforce,abs(func))
|
maxforce = max(maxforce,abs(func))
|
||||||
position.append(positive)
|
position.append(positive)
|
||||||
|
|||||||
@@ -465,8 +465,14 @@ class BIM_PT_show_structural_activities(Panel):
|
|||||||
row.operator(
|
row.operator(
|
||||||
"bim.show_loads",
|
"bim.show_loads",
|
||||||
text="Show loads" ,
|
text="Show loads" ,
|
||||||
icon="FILTER",
|
icon="HIDE_OFF",
|
||||||
)
|
)
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.prop(self.props,"reference_frame")
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.prop(self.props,"activity_type")
|
||||||
|
row = self.layout.row(align=True)
|
||||||
|
row.prop(self.props,"load_group_to_show")
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_structural_loads(Panel):
|
class BIM_PT_structural_loads(Panel):
|
||||||
|
|||||||
Reference in New Issue
Block a user