Files
create/src/Mod/BIM/nativeifc/ifc_layers.py
2025-04-04 17:46:58 +02:00

160 lines
5.6 KiB
Python

# SPDX-License-Identifier: LGPL-2.1-or-later
# ***************************************************************************
# * *
# * Copyright (c) 2023 Yorik van Havre <yorik@uncreated.net> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * This program 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 Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with this program; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# * *
# ***************************************************************************
"""This NativeIFC module deals with layers"""
import ifcopenshell
import ifcopenshell.util.element
from . import ifc_tools
def load_layers(obj):
"""Loads all the layers of an IFC file"""
proj = ifc_tools.get_project(obj)
ifcfile = ifc_tools.get_ifcfile(obj)
layers = ifcfile.by_type("IfcPresentationLayerAssignment")
for layer in layers:
obj = get_layer(layer, proj)
populate_layer(obj)
def has_layers(obj):
"""Returns true if the given project has layers"""
ifcfile = ifc_tools.get_ifcfile(obj)
layers = ifcfile.by_type("IfcPresentationLayerAssignment")
if layers:
return True
return False
def get_layer(layer, project):
"""Returns (creates if necessary) a layer object in the given project"""
group = ifc_tools.get_group(project, "IfcLayersGroup")
if not group:
return None
if hasattr(project, "Document"):
doc = project.Document
else:
doc = project
exobj = ifc_tools.get_object(layer, doc)
if exobj:
return exobj
obj = ifc_tools.add_object(doc, otype="layer")
ifcfile = ifc_tools.get_ifcfile(project)
ifc_tools.add_properties(obj, ifcfile, layer)
group.addObject(obj)
return obj
def populate_layer(obj):
"""Attaches all the possible objects to this layer"""
g = []
element = ifc_tools.get_ifc_element(obj)
for shape in getattr(element, "AssignedItems", []):
rep = getattr(shape, "OfProductRepresentation", None)
for prod in getattr(rep, "ShapeOfProduct", []):
obj = ifc_tools.get_object(prod)
if obj:
g.append(obj)
obj.Group = g
def add_layers(obj, element=None, ifcfile=None, proj=None):
"""Creates necessary layers for the given object"""
if not ifcfile:
ifcfile = ifc_tools.get_ifcfile(obj)
if not element:
element = ifc_tools.get_ifc_element(obj, ifcfile)
if not proj:
proj = ifc_tools.get_project(obj)
layers = ifcopenshell.util.element.get_layers(ifcfile, element)
for layer in layers:
lay = get_layer(layer, proj)
if lay and not obj in lay.Group:
lay.Proxy.addObject(lay, obj)
def add_to_layer(obj, layer):
"""Adds the given object to the given layer"""
if hasattr(obj, "StepId"):
obj_element = ifc_tools.get_ifc_element(obj)
elif hasattr(obj, "id"):
obj_element = obj
obj = ifc_tools.get_object(obj_element)
else:
return
if hasattr(layer, "StepId"):
layer_element = ifc_tools.get_ifc_element(layer)
elif hasattr(layer, "id"):
layer_element = layer
layer = ifc_tools.get_object(layer_element)
else:
return
ifcfile = ifc_tools.get_ifcfile(obj)
if not ifcfile:
return
items = ()
if layer_element.AssignedItems:
items = layer_element.AssignedItems
if not obj_element in items:
cmd = "attribute.edit_attributes"
attribs = {"AssignedItems": items + (obj_element,)}
ifc_tools.api_run(cmd, ifcfile, product=layer_element, attributes=attribs)
if not obj in layer.Group:
layer.Proxy.addObject(layer, obj)
def create_layer(name, project):
"""Adds a new layer to the given project"""
group = ifc_tools.get_group(project, "IfcLayersGroup")
ifcfile = ifc_tools.get_ifcfile(project)
try:
# IfcopenShell 0.8
layer = ifc_tools.api_run("layer.add_layer", ifcfile, name=name)
except:
# IfcopenShell 0.7
layer = ifc_tools.api_run("layer.add_layer", ifcfile, Name=name)
return get_layer(layer, project)
def transfer_layer(layer, project):
"""Transfer a non-NativeIFC layer to a project"""
label = layer.Label
ifclayer = create_layer(label, project)
delete = not (ifc_tools.PARAMS.GetBool("KeepAggregated", False))
# delete the old one if empty and delete param allows
if delete and not layer.Group:
layer.Document.removeObject(layer.Name)
ifclayer.Label = label # to avoid 001-ing the Label...
return ifclayer