Updates to space boundary geometry now auto updates on export.

This commit is contained in:
Dion Moult
2022-01-24 21:52:51 +11:00
parent f88a1038a8
commit 5884af0678
5 changed files with 82 additions and 43 deletions
@@ -1,5 +1,5 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
# Copyright (C) 2020, 2021, 2022 Cyril Waechter <cyril@biminsight.ch>
#
# This file is part of BlenderBIM Add-on.
#
@@ -16,16 +16,13 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import logging
import bpy
import mathutils
import ifcopenshell.util.attribute
import logging
import ifcopenshell.api
import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore
from ifcopenshell.api.boundary.data import Data
import blenderbim.bim.import_ifc as import_ifc
from blenderbim.bim.module.geometry.helper import Helper
def get_boundaries_collection(blender_space):
@@ -70,6 +67,7 @@ class Loader:
surface.InnerBoundaries = ()
shape = ifcopenshell.geom.create_shape(self.settings, surface)
mesh = self.ifc_importer.create_mesh(None, shape)
self.ifc_importer.link_mesh(shape, mesh)
obj = bpy.data.objects.new(f"{boundary.is_a()}/{boundary.Name}", mesh)
obj.matrix_world = blender_space.matrix_world
boundaries_collection = get_boundaries_collection(blender_space)
@@ -267,20 +265,11 @@ class EditBoundaryAttributes(bpy.types.Operator):
return {"FINISHED"}
def polyline_from_indexes(mesh, indexes):
return tuple(mesh.vertices[i].co for i in indexes)
def polyline_to_2d(polyline, placement_matrix):
matrix_inv = placement_matrix.inverted()
return tuple((matrix_inv @ v).to_2d() for v in polyline)
class UpdateBoundaryGeometry(bpy.types.Operator):
bl_idname = "bim.update_boundary_geometry"
bl_label = "Update boundary geometry"
bl_description = """
Update boundary connection geometry from mesh.
Update boundary connection geometry from mesh.
Mesh must lie on a single plane. It should look like a face or a face with holes.
"""
bl_options = {"REGISTER", "UNDO"}
@@ -289,32 +278,6 @@ class UpdateBoundaryGeometry(bpy.types.Operator):
return IfcStore.execute_ifc_operator(self, context)
def _execute(self, context):
ifc_file = tool.Ifc.get()
helper = Helper(ifc_file)
mesh = context.active_object.data
curves = helper.auto_detect_curve_bounded_plane(mesh)
outer_boundary = polyline_from_indexes(mesh, curves["outer_curve"])
inner_boundaries = tuple(polyline_from_indexes(mesh, boundary) for boundary in curves["inner_curves"])
# Create placement matrix
location = outer_boundary[0]
i = (outer_boundary[1] - outer_boundary[0]).normalized()
k = mesh.polygons[0].normal
j = k.cross(i)
matrix = mathutils.Matrix()
matrix[0].xyz = i
matrix[1].xyz = j
matrix[2].xyz = k
matrix.transpose()
matrix.translation = location
settings = {
"rel_space_boundary": tool.Ifc.get_entity(context.active_object),
"outer_boundary": polyline_to_2d(outer_boundary, matrix),
"inner_boundaries": tuple(polyline_to_2d(boundary, matrix) for boundary in inner_boundaries),
"location": location,
"axis": k,
"ref_direction": i,
}
ifcopenshell.api.run("boundary.assign_connection_geometry", ifc_file, **settings)
settings = tool.Boundary.get_assign_connection_geometry_settings(context.active_object)
ifcopenshell.api.run("boundary.assign_connection_geometry", tool.Ifc.get(), **settings)
return {"FINISHED"}
@@ -155,6 +155,11 @@ class UpdateRepresentation(bpy.types.Operator):
if product.is_a("IfcGridAxis"):
ifcopenshell.api.run("grid.create_axis_curve", self.file, **{"axis_curve": obj, "grid_axis": product})
return
if product.is_a("IfcRelSpaceBoundary"):
# TODO refactor
settings = tool.Boundary.get_assign_connection_geometry_settings(obj)
ifcopenshell.api.run("boundary.assign_connection_geometry", tool.Ifc.get(), **settings)
return
core.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
+4
View File
@@ -41,6 +41,10 @@ class Aggregate:
class Blender: pass
@interface
class Boundary: pass
@interface
class Brick:
def add_brick(cls, namespace, brick_class): pass
@@ -18,6 +18,7 @@
from blenderbim.tool.aggregate import Aggregate
from blenderbim.tool.blender import Blender
from blenderbim.tool.boundary import Boundary
from blenderbim.tool.brick import Brick
from blenderbim.tool.collector import Collector
from blenderbim.tool.context import Context
@@ -0,0 +1,66 @@
# BlenderBIM Add-on - OpenBIM Blender Add-on
# Copyright (C) 2022 Cyril Waechter <cyril@biminsight.ch>
#
# This file is part of BlenderBIM Add-on.
#
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# BlenderBIM Add-on is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy
import mathutils
import blenderbim.core.tool
import blenderbim.tool as tool
from blenderbim.bim.module.geometry.helper import Helper
class Boundary(blenderbim.core.tool.Boundary):
@classmethod
def get_assign_connection_geometry_settings(cls, obj):
ifc = tool.Ifc.get()
helper = Helper(ifc)
mesh = obj.data
curves = helper.auto_detect_curve_bounded_plane(mesh)
outer_boundary = cls.polyline_from_indexes(mesh, curves["outer_curve"])
inner_boundaries = tuple(cls.polyline_from_indexes(mesh, boundary) for boundary in curves["inner_curves"])
# Create placement matrix
location = outer_boundary[0]
i = (outer_boundary[1] - outer_boundary[0]).normalized()
k = mesh.polygons[0].normal
j = k.cross(i)
matrix = mathutils.Matrix()
matrix[0].xyz = i
matrix[1].xyz = j
matrix[2].xyz = k
matrix.transpose()
matrix.translation = location
return {
"rel_space_boundary": tool.Ifc.get_entity(obj),
"outer_boundary": cls.polyline_to_2d(outer_boundary, matrix),
"inner_boundaries": tuple(cls.polyline_to_2d(boundary, matrix) for boundary in inner_boundaries),
"location": location,
"axis": k,
"ref_direction": i,
}
@classmethod
def polyline_from_indexes(cls, mesh, indexes):
return tuple(mesh.vertices[i].co for i in indexes)
@classmethod
def polyline_to_2d(cls, polyline, placement_matrix):
matrix_inv = placement_matrix.inverted()
return tuple((matrix_inv @ v).to_2d() for v in polyline)