Python script to upload IFC files

Hi ALL,
I’m trying to finalize a script to upload via a python script an IFC file stored on one of my desktop folders.
I’m able now to upload the file according to the file size limit of the server, but, when i see the commit on the stream no 3D is available…and more…i can see the IDs of each element stored on the file but the hieararchy it self of the file is it not correctly visible on the scene explorer.

I tryied to use powerbi to get the data, i can obtein correctly all the ids objects but i’m not able to see the properties of my file, not even possible to see that on the web.

Here I post the script based on specklepy and python.

from specklepy.api.client import SpeckleClient
from specklepy.transports.server import ServerTransport
from specklepy.api import operations
from specklepy.objects import Base
import ifcopenshell

# Speckle server information
speckle_server_url = "https://app.speckle.systems/"  # Speckle URL
stream_id = "your_stream_id"  # Stream ID
branch_name = "test_branch"  # Branch name for the commit

# Speckle Token
token = "your_speckle_token"

# Initialization
client = SpeckleClient(host=speckle_server_url)
client.authenticate_with_token(token=token)

# Path to the IFC file
ifc_file_path = 'path_to_your_ifc_file.ifc'

# Open the IFC file
ifc_file = ifcopenshell.open(ifc_file_path)

# Speckle Object creation
speckle_base = Base()

# Create separate base objects for IfcSite, IfcBuilding, and IfcBuildingStorey
site = None
building = None
storeys = {}

# List of main objects to add to the scene
main_objects = []

# Step 1: Iterate through all elements and categorize them
for element in ifc_file.by_type("IfcProduct"):
    element_base = Base()
    element_base.name = element.Name if hasattr(element, 'Name') else "Unnamed"
    element_base.category = element.is_a()
    element_base.global_id = element.GlobalId
    
    # Step 2: Classify and organize elements by their hierarchy
    if element.is_a("IfcSite"):
        site = Base()
        site.name = element.Name if element.Name else "Unnamed Site"
        site["GlobalId"] = element.GlobalId
        speckle_base["@site"] = site  # Set as site in Speckle Base

    elif element.is_a("IfcBuilding"):
        building = Base()
        building.name = element.Name if element.Name else "Unnamed Building"
        building["GlobalId"] = element.GlobalId
        if site:
            site["@building"] = building  # Attach building to the site
        speckle_base["@building"] = building  # Add building to base

    elif element.is_a("IfcBuildingStorey"):
        storey_base = Base()
        storey_base.name = element.Name if element.Name else "Unnamed Storey"
        storey_base["GlobalId"] = element.GlobalId
        if building:
            building["@{}".format(element.GlobalId)] = storey_base  # Attach storey to the building
            storeys[element.GlobalId] = storey_base  # Track storeys for further element associations

    # Step 3: Link elements (components) to their respective storey
    if hasattr(element, "ContainedInStructure"):
        for rel in element.ContainedInStructure:
            if rel.is_a("IfcRelContainedInSpatialStructure") and rel.RelatingStructure:
                related_storey = rel.RelatingStructure.GlobalId
                if related_storey in storeys:
                    storeys[related_storey][element.GlobalId] = element_base  # Attach element to the respective storey

# Serialize the Speckle objects and send to the server
serializer = BaseObjectSerializer()
hash_id, obj_dict = serializer.traverse_base(speckle_base)

# Transport objects
transport = ServerTransport(client=client, stream_id=stream_id)

# Send objects to the Speckle server
object_id = operations.send(base=speckle_base, transports=[transport])
print(f"Object ID sent: {object_id}")

# Create commit in the specified branch
commit_id = client.commit.create(
    stream_id=stream_id,
    object_id=object_id,
    message="Upload IFC file with structured hierarchy",
    branch_name=branch_name
)
print(f"Commit ID: {commit_id}")

Let me know if you arrive to solve the problem :slight_smile:

Thanks for sharing the script!

To summarise, you’ve got the basics down with parsing the IFC file using ifcopenshell, restructuring elements like IfcSite, IfcBuilding, and IfcProduct, and sending it to Speckle. But I get that there are still some hiccups with the 3D view, the hierarchy in the Scene Explorer, and property access in Power BI.

I don’t have time to run your script with my IFC file, but if you could share a sample project where you see these issues, that’d help a lot. I can usually grok the resultant hierarchy just from code but seeing an actual result you already have would help a bunch.

Also:

  • Are there specific properties you expected to see but aren’t?
  • Have you tried other IFC files, and do they show the same issues?

For sure,
this is the file uploaded using the script .

https://app.speckle.systems/projects/60a413a5cd/models/2b581b18f4

And this is the link to the same file just dragndroped

https://app.speckle.systems/projects/60a413a5cd/models/c1cd499765

And here a version of the code without hashtags for an easy use of it!!

from specklepy.api.client import SpeckleClient
from specklepy.transports.server import ServerTransport
from specklepy.api import operations
from specklepy.objects import Base
from specklepy.objects.geometry import Mesh
from specklepy.serialization.base_object_serializer import BaseObjectSerializer
import ifcopenshell


speckle_server_url = "https://app.speckle.systems"
stream_id = "XXXXXX"  
branch_name = "XXXXXXX"  


token = "XXXXXXXXX"  


client = SpeckleClient(host=speckle_server_url)
client.authenticate_with_token(token=token)


ifc_file_path = "C:/Users/xxxx/Desktop/TESTIFC/PN1206-1_05_PRA_MOD_002328_1_OA0704P_MEP.ifc"


ifc_file = ifcopenshell.open(ifc_file_path)


speckle_base = Base()

site = None
building = None
storeys = {}


main_objects = []


for element in ifc_file.by_type("IfcProduct"):
    element_base = Base()
    element_base.name = element.Name if hasattr(element, 'Name') else "Unnamed"
    element_base.category = element.is_a()
    element_base.global_id = element.GlobalId
    
 
    if element.is_a("IfcSite"):
        site = Base()
        site.name = element.Name if element.Name else "Unnamed Site"
        site["GlobalId"] = element.GlobalId
        speckle_base["@site"] = site  # Set as site in Speckle Base

    elif element.is_a("IfcBuilding"):
        building = Base()
        building.name = element.Name if element.Name else "Unnamed Building"
        building["GlobalId"] = element.GlobalId
        if site:
            site["@building"] = building  
        speckle_base["@building"] = building  

    elif element.is_a("IfcBuildingStorey"):
        storey_base = Base()
        storey_base.name = element.Name if element.Name else "Unnamed Storey"
        storey_base["GlobalId"] = element.GlobalId
        if building:
            building["@{}".format(element.GlobalId)] = storey_base 
            storeys[element.GlobalId] = storey_base  


    if hasattr(element, "ContainedInStructure"):
        for rel in element.ContainedInStructure:
            if rel.is_a("IfcRelContainedInSpatialStructure") and rel.RelatingStructure:
                related_storey = rel.RelatingStructure.GlobalId
                if related_storey in storeys:
                    storeys[related_storey][element.GlobalId] = element_base  

serializer = BaseObjectSerializer()
hash_id, obj_dict = serializer.traverse_base(speckle_base)


transport = ServerTransport(client=client, stream_id=stream_id)


object_id = operations.send(base=speckle_base, transports=[transport])
print(f"Object ID sent: {object_id}")


commit_id = client.commit.create(
    stream_id=stream_id,
    object_id=object_id,
    message="Upload IFC file with structured hierarchy",
    branch_name=branch_name
)
print(f"Commit ID: {commit_id}")

Yes I should see all the properties like in the link with the ifc just draged and droped.
Yes i tested different files and I have always the same result like in the last picture.

In this picture you can see on the left part one element of the model and in to the right part of the screen you can see the same element globalid and properties but without visualization in 3d.

This is another version of the script but always with the same result:

from specklepy.api.client import SpeckleClient
from specklepy.transports.server import ServerTransport
from specklepy.api import operations
from specklepy.objects import Base
from specklepy.serialization.base_object_serializer import BaseObjectSerializer
import ifcopenshell

speckle_server_url = "https://app.speckle.systems/"  
stream_id = "XXX"  
branch_name = "XXX"  

token = "XXXX" 

client = SpeckleClient(host=speckle_server_url)
client.authenticate(token=token) 

ifc_path = "C:/Users/xxxx/Desktop/TESTIFC/PN1206-1_05_PRA_MOD_002328_1_OA0704P_MEP.ifc"
ifc_file = ifcopenshell.open(ifc_path)

speckle_base = Base()

for element in ifc_file.by_type("IfcProduct"):
    element_base = Base()
    element_base.name = element.Name
    element_base.category = element.is_a()
    element_base.global_id = element.GlobalId
    speckle_base[element.GlobalId] = element_base

serializer = BaseObjectSerializer()
hash_id, obj_dict = serializer.traverse_base(speckle_base)

transport = ServerTransport(client=client, stream_id=stream_id)

object_id = operations.send(base=speckle_base, transports=[transport])
print(f"Object ID sent: {object_id}")

commit_id = client.commit.create(
    stream_id=stream_id,
    object_id=object_id,
    message="Upload files",
    branch_name=branch_name
)
print(f"Commit ID: {commit_id}")

Ok - I’m not sure what you get from ifcopenshell; it is years since I last used it as a data interrogation tool, but in order for your Python script to bear visual fruit, you will need at least to upload a mesh representation of each element in a displayValue prop.

For a basic structure if you are looking for a hierarchical structure look into the Collection object.

This has a property collectionType and expects sub-elements in an elements prop as an array.

Collection (collectionType = "model", name = "IFC Filename"):
    elements: [
        Base (ifcType = "IfcPart"):
            displayValue = [Mesh, Mesh, ...],
       Base (ifcType = "IfcPart"):
            displayValue = [Mesh, Mesh, ...],
    ]

Excuse pseudocode

Obviously if you start with the valid IFC schema

Collection (collectionType = "model", name = "IFC Filename"):
    elements: [
        Collection (collectionType = "IFCProject"):
            elements: [
                Collection (collectionType = "IFCSite"):
                    elements: [
                        Collection (collectionType = "IFCBuilding"):
                        elements: [
                            Base (ifcType = "IfcPart"):
                                displayValue = [Mesh, Mesh, ...],
                            Base (ifcType = "IfcPart"):
                                displayValue = [Mesh, Mesh, ...],
                        ]]]]]]]
1 Like

Hi and thanks, i’ve updated my script following your suggestions.
Now i can retriews objects in storey levels but i’m still not able to see 3D elements in the viewer.
I share again the updated code

Here the link of the commit
https://app.speckle.systems/projects/60a413a5cd/models/2b581b18f4

# IMPORT IFC WITH PYTHON
from specklepy.api.client import SpeckleClient
from specklepy.transports.server import ServerTransport
from specklepy.api import operations
from specklepy.objects import Base
from specklepy.serialization.base_object_serializer import BaseObjectSerializer
import ifcopenshell

speckle_server_url = "xxx"  
stream_id = "xxx"  
branch_name = "xxx"  

token = "xxx"  


client = SpeckleClient(host=speckle_server_url)
client.authenticate_with_token(token=token)


ifc_path = "C:/Users/xxx/Desktop/TESTIFC/xxx.ifc"
ifc_file = ifcopenshell.open(ifc_path)

speckle_base = Base()
speckle_base.name = "Model"
speckle_base["collectionType"] = "model"

project = Base()
project.name = "IFC Project"
project["collectionType"] = "IFCProject"

site = Base()
site.name = "Site"
site["collectionType"] = "IFCSite"

building = Base()
building.name = "Unnamed Building"
building["collectionType"] = "IFCBuilding"

storeys = {}

def extract_geometry(ifc_element):
    mesh = Base()  # Placeholder for the actual mesh
    mesh.name = f"Mesh for {ifc_element.GlobalId}"
    return mesh

for element in ifc_file.by_type("IfcProduct"):
    element_base = Base()
    element_base.name = element.Name if hasattr(element, 'Name') else "Unnamed Element"
    element_base["ifcType"] = element.is_a()  # Classify based on IFC type
    element_base.global_id = element.GlobalId

    geometry = extract_geometry(element)
    if geometry:
        element_base["displayValue"] = [geometry] 

    if hasattr(element, "ContainedInStructure"):
        for rel in element.ContainedInStructure:
            if rel.is_a("IfcRelContainedInSpatialStructure") and rel.RelatingStructure.is_a("IfcBuildingStorey"):
                storey_id = rel.RelatingStructure.GlobalId
                if storey_id not in storeys:
                    storey_base = Base()
                    storey_base.name = rel.RelatingStructure.Name if rel.RelatingStructure.Name else "Unnamed Storey"
                    storey_base["ifcType"] = "IFCBuildingStorey"
                    storey_base.global_id = storey_id
                    storey_base["elements"] = []
                    storeys[storey_id] = storey_base

                storeys[storey_id]["elements"].append(element_base)  

building["elements"] = list(storeys.values())  
project["elements"] = [site, building]

speckle_base["elements"] = [project]

serializer = BaseObjectSerializer()
hash_id, obj_dict = serializer.traverse_base(speckle_base)

transport = ServerTransport(client=client, stream_id=stream_id)

object_id = operations.send(base=speckle_base, transports=[transport])
print(f"Object ID sent: {object_id}")

commit_id = client.commit.create(
    stream_id=stream_id,
    object_id=object_id,
    message="Upload IFC file with storey structure and elements",
    branch_name=branch_name
)
print(f"Commit ID: {commit_id}")

Has you can see all the data is there but not the visual 3D!
:smile:

Hi @oscarazzus

I had a quick look at your stream and saw that your mesh display values have a speckle_type of Base. This will make the converter skip them

image

Try turning them into Mesh

Cheers

Thanks i will try today :smile:

Hi Alex, i’m not able to change the Speckle type using Ifc categories.
I’m trying since 2 days whitout success.

I share there my last code.
I’m able right now to upload correctly an IFC file and see storey levels and all the elements of an ifc file and some properties, but still not able to see the model in 3D.
I share too a screenshot of the result printed in my terminal where it shows that are presents 3 meshes.

image

Here the code:

from specklepy.api.client import SpeckleClient
from specklepy.transports.server import ServerTransport
from specklepy.api import operations
from specklepy.objects import Base
import ifcopenshell
import ifcopenshell.geom

speckle_server_url = "xxxx/"  
stream_id = "x" 

client = SpeckleClient(host=speckle_server_url)
client.authenticate_with_token("xxxxx")

ifc_path = "C:/Users/xxxx/Desktop/TESTIFC/SimpleWall.ifc"
ifc_file = ifcopenshell.open(ifc_path)

speckle_base = Base()
speckle_base.name = "IFC Model"
speckle_base["collectionType"] = "model"

project = Base()
project.name = "IFC Project"
project.speckle_type = "IFCProject"

site = Base()
site.name = "Site"
site.speckle_type = "IFCSite"

building = Base()
building.name = "Unnamed Building"
building.speckle_type = "IFCBuilding"

storeys = {}

def extract_properties(ifc_element):
    props = Base()
    props["global_id"] = ifc_element.GlobalId
    props["name"] = ifc_element.Name if hasattr(ifc_element, 'Name') else "Unnamed Element"
    props["ifcType"] = ifc_element.is_a()  
    props["ObjectType"] = ifc_element.ObjectType if hasattr(ifc_element, 'ObjectType') else "N/A"
    props["Tag"] = ifc_element.Tag if hasattr(ifc_element, 'Tag') else "N/A"
    props["expressID"] = ifc_element.id()  
    if hasattr(ifc_element, "HasPropertySets"):
        props["PropertySets"] = {}
        for pset in ifc_element.HasPropertySets:
            if hasattr(pset, "Name") and hasattr(pset, "HasProperties"):
                pset_name = pset.Name
                props["PropertySets"][pset_name] = {}
                for prop in pset.HasProperties:
                    prop_name = prop.Name
                    prop_value = prop.NominalValue.wrappedValue if hasattr(prop.NominalValue, 'wrappedValue') else prop.NominalValue
                    props["PropertySets"][pset_name][prop_name] = prop_value

    if hasattr(ifc_element, "IsDefinedBy"):
        props["BaseQuantities"] = {}
        for rel in ifc_element.IsDefinedBy:
            if rel.is_a("IfcRelDefinesByProperties"):
                prop_set = rel.RelatingPropertyDefinition
                if prop_set.is_a("IfcElementQuantity"):
                    for quantity in prop_set.Quantities:
                        quantity_name = quantity.Name
            
                        if hasattr(quantity, "LengthValue"):
                            quantity_value = quantity.LengthValue
                        elif hasattr(quantity, "AreaValue"):
                            quantity_value = quantity.AreaValue
                        elif hasattr(quantity, "VolumeValue"):
                            quantity_value = quantity.VolumeValue
                        elif hasattr(quantity, "CountValue"):
                            quantity_value = quantity.CountValue
                        elif hasattr(quantity, "WeightValue"):
                            quantity_value = quantity.WeightValue
                        elif hasattr(quantity, "TimeValue"):
                            quantity_value = quantity.TimeValue
                        else:
                            quantity_value = None  
                        
                        props["BaseQuantities"][quantity_name] = quantity_value

    return props


def extract_geometry(ifc_element):
    settings = ifcopenshell.geom.settings()
    settings.set(settings.USE_WORLD_COORDS, True)
    
    try:
        shape = ifcopenshell.geom.create_shape(settings, ifc_element)
        geometry = shape.geometry
        vertices = geometry.verts
        faces = geometry.faces

        if len(vertices) == 0 or len(faces) == 0:
            print(f"No geometry for element {ifc_element.GlobalId}")
            return None

    
        speckle_faces = []
        for i in range(0, len(faces), 3):
            speckle_faces.append(f"3 {faces[i]} {faces[i+1]} {faces[i+2]}")


        mesh = Base()
        mesh.name = f"Mesh for {ifc_element.GlobalId}"
        mesh.speckle_type = "Objects.Geometry.Mesh"
        mesh["vertices"] = list(vertices)
        mesh["faces"] = speckle_faces
        mesh["units"] = "millimeters"


        print(f"Mesh for element {ifc_element.GlobalId}: vertices={len(vertices)}, faces={len(faces)//3}")
        return mesh
    except Exception as e:
        print(f"Error extracting geometry for {ifc_element.GlobalId}: {e}")
        return None


for element in ifc_file.by_type("IfcProduct"):
    element_base = Base()  
    

    properties = extract_properties(element)
    for key in properties.get_dynamic_member_names():
        element_base[key] = properties[key]

    element_base.speckle_type = properties["ifcType"]

    geometry = extract_geometry(element)
    if geometry:
        element_base["displayValue"] = [geometry]
    else:
        print(f"Element {element.GlobalId} does not have valid geometry, but properties were added.")
    
    if hasattr(element, "ContainedInStructure"):
        for rel in element.ContainedInStructure:
            if rel.is_a("IfcRelContainedInSpatialStructure") and rel.RelatingStructure.is_a("IfcBuildingStorey"):
                storey_id = rel.RelatingStructure.GlobalId
                if storey_id not in storeys:
                    storey_base = Base()
                    storey_base.name = rel.RelatingStructure.Name if rel.RelatingStructure.Name else "Unnamed Storey"
                    storey_base.speckle_type = "IFCBuildingStorey"
                    storey_base["global_id"] = storey_id
                    storey_base["elements"] = []
                    storeys[storey_id] = storey_base

                storeys[storey_id]["elements"].append(element_base)

building["elements"] = list(storeys.values())
site["elements"] = [building]
project["elements"] = [site]
speckle_base["elements"] = [project]

transport = ServerTransport(client=client, stream_id=stream_id)

object_id = operations.send(base=speckle_base, transports=[transport])
print(f"Object ID sent: {object_id}")

commit_id = client.commit.create(
    stream_id=stream_id,
    object_id=object_id,
    message="Uploaded IFC model with correct speckle types and geometry"
)
print(f"Commit ID: {commit_id}")

This is the commit refere to last script i shared

https://app.speckle.systems/projects/60a413a5cd/models/b2b2361027

and this is the same model uploaded with drag and drop

https://app.speckle.systems/projects/60a413a5cd/models/aec5b5f9e5

What @alex referred to is instead of

mesh = Base()
    mesh.name = f"Mesh for {ifc_element.GlobalId}"
    mesh.speckle_type = "Objects.Geometry.Mesh"
    mesh["vertices"] = list(vertices)
    mesh["faces"] = speckle_faces
    mesh["units"] = "millimeters"

Try

from specklepy.objects.geometry import Mesh

speckle_mesh = Mesh(
            vertices=list(vertices)
            faces=speckle_faces,
            colors=[],
            textureCoordinates=[],
            units=Units,
            area = mesh_area,
            bbox=Box(area=0.0, volume=0.0),
        )
1 Like

yesss :smiley: it works now!!!

from specklepy.api.client import SpeckleClient
from specklepy.transports.server import ServerTransport
from specklepy.api import operations
from specklepy.objects import Base
from specklepy.objects.geometry import Mesh, Box
import ifcopenshell
import ifcopenshell.geom

speckle_server_url = "https://app.speckle.systems"  
stream_id = "xxxx"  

client = SpeckleClient(host=speckle_server_url)
client.authenticate_with_token("xxxx")
ifc_path = "C:/Users/Oscar/Desktop/TESTIFC/SimpleWall.ifc"
ifc_file = ifcopenshell.open(ifc_path)

speckle_base = Base()
speckle_base.name = "IFC Model"
speckle_base["collectionType"] = "model"

project = Base()
project.name = "IFC Project"
project.speckle_type = "IFCProject"

site = Base()
site.name = "Site"
site.speckle_type = "IFCSite"

building = Base()
building.name = "Unnamed Building"
building.speckle_type = "IFCBuilding"

storeys = {}

def extract_properties(ifc_element):
    props = Base()
    props["global_id"] = ifc_element.GlobalId
    props["name"] = ifc_element.Name if hasattr(ifc_element, 'Name') else "Unnamed Element"
    props["ifcType"] = ifc_element.is_a()
    props["ObjectType"] = ifc_element.ObjectType if hasattr(ifc_element, 'ObjectType') else "N/A"
    props["Tag"] = ifc_element.Tag if hasattr(ifc_element, 'Tag') else "N/A"
    props["expressID"] = ifc_element.id()

    if hasattr(ifc_element, "HasPropertySets"):
        props["PropertySets"] = {}
        for pset in ifc_element.HasPropertySets:
            if hasattr(pset, "Name") and hasattr(pset, "HasProperties"):
                pset_name = pset.Name
                props["PropertySets"][pset_name] = {}
                for prop in pset.HasProperties:
                    prop_name = prop.Name
                    prop_value = prop.NominalValue.wrappedValue if hasattr(prop.NominalValue, 'wrappedValue') else prop.NominalValue
                    props["PropertySets"][pset_name][prop_name] = prop_value

    return props

def extract_geometry(ifc_element):
    settings = ifcopenshell.geom.settings()
    settings.set(settings.USE_WORLD_COORDS, True)

    try:
        shape = ifcopenshell.geom.create_shape(settings, ifc_element)
        geometry = shape.geometry
        vertices = geometry.verts
        faces = geometry.faces

        if len(vertices) == 0 or len(faces) == 0:
            print(f"No geometry for element {ifc_element.GlobalId}")
            return None

        # Creazione della lista delle facce
        speckle_faces = []
        for i in range(0, len(faces), 3):
            speckle_faces.append(3)  # Il numero 3 indica una faccia triangolare
            speckle_faces.extend([faces[i], faces[i+1], faces[i+2]])

        mesh_area = 0.0  # Placeholder per il calcolo dell'area
        speckle_mesh = Mesh(
            vertices=list(vertices),
            faces=speckle_faces,
            colors=[],
            textureCoordinates=[],
            units="millimeters",
            area=mesh_area,
            bbox=Box(area=0.0, volume=0.0),
        )

        print(f"Mesh for element {ifc_element.GlobalId}: vertices={len(vertices)}, faces={len(faces)//3}")
        return speckle_mesh
    except Exception as e:
        print(f"Error extracting geometry for {ifc_element.GlobalId}: {e}")
        return None

for element in ifc_file.by_type("IfcProduct"):
    element_base = Base()

    properties = extract_properties(element)
    for key in properties.get_dynamic_member_names():
        element_base[key] = properties[key]

    element_base.speckle_type = properties["ifcType"]

    geometry = extract_geometry(element)
    if geometry:
        element_base["displayValue"] = [geometry]
    else:
        print(f"Element {element.GlobalId} does not have valid geometry, but properties were added.")

    if hasattr(element, "ContainedInStructure"):
        for rel in element.ContainedInStructure:
            if rel.is_a("IfcRelContainedInSpatialStructure") and rel.RelatingStructure.is_a("IfcBuildingStorey"):
                storey_id = rel.RelatingStructure.GlobalId
                if storey_id not in storeys:
                    storey_base = Base()
                    storey_base.name = rel.RelatingStructure.Name if rel.RelatingStructure.Name else "Unnamed Storey"
                    storey_base.speckle_type = "IFCBuildingStorey"
                    storey_base["global_id"] = storey_id
                    storey_base["elements"] = []
                    storeys[storey_id] = storey_base

                storeys[storey_id]["elements"].append(element_base)

building["elements"] = list(storeys.values())
site["elements"] = [building]
project["elements"] = [site]
speckle_base["elements"] = [project]

transport = ServerTransport(client=client, stream_id=stream_id)
object_id = operations.send(base=speckle_base, transports=[transport])
print(f"Object ID sent: {object_id}")

commit_id = client.commit.create(
    stream_id=stream_id,
    object_id=object_id,
    message="Uploaded IFC model with correct Speckle types and geometry"
)
print(f"Commit ID: {commit_id}")
1 Like


but it is not finished!
Why I can not see colors correctly?
I can fix the code to extract all the pset too.
But do you think it is possible to show color materials as we can see in the original ifc files?

In order for the colors to show, the objects either need to have a proper material with said colors, or alternatively the mesh objects can have per vertex colors

1 Like

Thanks,

I think i need to fix the data structure too cause when i try to open the stream in powerbi I get an error like the data column is not present.