mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Dumb slabs now roundtrip the Blender solidify modifier
This commit is contained in:
@@ -14,6 +14,7 @@ class IfcStore:
|
||||
pset_template_file = None
|
||||
library_path = ""
|
||||
library_file = None
|
||||
element_listeners = set()
|
||||
|
||||
@staticmethod
|
||||
def purge():
|
||||
@@ -60,6 +61,10 @@ class IfcStore:
|
||||
return
|
||||
return obj
|
||||
|
||||
@staticmethod
|
||||
def add_element_listener(callback):
|
||||
IfcStore.element_listeners.add(callback)
|
||||
|
||||
@staticmethod
|
||||
def link_element(element, obj):
|
||||
IfcStore.id_map[element.id()] = obj
|
||||
@@ -68,6 +73,8 @@ class IfcStore:
|
||||
obj.BIMObjectProperties.ifc_definition_id = element.id()
|
||||
blenderbim.bim.handler.subscribe_to(obj, "mode", blenderbim.bim.handler.mode_callback)
|
||||
blenderbim.bim.handler.subscribe_to(obj, "name", blenderbim.bim.handler.name_callback)
|
||||
for listener in IfcStore.element_listeners:
|
||||
listener(element, obj)
|
||||
|
||||
@staticmethod
|
||||
def unlink_element(element=None, obj=None):
|
||||
|
||||
@@ -2,15 +2,19 @@ import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
from blenderbim.bim.module.model import product, wall, slab
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from bpy.app.handlers import persistent
|
||||
|
||||
|
||||
@persistent
|
||||
def load_post(*args):
|
||||
ifcopenshell.api.add_post_listener("geometry.add_representation", None, product.generate_box)
|
||||
|
||||
ifcopenshell.api.add_post_listener("geometry.add_representation", None, wall.generate_axis)
|
||||
ifcopenshell.api.add_post_listener("geometry.add_representation", None, wall.calculate_quantities)
|
||||
ifcopenshell.api.add_pre_listener("material.edit_layer", None, wall.DumbWallPlaner().regenerate_from_layer)
|
||||
ifcopenshell.api.add_pre_listener("type.assign_type", None, wall.DumbWallPlaner().regenerate_from_type)
|
||||
|
||||
IfcStore.add_element_listener(slab.element_listener)
|
||||
ifcopenshell.api.add_pre_listener("material.edit_layer", None, slab.DumbSlabPlaner().regenerate_from_layer)
|
||||
ifcopenshell.api.add_pre_listener("type.assign_type", None, slab.DumbSlabPlaner().regenerate_from_type)
|
||||
|
||||
@@ -5,12 +5,53 @@ import ifcopenshell
|
||||
import ifcopenshell.util.type
|
||||
import ifcopenshell.util.unit
|
||||
import mathutils.geometry
|
||||
import blenderbim.bim.handler
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from math import pi, degrees
|
||||
from mathutils import Vector, Matrix
|
||||
from ifcopenshell.api.material.data import Data as MaterialData
|
||||
|
||||
|
||||
def element_listener(element, obj):
|
||||
blenderbim.bim.handler.subscribe_to(obj, "mode", mode_callback)
|
||||
|
||||
|
||||
def mode_callback(obj, data):
|
||||
for obj in bpy.context.selected_objects + [bpy.context.active_object]:
|
||||
if (
|
||||
obj.mode != "EDIT"
|
||||
or not obj.data
|
||||
or not isinstance(obj.data, (bpy.types.Mesh, bpy.types.Curve, bpy.types.TextCurve))
|
||||
or not obj.BIMObjectProperties.ifc_definition_id
|
||||
or not bpy.context.scene.BIMProjectProperties.is_authoring
|
||||
):
|
||||
return
|
||||
product = IfcStore.get_file().by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||
parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric")
|
||||
if parametric and parametric["Engine"] != "BlenderBIM.DumbSlab":
|
||||
return
|
||||
modifier = [m for m in obj.modifiers if m.type == "SOLIDIFY"]
|
||||
if modifier:
|
||||
return
|
||||
depth = obj.dimensions.z
|
||||
bm = bmesh.from_edit_mesh(obj.data)
|
||||
bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 1, verts=bm.verts, edges=bm.edges)
|
||||
bm.faces.ensure_lookup_table()
|
||||
non_bottom_faces = []
|
||||
for face in bm.faces:
|
||||
if face.normal.z > -0.9:
|
||||
non_bottom_faces.append(face)
|
||||
else:
|
||||
face.normal_flip()
|
||||
bmesh.ops.delete(bm, geom=non_bottom_faces, context="FACES")
|
||||
bmesh.update_edit_mesh(obj.data)
|
||||
bm.free()
|
||||
modifier = obj.modifiers.new("Slab Depth", "SOLIDIFY")
|
||||
modifier.use_even_offset = True
|
||||
modifier.offset = 1
|
||||
modifier.thickness = depth
|
||||
|
||||
|
||||
class DumbSlabGenerator:
|
||||
def __init__(self, relating_type):
|
||||
self.relating_type = relating_type
|
||||
|
||||
@@ -686,7 +686,6 @@ class DumbWallGenerator:
|
||||
return obj
|
||||
|
||||
|
||||
|
||||
def generate_axis(usecase_path, ifc_file, **settings):
|
||||
axis_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Axis", "GRAPH_VIEW")
|
||||
if not axis_context:
|
||||
@@ -747,13 +746,19 @@ def calculate_quantities(usecase_path, ifc_file, **settings):
|
||||
net_volume = gross_volume
|
||||
bm.free()
|
||||
|
||||
ifcopenshell.api.run("pset.edit_qto", ifc_file, should_run_listeners=False, qto=qto, properties={
|
||||
"Length": round(length, 2),
|
||||
"Width": round(width, 2),
|
||||
"Height": round(height, 2),
|
||||
"GrossVolume": round(gross_volume, 2),
|
||||
"NetVolume": round(net_volume, 2)
|
||||
})
|
||||
ifcopenshell.api.run(
|
||||
"pset.edit_qto",
|
||||
ifc_file,
|
||||
should_run_listeners=False,
|
||||
qto=qto,
|
||||
properties={
|
||||
"Length": round(length, 2),
|
||||
"Width": round(width, 2),
|
||||
"Height": round(height, 2),
|
||||
"GrossVolume": round(gross_volume, 2),
|
||||
"NetVolume": round(net_volume, 2),
|
||||
},
|
||||
)
|
||||
PsetData.load(ifc_file, obj.BIMObjectProperties.ifc_definition_id)
|
||||
|
||||
|
||||
@@ -835,7 +840,7 @@ class DumbWallPlaner:
|
||||
break
|
||||
if not slide_vector:
|
||||
continue
|
||||
slide_vector *= (slide_magnitude / abs(slide_vector.y))
|
||||
slide_vector *= slide_magnitude / abs(slide_vector.y)
|
||||
vert.co += slide_vector
|
||||
|
||||
# An end face is a quad that is on one end of the wall or the other. It must
|
||||
|
||||
Reference in New Issue
Block a user