mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
ifc2sql - support saving element types geometry
This commit is contained in:
@@ -33,6 +33,7 @@ import ifcopenshell.ifcopenshell_wrapper as W
|
||||
import ifcopenshell.util.attribute
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.schema
|
||||
import ifcopenshell.util.shape
|
||||
import ifcopenshell.util.unit
|
||||
@@ -249,29 +250,29 @@ class Patcher(ifcpatch.BasePatcher):
|
||||
self.geometry_rows = {}
|
||||
|
||||
if self.file.schema in ("IFC2X3", "IFC4"):
|
||||
self.elements = self.file.by_type("IfcElement") + self.file.by_type("IfcProxy")
|
||||
elements = self.file.by_type("IfcElement") + self.file.by_type("IfcProxy")
|
||||
else:
|
||||
self.elements = self.file.by_type("IfcElement")
|
||||
elements = self.file.by_type("IfcElement")
|
||||
|
||||
self.settings = ifcopenshell.geom.settings()
|
||||
self.settings.set("apply-default-materials", False)
|
||||
|
||||
self.body_contexts = [
|
||||
body_contexts = [
|
||||
c.id()
|
||||
for c in self.file.by_type("IfcGeometricRepresentationSubContext")
|
||||
if c.ContextIdentifier in ["Body", "Facetation"]
|
||||
]
|
||||
# Ideally, all representations should be in a subcontext, but some BIM programs don't do this correctly
|
||||
self.body_contexts.extend(
|
||||
body_contexts.extend(
|
||||
[
|
||||
c.id()
|
||||
for c in self.file.by_type("IfcGeometricRepresentationContext", include_subtypes=False)
|
||||
if c.ContextType == "Model"
|
||||
]
|
||||
)
|
||||
self.settings.set("context-ids", self.body_contexts)
|
||||
self.settings.set("context-ids", body_contexts)
|
||||
|
||||
products = self.elements
|
||||
products = elements
|
||||
iterator = ifcopenshell.geom.iterator(self.settings, self.file, multiprocessing.cpu_count(), include=products)
|
||||
valid_file = iterator.initialize()
|
||||
if not valid_file:
|
||||
@@ -301,12 +302,7 @@ class Patcher(ifcpatch.BasePatcher):
|
||||
geometry = shape.geometry
|
||||
geometry_id = geometry.id
|
||||
if geometry_id not in self.geometry_rows:
|
||||
v = geometry.verts_buffer
|
||||
e = geometry.edges_buffer
|
||||
f = geometry.faces_buffer
|
||||
mids = geometry.material_ids_buffer
|
||||
m = json.dumps([m.instance_id() for m in geometry.materials])
|
||||
self.geometry_rows[geometry_id] = (geometry_id, v, e, f, mids, m)
|
||||
self.add_geometry_row(geometry_id, geometry)
|
||||
# Copy required since otherwise it is read-only
|
||||
m = ifcopenshell.util.shape.get_shape_matrix(shape).copy()
|
||||
m[:3, 3] /= self.unit_scale
|
||||
@@ -315,6 +311,37 @@ class Patcher(ifcpatch.BasePatcher):
|
||||
if not iterator.next():
|
||||
break
|
||||
|
||||
# Process element types geometry.
|
||||
element_types = self.file.by_type("IfcElementType")
|
||||
body_contexts = [self.file.by_id(i) for i in body_contexts]
|
||||
m_bytes = np.eye(4, dtype=np.float64).tobytes()
|
||||
for element_type in element_types:
|
||||
representation = None
|
||||
for context in body_contexts:
|
||||
representation = ifcopenshell.util.representation.get_representation(element_type, context)
|
||||
if representation:
|
||||
break
|
||||
geometry_id = None
|
||||
if representation:
|
||||
geometry_id_ = str(representation.id())
|
||||
if geometry_id_ in self.geometry_rows:
|
||||
geometry_id = geometry_id_
|
||||
elif geometry := ifcopenshell.geom.create_shape(self.settings, representation):
|
||||
geometry_id = geometry_id_
|
||||
assert isinstance(geometry, W.Triangulation)
|
||||
self.add_geometry_row(geometry_id, geometry)
|
||||
|
||||
shape_id = element_type.id()
|
||||
self.shape_rows[shape_id] = (shape_id, *(0.0, 0.0, 0.0), m_bytes, geometry_id)
|
||||
|
||||
def add_geometry_row(self, geometry_id: str, geometry: W.Triangulation) -> None:
|
||||
v = geometry.verts_buffer
|
||||
e = geometry.edges_buffer
|
||||
f = geometry.faces_buffer
|
||||
mids = geometry.material_ids_buffer
|
||||
m = json.dumps([m.instance_id() for m in geometry.materials])
|
||||
self.geometry_rows[geometry_id] = (geometry_id, v, e, f, mids, m)
|
||||
|
||||
def check_existing_ifc_database(self) -> None:
|
||||
if self.sql_type == "sqlite":
|
||||
cursor = self.c.execute("SELECT 1 FROM sqlite_master WHERE type='table' AND name='id_map'")
|
||||
|
||||
Reference in New Issue
Block a user