Skip to content

Commit

Permalink
Add AdheresToElement for IfcSurfaceFeature
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrouwerdigibase committed Oct 20, 2024
1 parent 5433ac1 commit c9bd0b1
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 19 deletions.
67 changes: 48 additions & 19 deletions src/bt_ifcmanager/lib/lib_ifc/IfcProduct_su.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@
require_relative 'PropertyReader'
require_relative 'material_and_styling'
require_relative 'base_quantity_builder'
require_relative 'ifc_rel_adheres_to_element_builder'

module BimTools
module IfcProduct_su
attr_accessor :su_object, :parent, :total_transformation, :type_product

@su_object = nil
@parent = nil
@has_surface_features = nil

# @param [BimTools::IfcManager::IfcModel] ifc_model
# @param [nil, #definition] sketchup an empty object (default object), Sketchup::ComponentInstance or Sketchup::Group
Expand Down Expand Up @@ -90,19 +92,15 @@ def initialize(ifc_model, sketchup, total_transformation)
@predefinedtype = nil
end

# set material if sketchup @su_object has a material
# Material added to Product and not to TypeProduct because a Sketchup ComponentDefinition can have a different material for every Instance
if ifc_model.options[:materials] && (is_a? @ifc_module::IfcElement) && !(is_a? @ifc_module::IfcFeatureElementSubtraction) && !(is_a? @ifc_module::IfcVirtualElement)

# create materialassociation
su_material = @su_object.material
unless ifc_model.materials.include?(su_material)
ifc_model.materials[su_material] = BimTools::IfcManager::MaterialAndStyling.new(ifc_model, su_material)
end

# add product to materialassociation
ifc_model.materials[su_material].add_to_material(self)
end
# TODO: dont exclude on class but on relaggregates
add_material_association if ifc_model.options[:materials] &&
(is_a? @ifc_module::IfcElement) &&
!(is_a? @ifc_module::IfcFeatureElementSubtraction) &&
!(is_a? @ifc_module::IfcVirtualElement) &&
!(is_a? @ifc_module::IfcSpatialElement) &&
!(is_a? @ifc_module::IfcRoof) &&
!(is_a? @ifc_module::IfcElementAssembly) &&
!(is_a? @ifc_module::IfcCurtainWall)

# collect dynamic component attributes if export option is set
BimTools::DynamicAttributes.get_dynamic_attributes(ifc_model, self) if ifc_model.options[:dynamic_attributes]
Expand All @@ -112,6 +110,43 @@ def initialize(ifc_model, sketchup, total_transformation)
add_base_quantities
end

# Adds a surface feature to the IFC element.
#
# @param surface_feature [Object] The surface feature to be added.
# @return [void]
def add_surface_feature(surface_feature)
create_ifc_rel_adheres_to_element unless @has_surface_features
@has_surface_features.add_related_surface_feature(surface_feature)
end

# add export summary for IfcProducts
def step
@ifc_model.summary_add(self.class.name.split('::').last)
super
end

private

# Creates an IfcRelAdheresToElement relationship for the IFC element.
#
# @return [void]
def create_ifc_rel_adheres_to_element
@has_surface_features = BimTools::IfcManager::IfcRelAdheresToElementBuilder.build(@ifc_model) do |builder|
builder.set_relating_element(self)
end
end

# set material if sketchup @su_object has a material
# Material added to Product and not to TypeProduct because a Sketchup ComponentDefinition can have a different material for every Instance
def add_material_association
su_material = @su_object.material
unless @ifc_model.materials.include?(su_material)
@ifc_model.materials[su_material] = BimTools::IfcManager::MaterialAndStyling.new(@ifc_model, su_material)
end

@ifc_model.materials[su_material].add_to_material(self)
end

def add_base_quantities
unless is_a?(@ifc_module::IfcColumn) || is_a?(@ifc_module::IfcBeam) || is_a?(@ifc_module::IfcSlab) || is_a?(@ifc_module::IfcWall)
return
Expand All @@ -121,11 +156,5 @@ def add_base_quantities
builder.add_base_quantities(self, @su_object)
end
end

# add export summary for IfcProducts
def step
@ifc_model.summary_add(self.class.name.split('::').last)
super
end
end
end
19 changes: 19 additions & 0 deletions src/bt_ifcmanager/lib/lib_ifc/entity_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ def create_ifc_entity(entity_type_name, su_instance, placement_parent = nil, su_

create_geometry(su_definition, ifc_entity, placement_parent, su_material, su_layer)

add_placement_parent_relationships(ifc_entity, placement_parent)

# We always need a placement parent, so when the current entity is nil, we use the parent
placement_parent = ifc_entity if ifc_entity
create_nested_objects(placement_parent, su_instance, su_material, su_layer)
Expand Down Expand Up @@ -516,6 +518,23 @@ def add_representation_to_parent(placement_parent, definition_manager, su_materi
)
end
end

# Adds additional relationships between the given IFC entity and its placement parent.
#
# @param ifc_entity [Object] The IFC entity to which relationships will be added.
# @param placement_parent [Object] The parent entity to which the IFC entity is related.
# @return [void]
def add_placement_parent_relationships(ifc_entity, placement_parent)
return unless placement_parent

return if ifc_entity == placement_parent

unless ifc_entity.is_a?(@ifc_module::IfcSurfaceFeature) && placement_parent.is_a?(@ifc_module::IfcProduct)
return
end # TODO: should be IfcElement

placement_parent.add_surface_feature(ifc_entity)
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# frozen_string_literal: true

# ifc_rel_adheres_to_element_builder.rb
#
# Copyright 2024 Jan Brouwer <[email protected]>
#
# This program 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 2 of the License, or
# (at your option) any later version.
#
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
#
#

require_relative 'ifc_types'

module BimTools
module IfcManager
class IfcRelAdheresToElementBuilder
UNSUPPORTED_VERSIONS = ['IFC 2x3', 'IFC 4'].freeze

attr_reader :ifc_rel_adheres_to_element

def self.build(ifc_model)
builder = new(ifc_model)
return nil unless builder.supported_version?

yield(builder) if block_given?
builder
end

def initialize(ifc_model)
@ifc_module = ifc_model.ifc_module
@ifc_model = ifc_model
@ifc_rel_adheres_to_element = @ifc_module::IfcRelAdheresToElement.new(ifc_model)
@ifc_rel_adheres_to_element.relatedsurfacefeatures = IfcManager::Types::Set.new
end

def set_relating_element(element)
raise TypeError, 'Expected IfcElement' unless element.is_a?(@ifc_module::IfcElement)

@ifc_rel_adheres_to_element.relatingelement = element
self
end

def add_related_surface_feature(surface_feature)
raise TypeError, 'Expected IfcSurfaceFeature' unless surface_feature.is_a?(@ifc_module::IfcSurfaceFeature)

@ifc_rel_adheres_to_element.relatedsurfacefeatures.add(surface_feature)
self
end

def supported_version?
!UNSUPPORTED_VERSIONS.include?(@ifc_model.ifc_version)
end
end
end
end
2 changes: 2 additions & 0 deletions src/bt_ifcmanager/lib/lib_ifc/spatial_structure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ def set_parent(ifc_entity)
end
ifc_entity.parent = parent
case ifc_entity
when @ifc_module::IfcSurfaceFeature
# skip
when @ifc_module::IfcSpatialStructureElement
ifc_entity.parent.add_related_object(ifc_entity)
else
Expand Down

0 comments on commit c9bd0b1

Please sign in to comment.