Menu

how can i add some new entify or property to module ifcopenshell?

2021-12-11
2021-12-20
  • Zhijian Jin

    Zhijian Jin - 2021-12-11

    I try to add some new entify and some Propertifies to do my research about Building heating control . I try to use methode ifcopenshell_wrapper.new_IfcBaseClass, but i need a schema_identifier. What is this Schema_identifier?

     
    • Thomas Krijnen

      Thomas Krijnen - 2021-12-12

      It's not very clear whether you want to add:
      an entity to the schema, or
      an instance of an existing entity to an IFC file

      For the first. I would recommend to create an Express file. Just use an existing one as a starting point and add the schema.

      Then you can use the dynamic latebound schema parser. Only available in Python and do something like this:

      import ifcopenshell
      import ifcopenshell.express
      schema = ifcopenshell.express.parse('my_new_schema.exp')
      ifcopenshell.register_schema(schema)
      f = ifcopenshell.file(schema=schema.schema_name)
      

      If it's just about the 2nd option, you open a file with

      f = ifcopenshell.open() or start a new file with ifcopenshell.file(schema=...) and use convenience methods such as f.createIfcWall(GlobalId=ifcopenshell.guid.new(), ...)

       
  • Zhijian Jin

    Zhijian Jin - 2021-12-13

    Hello Thomas,
    thank u for ur informative answer! I am trying to creat some new ifctype, for example "ifctoken" to say if a pump on or off.
    what do u mean add schema to the Express file? What does schema looks like and how can i add it?

     

    Last edit: Zhijian Jin 2021-12-14
  • Zhijian Jin

    Zhijian Jin - 2021-12-14

    Thank u! That's what I am looking for all the time! I can move on to next step now.

     

    Last edit: Zhijian Jin 2021-12-14
  • Zhijian Jin

    Zhijian Jin - 2021-12-14

    Hello Thomas,

    i copy the express file in txt and change the name to somethin.exp, but i can only get a empty express_parse in file ordner express. What I did wrong?

     
    • Thomas Krijnen

      Thomas Krijnen - 2021-12-15

      express_parse in file ordner express

      what do you mean by this?

      Can you share exactly what you have tried?

       
  • Zhijian Jin

    Zhijian Jin - 2021-12-15

    Thank for ur Answer. That's my bad i didn't describe it clearly.

    I copyed the express file that u show into a txt file and tried to bild a new type ifctoken in it by copy ifcwall. I copyed and changed all text, that have ifcwall in it, to text for ifctoken.

    And i build a py.file in the same path address:

    import ifcopenshell
    import ifcopenshell.express
    schema = ifcopenshell.express.parse('my_version.exp')
    ifcopenshell.register_schema(schema)
    f = ifcopenshell.file(schema=schema.schema_name)
    

    after run i have Error message:

     File "somewhere\mycode.py", line 9, in <module>
        schema = ifcopenshell.express.parse('my_version.exp')
    
      File "D:\Annaconda\lib\site-packages\ifcopenshell\express\__init__.py", line 19, in parse
        mapping = express_parser.parse(fn)
    
    AttributeError: module 'express_parser' has no attribute 'parse'
    
    
    Traceback (most recent call last):
      File "D:\Annaconda\lib\site-packages\pyparsing\core.py", line 1854, in parse_file
        file_contents = file_or_filename.read()
    AttributeError: 'str' object has no attribute 'read'
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "bootstrap.py", line 102, in <module>
        express = grammar.parseFile(os.path.join(os.path.dirname(__file__), 'express.bnf'))
      File "D:\Annaconda\lib\site-packages\pyparsing\core.py", line 1856, in parse_file
        with open(file_or_filename, "r", encoding=encoding) as f:
    FileNotFoundError: [Errno 2] No such file or directory: 'express.bnf'
    

    And I find when i go into ifcopenshell module file, go into a file folder "express file". A empty .py file named "express_parser" is made. See the picture that I uploaded.

    That is my situation right now.

     
  • Zhijian Jin

    Zhijian Jin - 2021-12-15

    Hi, Thomas,

    here is my main code, I use txt to save express file:

    import ifcopenshell
    import ifcopenshell.express
    import os
    schema = ifcopenshell.express.parse('my_version.txt')
    ifcopenshell.register_schema(schema)
    f = ifcopenshell.file(schema=schema.schema_name)
    

    it goes to express_parser
    here is the code express_parser:

    import os
    import sys
    import pickle
    
    import schema
    import mapping
    
    from pyparsing import *
    from nodes import *
    
    def parse(fn):
        cache_file = fn + ".cache.dat"
        if os.path.exists(cache_file) and os.path.getmtime(cache_file) >= os.path.getmtime(fn):
            with open(cache_file, "rb") as f:
                m = pickle.load(f)
    

    what means ".cache.dat" here? It makes the code can't find my express file.
    But if i delet ".cache.dat", I get Error message in line m = pickle.load(f): _pickle.UnpicklingError: invalid load key, '\x0d'.

     

    Last edit: Zhijian Jin 2021-12-15
    • Thomas Krijnen

      Thomas Krijnen - 2021-12-16

      express parsing is a bit slow, so the resulting syntax tree is cached.

      os.path.exists() won't throw an exception it's just a check if the cache exists.

      you probably have 'my_version.txt' in another directory than the current working directory where you are running the script. Maybe use an absolute path for 'my_version.txt'

       
  • Zhijian Jin

    Zhijian Jin - 2021-12-16

    Thanks Thomas, i thought that was a Error, but it was just a check.

    I run my main code above and i got a Error message:

    File "D:\DOC\BA\IFCfile\ifcmodulechange\nachantwort.py", line 10, in <module>
        schema = ifcopenshell.express.parse('my_version.txt')
    
      File "D:\Annaconda\lib\site-packages\ifcopenshell\express\__init__.py", line 19, in parse
        mapping = express_parser.parse(fn)
    
      File "D:\Annaconda\lib\site-packages\ifcopenshell\express\express_parser.py", line 480, in parse
        ast = syntax.parseFile(fn)
    
      File "D:\Annaconda\lib\site-packages\pyparsing\core.py", line 1865, in parse_file
        raise exc.with_traceback(None)
    
    ParseException: Expected CaselessKeyword 'schema'
    

    here is the code for pyparsing/core.py, where raise exc.with_traceback(None) runs:

    def parse_file(
            self,
            file_or_filename: Union[str, Path, TextIO],
            encoding: str = "utf-8",
            parse_all: bool = False,
            *,
            parseAll: bool = False,
        ) -> ParseResults:
            """
            Execute the parse expression on the given file or filename.
            If a filename is specified (instead of a file object),
            the entire file is opened, read, and closed before parsing.
            """
            parseAll = parseAll or parse_all
            try:
                file_contents = file_or_filename.read()
            except AttributeError:
                with open(file_or_filename, "r", encoding=encoding) as f:
                    file_contents = f.read()
            try:
                return self.parse_string(file_contents, parseAll)
            except ParseBaseException as exc:
                if ParserElement.verbose_stacktrace:
                    raise
                else:
                    # catch and re-raise exception from here, clears out pyparsing internal stack trace
                    raise exc.with_traceback(None)
    

    I totally don't understand what is going on here. Pls help.

     

    Last edit: Zhijian Jin 2021-12-16
    • Thomas Krijnen

      Thomas Krijnen - 2021-12-16

      It failed to parse your file my_version.txt what's in it?

       
  • Zhijian Jin

    Zhijian Jin - 2021-12-16

    It's original express file plus my new entify 'ifctoken'
    I just search all text with word "ifcwall" and creat new text no more with "ifcwall" but with "ifctoken"
    Here is what i added to the express file.

    TYPE IfcTokenTypeEnum=ENUMERATION OF
        (TOKEN
        ,USERDEFINED
        ,NOTDEFINED);
    END_TYPE;
    
    ENTITY IfcBuildingElement
     ABSTRACT SUPERTYPE OF (ONEOF
        (IfcBeam
        ,IfcBuildingElementProxy
        ,IfcChimney
        ,IfcColumn
        ,IfcCovering
        ,IfcCurtainWall
        ,IfcDoor
        ,IfcFooting
        ,IfcMember
        ,IfcPile
        ,IfcPlate
        ,IfcRailing
        ,IfcRamp
        ,IfcRampFlight
        ,IfcRoof
        ,IfcShadingDevice
        ,IfcSlab
        ,IfcStair
        ,IfcStairFlight
        ,IfcWall
        ,IfcWindow
        ,IfcToken))
     SUBTYPE OF (IfcElement);
     WHERE
        MaxOneMaterialAssociation  SIZEOF (QUERY(temp  SELFIfcObjectDefinition.HasAssociations 
      'IFC4X1.IFCRELASSOCIATESMATERIAL' IN TYPEOF(temp)
      )) = 1;
    END_ENTITY;
    
    ENTITY IfcBuildingElementType
     ABSTRACT SUPERTYPE OF (ONEOF
        (IfcBeamType
        ,IfcBuildingElementProxyType
        ,IfcChimneyType
        ,IfcColumnType
        ,IfcCoveringType
        ,IfcCurtainWallType
        ,IfcDoorType
        ,IfcFootingType
        ,IfcMemberType
        ,IfcPileType
        ,IfcPlateType
        ,IfcRailingType
        ,IfcRampFlightType
        ,IfcRampType
        ,IfcRoofType
        ,IfcShadingDeviceType
        ,IfcSlabType
        ,IfcStairFlightType
        ,IfcStairType
        ,IfcWallType
        ,IfcWindowType
        ,IfcToken))
     SUBTYPE OF (IfcElementType);
    END_ENTITY;
    
    ENTITY IfcToken
     SUPERTYPE OF (ONEOF
        (IfcTokenElementedCase))
     SUBTYPE OF (IfcBuildingElement);
        PredefinedType  OPTIONAL  IfcTokenTypeEnum ;
     WHERE
        CorrectPredefinedType  NOT(EXISTS(PredefinedType)) OR
     (PredefinedType  IfcTokenTypeEnum.USERDEFINED) OR
     ((PredefinedType = IfcTokenTypeEnum.USERDEFINED) AND EXISTS (SELFIfcObject.ObjectType));
        CorrectTypeAssigned  (SIZEOF(IsTypedBy) = 0) OR
      ('IFC4X1.IFCTOKENTYPE' IN TYPEOF(SELFIfcObject.IsTypedBy[1].RelatingType));
    END_ENTITY;
    
    ENTITY IfcTokenElementedCase
     SUBTYPE OF (IfcToken);
     WHERE
        HasDecomposition  HIINDEX(SELFIfcObjectDefinition.IsDecomposedBy)  0;
    END_ENTITY;
    
    ENTITY IfcTokenType
     SUBTYPE OF (IfcBuildingElementType);
        PredefinedType  IfcTokenTypeEnum;
     WHERE
        CorrectPredefinedType  (PredefinedType  IfcTokenTypeEnum.USERDEFINED) OR
    ((PredefinedType = IfcTokenTypeEnum.USERDEFINED) AND EXISTS(SELFIfcElementType.ElementType));
    END_ENTITY;
    
     

    Last edit: Zhijian Jin 2021-12-16
    • Thomas Krijnen

      Thomas Krijnen - 2021-12-17

      Can you share the complete file? Maybe you inserted in the wrong place or something...

       
  • Zhijian Jin

    Zhijian Jin - 2021-12-17

    Sure. I very apprieciate ur help, Thomas. Here is URL of my txt file. If u use ctrl+f to search "ifctoken" , u can find what i did. But not in browser, the search result in browser is not complete. Pls open and search "ifctoken" with Editor of windows.
    https://drive.google.com/file/d/1FXCZP9NKRGv7UW5eFziPwwraRMAxdXT3/view?usp=sharing

     

    Last edit: Zhijian Jin 2021-12-17
    • Thomas Krijnen

      Thomas Krijnen - 2021-12-18

      For some reason your file starts with

      (
      Copyright by
      

      but actually the original file starts with

      (*
      Copyright by:
      

      (* is the start of a comment. So with that altered it tries to interpret the copyright text as the formal schema. You can use text based diff tools to see these differences between files.

       
  • Zhijian Jin

    Zhijian Jin - 2021-12-20

    Hello, Thomas,

    my Tutor has changed strategie. We will try to record our plan with property, no more with neu instance. So i don't need to creat new instance anymore. Thank u for ur informative and frendly help.

     
    👍
    2

Log in to post a comment.