Dumb slabs now auto generate footprint representations

This commit is contained in:
Dion Moult
2021-06-07 14:28:46 +10:00
parent 5a822d5e39
commit 137a00225c
3 changed files with 64 additions and 1 deletions
@@ -33,6 +33,9 @@ def load_post(*args):
ifcopenshell.api.add_pre_listener( ifcopenshell.api.add_pre_listener(
"geometry.add_representation", "BlenderBIM.DumbSlab.EnsureSolid", slab.ensure_solid "geometry.add_representation", "BlenderBIM.DumbSlab.EnsureSolid", slab.ensure_solid
) )
ifcopenshell.api.add_post_listener(
"geometry.add_representation", "BlenderBIM.DumbSlab.GenerateFootprint", slab.generate_footprint
)
ifcopenshell.api.add_pre_listener( ifcopenshell.api.add_pre_listener(
"material.edit_layer", "BlenderBIM.DumbSlab.RegenerateFromLayer", slab.DumbSlabPlaner().regenerate_from_layer "material.edit_layer", "BlenderBIM.DumbSlab.RegenerateFromLayer", slab.DumbSlabPlaner().regenerate_from_layer
) )
@@ -4,12 +4,14 @@ import math
import ifcopenshell import ifcopenshell
import ifcopenshell.util.type import ifcopenshell.util.type
import ifcopenshell.util.unit import ifcopenshell.util.unit
import ifcopenshell.util.element
import mathutils.geometry import mathutils.geometry
import blenderbim.bim.handler import blenderbim.bim.handler
from blenderbim.bim.ifc import IfcStore from blenderbim.bim.ifc import IfcStore
from math import pi, degrees from math import pi, degrees
from mathutils import Vector, Matrix from mathutils import Vector, Matrix
from ifcopenshell.api.material.data import Data as MaterialData from ifcopenshell.api.material.data import Data as MaterialData
from blenderbim.bim.module.geometry.helper import Helper
def element_listener(element, obj): def element_listener(element, obj):
@@ -61,6 +63,64 @@ def ensure_solid(usecase_path, ifc_file, settings):
settings["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids" settings["ifc_representation_class"] = "IfcExtrudedAreaSolid/IfcArbitraryProfileDefWithVoids"
def generate_footprint(usecase_path, ifc_file, settings):
footprint_context = ifcopenshell.util.representation.get_context(ifc_file, "Plan", "FootPrint", "SKETCH_VIEW")
if not footprint_context:
return
obj = settings["blender_object"]
product = ifc_file.by_id(obj.BIMObjectProperties.ifc_definition_id)
parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric")
if not parametric or parametric["Engine"] != "BlenderBIM.DumbSlab":
return
old_footprint = ifcopenshell.util.representation.get_representation(product, "Plan", "FootPrint", "SKETCH_VIEW")
if settings["context"].ContextType == "Model" and getattr(settings["context"], "ContextIdentifier") == "Body":
if old_footprint:
bpy.ops.bim.remove_representation(representation_id=old_footprint.id(), obj=obj.name)
helper = Helper(ifc_file)
indices = helper.auto_detect_arbitrary_profile_with_voids_extruded_area_solid(settings["geometry"])
bm = bmesh.new()
bm.from_mesh(settings["geometry"])
bm.verts.ensure_lookup_table()
bm.edges.ensure_lookup_table()
profile_edges = []
def append_profile_edges(profile_edges, indices):
indices.append(indices[0]) # Close the loop
edge_vert_pairs = list(zip(indices, indices[1:]))
for p in edge_vert_pairs:
profile_edges.append(
[e for e in bm.verts[p[0]].link_edges if e.other_vert(bm.verts[p[0]]).index == p[1]][0]
)
append_profile_edges(profile_edges, indices["profile"])
for inner_indices in indices["inner_curves"]:
append_profile_edges(profile_edges, inner_indices)
irrelevant_edges = [e for e in bm.edges if e not in profile_edges]
bmesh.ops.delete(bm, geom=irrelevant_edges, context="EDGES")
mesh = bpy.data.meshes.new("Temporary Footprint")
bm.to_mesh(mesh)
bm.free()
new_settings = settings.copy()
new_settings["context"] = footprint_context
new_settings["geometry"] = mesh
new_footprint = ifcopenshell.api.run(
"geometry.add_representation", ifc_file, should_run_listeners=False, **new_settings
)
ifcopenshell.api.run(
"geometry.assign_representation",
ifc_file,
should_run_listeners=False,
**{"product": product, "representation": new_footprint}
)
bpy.data.meshes.remove(mesh)
class DumbSlabGenerator: class DumbSlabGenerator:
def __init__(self, relating_type): def __init__(self, relating_type):
self.relating_type = relating_type self.relating_type = relating_type
@@ -134,7 +134,7 @@ class Usecase:
elif self.settings["context"].ContextIdentifier == "CoG": elif self.settings["context"].ContextIdentifier == "CoG":
pass pass
elif self.settings["context"].ContextIdentifier == "FootPrint": elif self.settings["context"].ContextIdentifier == "FootPrint":
if self.settings["context"].TargetView in ["PLAN_VIEW", "REFLECTED_PLAN_VIEW"]: if self.settings["context"].TargetView in ["SKETCH_VIEW", "PLAN_VIEW", "REFLECTED_PLAN_VIEW"]:
return self.create_geometric_curve_set_representation(is_2d=True) return self.create_geometric_curve_set_representation(is_2d=True)
elif self.settings["context"].ContextIdentifier == "Reference": elif self.settings["context"].ContextIdentifier == "Reference":
pass pass