mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-17 19:09:07 +00:00
Import alignment from csv (#6234)
* Start of the official alignment API * Import alignment into bonsai model using CSV file
This commit is contained in:
@@ -83,6 +83,7 @@ modules = {
|
||||
"covering": None,
|
||||
"web": None,
|
||||
"light": None,
|
||||
"alignment": None,
|
||||
# Uncomment this line to enable loading of the demo module. Happy hacking!
|
||||
# The name "demo" must correlate to a folder name in `bim/module/`.
|
||||
# "demo": None,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# Bonsai - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of Bonsai.
|
||||
#
|
||||
# Bonsai 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.
|
||||
#
|
||||
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
|
||||
# from . import ui, prop, operator
|
||||
from . import operator
|
||||
|
||||
classes = (operator.ImportAlignmentCSV,)
|
||||
|
||||
|
||||
def menu_func_import(self, context):
|
||||
self.layout.operator(operator.ImportAlignmentCSV.bl_idname, text="Alignment (.csv)")
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
|
||||
|
||||
|
||||
def unregister():
|
||||
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
|
||||
@@ -0,0 +1,113 @@
|
||||
# Bonsai - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>, 2022 Yassine Oualid <yassine@sigmadimensions.com>
|
||||
#
|
||||
# This file is part of Bonsai.
|
||||
#
|
||||
# Bonsai 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.
|
||||
#
|
||||
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# pyright: reportUnnecessaryTypeIgnoreComment=error
|
||||
|
||||
import os
|
||||
|
||||
import ifcopenshell.api.alignment
|
||||
import ifcopenshell.api.alignment.add_stationing_to_alignment
|
||||
|
||||
import bpy
|
||||
import json
|
||||
import time
|
||||
import calendar
|
||||
import isodate
|
||||
import bonsai.core.sequence as core
|
||||
import bonsai.tool as tool
|
||||
import bonsai.bim.module.sequence.helper as helper
|
||||
import ifcopenshell.util.sequence
|
||||
import ifcopenshell.util.selector
|
||||
from datetime import datetime
|
||||
from dateutil import parser, relativedelta
|
||||
from bpy_extras.io_utils import ImportHelper
|
||||
from typing import get_args, TYPE_CHECKING
|
||||
from typing_extensions import assert_never
|
||||
|
||||
|
||||
class ImportAlignmentCSV(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
||||
bl_idname = "bim.import_alignment_csv"
|
||||
bl_label = "Import Alignment CSV"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
filename_ext = ".csv"
|
||||
filter_glob: bpy.props.StringProperty(default="*.csv", options={"HIDDEN"})
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
ifc_file = tool.Ifc.get()
|
||||
if ifc_file is None:
|
||||
cls.poll_message_set("No IFC file is loaded.")
|
||||
return False
|
||||
elif ifc_file.schema != "IFC4X3":
|
||||
cls.poll_message_set("Schema must be IFC4x3.")
|
||||
return False
|
||||
return True
|
||||
|
||||
def _execute(self, context):
|
||||
import ifcopenshell.api.alignment
|
||||
|
||||
self.file = tool.Ifc.get()
|
||||
start = time.time()
|
||||
alignment = ifcopenshell.api.alignment.create_alignment_from_csv(self.file, self.filepath)
|
||||
ifcopenshell.api.alignment.create_geometric_representation(self.file, alignment)
|
||||
ifcopenshell.api.alignment.add_stationing_to_alignment(self.file, alignment=alignment, start_station=0.0)
|
||||
|
||||
# IFC 4.1.5.1 alignments cannot be contained in spatial structures, but can be referenced into them
|
||||
sites = self.file.by_type("IfcSite")
|
||||
for site in sites:
|
||||
ifcopenshell.api.spatial.reference_structure(self.file, products=[alignment], relating_structure=site)
|
||||
|
||||
# process the generated IfcReferent for the alignment
|
||||
for rel in alignment.IsNestedBy:
|
||||
for referent in rel.RelatedObjects:
|
||||
if referent.is_a("IfcReferent"):
|
||||
referent_obj = bpy.data.objects.new(tool.Loader.get_name(referent), None)
|
||||
tool.Geometry.link(referent, referent_obj)
|
||||
tool.Collector.assign(referent_obj, should_clean_users_collection=False)
|
||||
|
||||
# an alignment can be an aggregation of multiple child alignments (ie. multiple verticals for a single horizontal)
|
||||
# get all the alignment curves
|
||||
curves = []
|
||||
for rel in alignment.IsDecomposedBy:
|
||||
for agg in rel.RelatedObjects:
|
||||
if agg.is_a("IfcAlignment"):
|
||||
curves.append(ifcopenshell.api.alignment.get_curve(agg)) # 3D curve
|
||||
|
||||
# if there aren't any curves from aggregation, then there is only a single vertical or no vertical
|
||||
if len(curves) == 0:
|
||||
curves.append(ifcopenshell.api.alignment.get_curve(alignment))
|
||||
|
||||
settings = ifcopenshell.geom.settings()
|
||||
for curve in curves:
|
||||
shape = ifcopenshell.geom.create_shape(settings, curve)
|
||||
|
||||
# create a new Blender mesh
|
||||
mesh_name = tool.Loader.get_mesh_name_from_shape(shape)
|
||||
mesh = bpy.data.meshes.new(mesh_name)
|
||||
m = tool.Loader.convert_geometry_to_mesh(shape, mesh)
|
||||
|
||||
# create a new Blender object
|
||||
alignment_obj = bpy.data.objects.new(tool.Loader.get_name(alignment), m)
|
||||
|
||||
# link the blender object to with the alignment element
|
||||
tool.Geometry.link(alignment, alignment_obj)
|
||||
|
||||
# assign the object to the blender collections
|
||||
tool.Collector.assign(alignment_obj, should_clean_users_collection=False)
|
||||
|
||||
self.report({"INFO"}, "Imported in %s seconds" % (time.time() - start))
|
||||
@@ -19,6 +19,7 @@
|
||||
# pyright: reportUnnecessaryTypeIgnoreComment=error
|
||||
|
||||
import os
|
||||
|
||||
import bpy
|
||||
import json
|
||||
import time
|
||||
@@ -653,7 +654,6 @@ class DisableEditingWorkCalendar(bpy.types.Operator):
|
||||
core.disable_editing_work_calendar(tool.Sequence)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ImportCSV(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
||||
bl_idname = "bim.import_csv"
|
||||
bl_label = "Import CSV"
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
Road and Rail Alignments
|
||||
========================
|
||||
|
||||
.. Note::
|
||||
|
||||
Bonsai lacks modeling features for road and rail alignments. This feature is intended to be a stop-gap measure to allow alignments
|
||||
to be defined and imported into an IFC model. This feature is most likely temporary and will be phased out as robust alignment
|
||||
modeling capabilities are developed.
|
||||
|
||||
Alignments may be defined by the PI method in a CSV file for import into an IFC4X3 Bonsai project. The format of the CSV file is as follows:
|
||||
|
||||
.. csv-table:: Alignment by PI Method
|
||||
|
||||
"X1","Y1","R1","X2","Y2","R2","...,","Xn-1","Yn-1","Rn-1","Xn","Yn","Rn"
|
||||
"D1","Z1","L1","D2","Z2","L2","...,","Dn-1","Zn-1","Ln-1","Dn","Zn","Ln"
|
||||
"D1","Z1","L1","D2","Z2","L2","...,","Dn-1","Zn-1","Ln-1","Dn","Zn","Ln"
|
||||
|
||||
|
||||
where:
|
||||
Xi,Yi are horizontal alignment PI points
|
||||
Ri are horizontal curve radii.
|
||||
Di,Zi are vertical alignment PI points as Distance_Along,Elevation
|
||||
Li are the horizontal length of parabolic vertical transition curves
|
||||
|
||||
R1 and Rn, as well as L1 and Ln, are placeholder values and should be set to 0.0
|
||||
|
||||
The CSV file must contain exactly one horizontal alignment definition with a minimum of three points.
|
||||
X1,Y1 is the Point of Beginning (POB). Xn,Yn is the Point of Ending (POE).
|
||||
|
||||
The CSV file may contain zero, one or more vertical alignment definitions.
|
||||
|
||||
Alignments with a single horizontal layout and zero or one vertical layout are modeled per `IFC Concept Template 4.1.4.4.1.1, Alignment Layout - Horizontal, Vertical, and Cant, <https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/concepts/Object_Composition/Nesting/Alignment_Layouts/Alignment_Layout_-_Horizontal,_Vertical_and_Cant/content.html>`_. Alignments with multiple vertical layouts are modeled per `IFC Concept Template 4.1.4.4.1.2, Alignment Layout - Reusing Horizontal Layout, <https://ifc43-docs.standards.buildingsmart.org/IFC/RELEASE/IFC4x3/HTML/concepts/Object_Composition/Nesting/Alignment_Layouts/Alignment_Layout_-_Reusing_Horizontal_Layout/content.html>`_.
|
||||
|
||||
Example based on the `FHWA Bridge Geometry Manual <https://www.fhwa.dot.gov/bridge/pubs/hif22034.pdf>`_:
|
||||
|
||||
500,2500,0.0,3340,660,1000,4340,5000,1250,7600,4560,950,8480,2010,0
|
||||
0,100,0,2000,135,1600,5000,105,1200,7400,153,2000,9800,105,800,12800,90,0
|
||||
@@ -56,6 +56,7 @@ and data-rich OpenBIM with Blender :)
|
||||
guides/authoring/georeferencing
|
||||
guides/authoring/git_support
|
||||
guides/development/index
|
||||
guides/alignment
|
||||
guides/authoring/other_addons
|
||||
guides/troubleshooting
|
||||
guides/debugging
|
||||
|
||||
@@ -98,3 +98,4 @@ Imports data from external sources into the Blender session or IFC model.
|
||||
- **P6 (.xer)**: Imports a P6 XER file containing a work schedule into the active IFC model.
|
||||
- **Powerproject (.pp)**: Imports a Powerproject file containing a work schedule into the active IFC model.
|
||||
- **Microsoft Project (.xml)**: Imports a Microsoft Project XML file containing a work schedule into the active IFC model.
|
||||
- **Alignment (.csv)**: Imports a CSV containing horizontal and vertical alignments defined by the PI method into the active IFC model.
|
||||
Reference in New Issue
Block a user