Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GEM005 representation in decomposed elements #40

Closed
wants to merge 12 commits into from

Conversation

Ghesselink
Copy link
Contributor

@Ghesselink Ghesselink commented Feb 1, 2023

    In cases of aggregation of physical elements into a physical aggregate
    the shape representation of the whole (within the same representation identifier)
    must be taken from the sum of the shape representations of the parts.

    If a building element acts as container, i.e. has parts associated,
    and those parts have own shape re

The rule can be interpreted as follows: starting from the related elements, if they have their own shape representations, the relating container should have no shape representation with 'Body' as RepresentationIdentifier. In that case, we could first check the related (parts) elements, and if the condition is met, go back to the related elements and from there check the attributes of the relating (container) element.

The current PR builds upon the 'and following that' functionality introduced in the previous PR (a more in-depth explanation can be found here #37). In short, when analyzing a relationship between elements, the 'and following that' can be used for the context to switch the context. When using stack frames in gherkin statement, it is possible to go from an entity to the representationidentifier as follows:

Given An IfcBuildingElement 
      And A relationship IfcRelAggregates to IfcBuildingElement from IfcObject #stay at the IfcBuildingElement (related) context
      And Its attribute Representation 
      And Its attribute Representations 
      And Its attribute RepresentationIdentifier **and return to first**

And return to first is added to go back to the first stacked elements. In this case, this would be the parts (related) elements. In order to prevent false negatives: if the attribute (RepresentationIdentifier in this case; parts have no own shape representations) is empty and we try to return to the first stacked elements, the context will be empty as well.
For this last part I'm not completely sure whether it is the best solution. If parts have no own shape representations, it seems the rule of the current PR should pass. Is that generally applicable however? I am still thinking about this one.

But continuing, we can return to the first stacked element with the 'and return to first' and proceed with the gherkin analysis:

      #from context.instances = [related_element, related_element]
      And A relationship IfcRelAggregates to IfcObject from IfcBuildingElement and following that #continue from IfcObject(relating/container-object) -> [relating_element]
      And Its attribute Representation 
      And Its attribute Representations 
      And Its attribute RepresentationIdentifier 

     Then The value must not be Body

Another advantage of this rule might be that we can merge most functionalities of ALB999. With all these functionalities available, I think we will have a better basis to create new rules.

Copy link
Collaborator

@aothms aothms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What did you base your rule on precisely? Did you see https://standards.buildingsmart.org/documents/Implementation/IFC_Implementation_Agreements/CV-2x3-119.html?

If the building element acts as a container, i.e. has parts associated, and those parts have own shape representations, then the container shall have no shape representation.

and later

The requirement only concerns the shape representation of the container with RepresentationIdentifier = "Body".

This Body representation in the parts appears missing from the gherkin implementation.

"""
Background: Entity is part having own shape representation

Given An IfcBuildingElement
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a constant attempt to tease implementers IfcBuildingElement in IFC4X3 onwards has been renamed to IfcBuiltElement. So we either need to have a Given that selects on schema version and duplicate the scenario or do something clever with the entity selection.

And A relationship IfcRelAggregates to IfcBuildingElement from IfcObject
And Its attribute Representation
And Its attribute Representations
And Its attribute RepresentationIdentifier and return to first
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some objections to this:

  • return to first is not very general as it can only jump back to the top of the stack
  • return to first seems to set context.applicable which is surprising behaviour
  • I think we need to specifically see if a body representation exists, but I'm not sure, the wording of the rule is not very precise.

Can we work towards something like this:

Suggested change
And Its attribute RepresentationIdentifier and return to first
And its attribute RepresentationIdentifier
And the value is "Body"
And return to IfcBuildingElement


import ifcopenshell
import pyparsing

from behave import *

register_type(from_to=TypeBuilder.make_enum({"from": 0, "to": 1 }))
register_type(maybe_and_following_that=TypeBuilder.make_enum({"": 0, "and following that": 1, "and return to first": 2 }))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name of maybe_and_following_that should be changed, but I guess in my gherkin proposal we wouldn't have another tail option.

def step_impl(context, attribute, tail=0):
context._push()
if attribute == 'RepresentationIdentifier':
x = 'hi'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hold on for this change. This depends on which IFC schema version the rule applies.
IfcBuildingElement was renamed IfcBuiltElement only in 4.3. For 2X3 and 4 the previous version of the feature file is valid. Is the "schema Given" part of this rule?
cc: @aothms

Copy link
Contributor Author

@Ghesselink Ghesselink Apr 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for noting, it is addressed last days

def list_renamed_entities():
dirname = os.path.dirname(__file__)
fn_related_attr_matrix = Path(
dirname).parent / 'resources' / 'renamed_entities.csv'
related_attr_matrix = next(
csv.DictReader(open(fn_related_attr_matrix)))
return list(related_attr_matrix.items())
@dataclass
class IfcEntity:
entity : str
instances : typing.List = field(default_factory=lambda: [])
renamed_entities : typing.List = field(default_factory=lambda : list_renamed_entities())
def search(self, num):
tup = next((t for t in self.renamed_entities if t[num] == self.entity), None)
if tup:
idx = 1 if num == 0 else 0
return tup[idx]
def alternative_name(self):
# If the entity is renamed, such as in the case of 'IfcBuildingElement' being changed to 'IfcBuiltElement'
self.alternative_name = next(filter(None, map(self.search, [0, 1])), None)
return self.alternative_name
def get_entity_instances(self, context):
try:
return context.model.by_type(self.entity)
except:
try:
return context.model.by_type(self.alternative_name())
except:
return []

Thomas noted this as well. There is separate document now with all renamed entities (only with IfcBuiltElement -> IfcBuildingElement at the moment, but can be expanded). In short, the current implementation recognizes that the element is potentially outdated, and will also search in the Ifcfile for the updated version (or vice versa).

Hope this is a good solution for it. Another solution will be to simply duplicate the given statements and add a 'Given an file with Schema Identifiers "Applicable Schema1", "Applicable Schema2" etc..'. I my view, this will be more difficult to maintain as with every update of IFC we will have to go back to this file and manually add the updated IFC versions to the Given statement.

@Ghesselink
Copy link
Contributor Author

Due to the recent restructure of the repository, there were many conflicts.

Instead of resolving them all, it was less work to create a new PR #60

@Ghesselink Ghesselink closed this Apr 20, 2023
@Ghesselink Ghesselink deleted the gem005-representations_in_decomposed_elements branch November 1, 2023 10:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants