cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Streamline your workflows and master BIM coordination! Program starts April 28!

Archicad Python API
About automating tasks in Archicad using the Python API.

extracting composite name from slabs, walls, roofs - python API

Dano_
Participant

Hello. I am currently working on a script that extracts Archicad IDs and assigns the composite names of walls, slabs, etc. I know there is a topic about this but for C++. I can't figure it out. My best attempt can be seen below.

rep from Python palette 

==========

 

Spouštění skriptu prepis podláh 2.py

Slab ID: p02, Composite: Unknown composite
Slab ID: p03, Composite: Unknown composite
Slab ID: p04, Composite: Unknown composite
Slab ID: p01, Composite: Unknown composite
Slab ID: p01, Composite: Unknown composite
Slab ID: p01, Composite: Unknown composite

=== Proces dokončen ==

 

Script

 


from archicad import ACConnection

# Connecting to Archicad
conn = ACConnection.connect()
if not conn:
raise Exception("Failed to connect to Archicad")

# Shortened references
acc = conn.commands
acu = conn.utilities
act = conn.types

# Getting the ID of the property 'General_ElementID'
property_id = acu.GetBuiltInPropertyId('General_ElementID')

# Getting all slabs
elements = acc.GetElementsByType('Slab')

# Getting all composites (sandwich structures)
composite_ids = [comp.attributeId for comp in acc.GetAttributesByType('Composite')]
composite_details = acc.GetCompositeAttributes(composite_ids)

# Mapping: composite ID -> composite name
composites = {comp.compositeAttribute.attributeId.guid: comp.compositeAttribute.name for comp in composite_details if comp.compositeAttribute}

# Getting the Archicad ID and composite name (sandwich structure) using the property 'General_ElementID'
def print_slab_ids_and_composites():
property_values = acc.GetPropertyValuesOfElements(elements, [property_id])
for element, value_list in zip(elements, property_values):
archicad_id = None
for value in value_list.propertyValues:
archicad_id = value.propertyValue.value

# Attempt to get the composite ID through classifications or parameters
try:
composite_id = element.elementAttributes[0].attributeId.guid # Confirm or adjust this method if available
except AttributeError:
composite_id = None

# Getting the composite name
composite_name = composites.get(composite_id, "Unknown composite")

# Printing the slab ID and composite name
print(f"Slab ID: {archicad_id}, Composite: {composite_name}")

print_slab_ids_and_composites()

 

 

1 REPLY 1
SzamosiMate
Contributor

Hi Dano_,

 

The problem lies within the Try - Except block that causes your code to siletly fail.

As elements of type ElementIdArrayItem does not have a .elementAttributes property, composite_id is always None.

 

GetElementsByType simply returns ElementIds. You need GetPropertyValuesOfElements to get the Composite index associated with an element, and GetAttributesIndices to bridge the attributes and the elements.

 

A trick for your code - Writeing it like that your IDE will not know the type of your variables. As Graphisoft did not specify the return value of the .connect() method, you need to specify it like this, and the IDE will offer autocompletion/flag errors:

from archicad import ACConnection

from archicad.releases import Commands, Types, Utilities

# Connecting to Archicad
conn = ACConnection.connect()
if not conn:
    raise Exception("Failed to connect to Archicad")

# Shortened references
acc: Commands = conn.commands
acu: Utilities = conn.utilities
act: Types = conn.types