mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 08:45:22 +00:00
Updates to space boundary geometry now auto updates on export.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
# 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.
|
# This file is part of BlenderBIM Add-on.
|
||||||
#
|
#
|
||||||
@@ -16,16 +16,13 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# 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/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
|
||||||
import bpy
|
import bpy
|
||||||
import mathutils
|
import logging
|
||||||
import ifcopenshell.util.attribute
|
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from ifcopenshell.api.boundary.data import Data
|
from ifcopenshell.api.boundary.data import Data
|
||||||
import blenderbim.bim.import_ifc as import_ifc
|
import blenderbim.bim.import_ifc as import_ifc
|
||||||
from blenderbim.bim.module.geometry.helper import Helper
|
|
||||||
|
|
||||||
|
|
||||||
def get_boundaries_collection(blender_space):
|
def get_boundaries_collection(blender_space):
|
||||||
@@ -70,6 +67,7 @@ class Loader:
|
|||||||
surface.InnerBoundaries = ()
|
surface.InnerBoundaries = ()
|
||||||
shape = ifcopenshell.geom.create_shape(self.settings, surface)
|
shape = ifcopenshell.geom.create_shape(self.settings, surface)
|
||||||
mesh = self.ifc_importer.create_mesh(None, shape)
|
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 = bpy.data.objects.new(f"{boundary.is_a()}/{boundary.Name}", mesh)
|
||||||
obj.matrix_world = blender_space.matrix_world
|
obj.matrix_world = blender_space.matrix_world
|
||||||
boundaries_collection = get_boundaries_collection(blender_space)
|
boundaries_collection = get_boundaries_collection(blender_space)
|
||||||
@@ -267,20 +265,11 @@ class EditBoundaryAttributes(bpy.types.Operator):
|
|||||||
return {"FINISHED"}
|
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):
|
class UpdateBoundaryGeometry(bpy.types.Operator):
|
||||||
bl_idname = "bim.update_boundary_geometry"
|
bl_idname = "bim.update_boundary_geometry"
|
||||||
bl_label = "Update boundary geometry"
|
bl_label = "Update boundary geometry"
|
||||||
bl_description = """
|
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.
|
Mesh must lie on a single plane. It should look like a face or a face with holes.
|
||||||
"""
|
"""
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
@@ -289,32 +278,6 @@ class UpdateBoundaryGeometry(bpy.types.Operator):
|
|||||||
return IfcStore.execute_ifc_operator(self, context)
|
return IfcStore.execute_ifc_operator(self, context)
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
ifc_file = tool.Ifc.get()
|
settings = tool.Boundary.get_assign_connection_geometry_settings(context.active_object)
|
||||||
helper = Helper(ifc_file)
|
ifcopenshell.api.run("boundary.assign_connection_geometry", tool.Ifc.get(), **settings)
|
||||||
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)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -155,6 +155,11 @@ class UpdateRepresentation(bpy.types.Operator):
|
|||||||
if product.is_a("IfcGridAxis"):
|
if product.is_a("IfcGridAxis"):
|
||||||
ifcopenshell.api.run("grid.create_axis_curve", self.file, **{"axis_curve": obj, "grid_axis": product})
|
ifcopenshell.api.run("grid.create_axis_curve", self.file, **{"axis_curve": obj, "grid_axis": product})
|
||||||
return
|
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)
|
core.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=obj)
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,10 @@ class Aggregate:
|
|||||||
class Blender: pass
|
class Blender: pass
|
||||||
|
|
||||||
|
|
||||||
|
@interface
|
||||||
|
class Boundary: pass
|
||||||
|
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Brick:
|
class Brick:
|
||||||
def add_brick(cls, namespace, brick_class): pass
|
def add_brick(cls, namespace, brick_class): pass
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
from blenderbim.tool.aggregate import Aggregate
|
from blenderbim.tool.aggregate import Aggregate
|
||||||
from blenderbim.tool.blender import Blender
|
from blenderbim.tool.blender import Blender
|
||||||
|
from blenderbim.tool.boundary import Boundary
|
||||||
from blenderbim.tool.brick import Brick
|
from blenderbim.tool.brick import Brick
|
||||||
from blenderbim.tool.collector import Collector
|
from blenderbim.tool.collector import Collector
|
||||||
from blenderbim.tool.context import Context
|
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)
|
||||||
|
|
||||||
Reference in New Issue
Block a user