Solved

How to iterate over a list in PythonCaller?


Badge +1

 I have a basic list of guids to iterate over and get the related object, append to another list, then use in a function as one of the arguments. Here is my script:

import fme
import fmeobjects
import uuid
import time
import tempfile
import ifcopenshell
 
class FeatureProcessor(object):
    
    def input(self, feature):    
    
        create_guid = lambda: ifcopenshell.guid.compress(uuid.uuid1().hex)
        
 
        # Obtain references to master file
        filename = FME_MacroValues['OUTPUT_FILE_PATH']
        ifcfile = ifcopenshell.open(filename)
        
        owner_history = ifcfile.by_type("IfcOwnerHistory")[0]
        building_storey = ifcfile.by_guid(feature.getAttribute('storey_guid'))
        
 
 
 
        guids = feature.getAttribute('_guids{}._guid')      
 
        guids = [ifcfile.by_guid(x) for x in guids]
        
           # Relate the wall to the building storey
        ifcfile.createIfcRelContainedInSpatialStructure(create_guid(), owner_history, "Building Storey Container", None, guids, building_storey)
 
 
        for i, x in enumerate(guids):
            objects = feature.setAttribute('_guids{%d}._guid' % i, x)
            
 
   
        # Write the contents of the file to disk
         
        ifcfile.write(filename)        
 
        self.pyoutput(feature)
 
        def close(self):
 
            pass

Here is the list:

guidList Error message:

Python Exception <TypeError>: Could not convert attribute value to a supported attribute type.

Traceback (most recent call last):

 File "<string>", line 36, in input

TypeError: Could not convert attribute value to a supported attribute type.

Error encountered while calling method `input'

Python_IFCRELCONTAINEDINSPATIALSTRUCTURE (PythonFactory): PythonFactory failed to process feature

 

 

 

 

What really helped me was this presentation. I was able to populate the ifc function, but could not correctly output a feature attribute to look at. So close! Any insight is appreciated.

 

Thanks,

Loren

 

 

icon

Best answer by lorenrouth 12 June 2022, 21:43

View original

4 replies

Badge +4

Your iteration looks fine, I’m more concerned about the datatype of the object ifcfile.by_guid() ? Since you want this object set as an attribute on the feature, then it must comply with the supported datatypes for feature attributes. I also see no point in asigning the setAttribute to a variable, in you case objects will always be None.

 

 

Badge +4

Your iteration looks fine, I’m more concerned about the datatype of the object ifcfile.by_guid() ? Since you want this object set as an attribute on the feature, then it must comply with the supported datatypes for feature attributes. I also see no point in asigning the setAttribute to a variable, in you case objects will always be None.

 

 

If ifcfile.by_guid() has a output as string that you want then use str(ifcfile.by__guid())

Badge +1

If ifcfile.by_guid() has a output as string that you want then use str(ifcfile.by__guid())

I think what is tripping me up is that ifcfile.by_guid() can't be cast as a string until after being used in the function. The ifcopenshell library uses C++ with a Python API. When I cast as string, as you suggest, it gave me an error and definitely did not like the string. Ironically, IFC files themselves are all readable text. So,  the next block of code where it creates an attribute output is where I need to cast, but how?

 

for i, x in enumerate(guids):

      feature.setAttribute('_guids{%d}._guid' % i, x)

       

      feature.setAttribute("objects", guids)

 

 

 

Badge +1

If ifcfile.by_guid() has a output as string that you want then use str(ifcfile.by__guid())

Aaaaand, I figured it out!

        for i, x in enumerate(guids):
            feature.setAttribute('_guids{%d}._guid' % i, str(x))
            
            feature.setAttribute("objects", str(guids))
   

By casting both the iterator  x  (is that what it is?) and the output attribute, it worked:

 

Output:

[#82=IfcWall('1CigTcweSHx9IGt25SkRI6',#5,'Generic - 8"','Basic Wall',$,#62,#81,'Generic - 8"',$), #157=IfcWall('1DWP5kweSHx9eNt25SkRI6',#5,'Generic - 8"','Basic Wall',$,#137,#156,'Generic - 8"',$), #232=IfcWall('1EHslyweSHx9Prt25SkRI6',#5,'Generic - 8"','Basic Wall',$,#212,#231,'Generic - 8"',$), #307=IfcWall('1F37wXweSHx9Wct25SkRI6',#5,'Generic - 5"','Basic Wall',$,#287,#306,'Generic - 5"',$), #382=IfcWall('1Fs8DWweSHxB4zt25SkRI6',#5,'Generic - 8"','Basic Wall',$,#362,#381,'Generic - 8"',$), #457=IfcWall('1GefR7weSHxBBAt25SkRI6',#5,'Generic - 5"','Basic Wall',$,#437,#456,'Generic - 5"',$), #532=IfcWall('1HRHRJweSHx9D1t25SkRI6',#5,'Generic - 5"','Basic Wall',$,#512,#531,'Generic - 5"',$), #625=IfcWindow('1Hw564weSHxA5gt25SkRI6',#5,'36" x 48"','Fixed',$,#609,#624,'4eec09fe-9a68-488f-8f66-f8eac8f83d14-00056e4c',48.,36.,.WINDOW.,$,$), #669=IfcWindow('1H_KsoweSHxBB2t25SkRI6',#5,'36" x 48"','Fixed',$,#653,#668,'4eec09fe-9a68-488f-8f66-f8eac8f83d14-00056eaa',48.,36.,.WINDOW.,$,$), #713=IfcWindow('1I0m_bweSHx9MPt25SkRI6',#5,'36" x 48"','Fixed',$,#697,#712,'4eec09fe-9a68-488f-8f66-f8eac8f83d14-00056edc',48.,36.,.WINDOW.,$,$), #757=IfcWindow('1I3lggweSHx8Evt25SkRI6',#5,'36" x 48"','Fixed',$,#741,#756,'4eec09fe-9a68-488f-8f66-f8eac8f83d14-00056e7f',48.,36.,.WINDOW.,$,$), #801=IfcWindow('1I7BVcweSHxBySt25SkRI6',#5,'36" x 48"','Fixed',$,#785,#800,'4eec09fe-9a68-488f-8f66-f8eac8f83d14-00056e95',48.,36.,.WINDOW.,$,$), #845=IfcWindow('1IAACRweSHx8kzt25SkRI6',#5,'36" x 48"','Fixed',$,#829,#844,'4eec09fe-9a68-488f-8f66-f8eac8f83d14-00056ebd',48.,36.,.WINDOW.,$,$)]

 

A nice way to end the weekend!

Reply