Hallo! Ich habe gerade begonnen mit der Unterstützung von Chat GDP mir ein Excel Export und Import-Skript für Blender BIM zu basteln. Der Export funktioniert. Beim Import bekomme ich ständig Indentation errors. Anbei das Skript. Vielleicht kann mir jemand einen Tip geben, woran es liegt. Wie bereits erwähnt sind das meine Anfänge und kenne mich nüsse aus.....
import bpy
from bpy import data as D
from bpy import context as C
from mathutils import *
from math import *
import ifcopenshell
import openpyxl
ifc_file_path = r"C:\Users\simon.engels\OneDrive - Geoconsult Group\TEMP\4739\Export\MSP\Baugrundmodell_Arbeitsstand_20241121.ifc"
excel_path = r"C:\Users\simon.engels\OneDrive - Geoconsult Group\TEMP\4739\Export\MSP\Baugrundmodell_Arbeitsstand_20241121.xlsx"
ifc_file = ifcopenshell.open(ifc_file_path)
wb = openpyxl.load_workbook(excel_path)
for sheet_name in wb.sheetnames:
sheet = wb[sheet_name]
headers = list(sheet.iter_rows(min_row=1, max_row=1, values_only=True))[0]
headers = [str(header).strip() for header in headers]
global_id_idx = headers.index("Global ID")
property_set = ifc_file.create_entity(
"IfcPropertySet",
Global Id=ifcopenshell.guid.new(),
Name=sheet_name
)
for row in sheet.iter_rows(min_row=2, values_only=True):
global_id = row[global_id_idx]
if not global_id:
continue
element = ifc_file.by_guid(global_id)
if not element:
continue
if not hasattr(element, "IsDefinedBy") or not element.IsDefinedBy:
element.IsDefinedBy = []
element.IsDefinedBy.append(
ifc_file.create_entity(
"IfcRelDefinesByProperties",
GlobalId=ifcopenshell.guid.new(),
RelatingPropertyDefinition=property_set,
RelatedObjects=[element]
)
)
for header, value in zip(headers, row):
if header != "Global ID" and value:
property_value = ifc_file.create_entity(
"IfcPropertySingleValue",
Name=header,
NominalValue=ifcopenshell.util.element.create_ifc_string(value)
)
property_set.HasProperties.append(property_value)
# Save the updated IFC file
output_path = r"C:\Users\simon.engels\OneDrive - Geoconsult Group\TEMP\4739\Export\MSP\Baugrundmodell_UPDATE.ifc"
ifc_file.write(output_path)
print(f"Updated IFC file saved at {output_path}")
IFC Attribuierung mittels Excelsheets
Wenn du den Python Code in Codetags setzen würdest, wäre es für alle im Forum viel leichter zu verstehen, was dein Problem ist.
Die Indentation ist ja teil des Pythoncodes und wenn du genau hier ein Fehler hast, ist das Fehlen der Codetags besonders hinderlich.
Folgende Zeile stimmt nicht und muss um 4 Whitespaces nach links gerückt werden.
Generell zu dein Code, wenn das die Codequalität von ChatGPT ist möchte ich das Problem zurück haben!
Warum die *path Variablen RawStrings sein müssen ( r" ") erschließt sich mir nicht, aber es sieht Falsch aus.
Generell sollten python Programme eine main Funktion haben, und nicht einfach Code ausführen, wenn Sie gestartet werden. ungefähr so:
Auch wenn du Technisch einfach Attribute an Dinge hängen kannst, solltest du das niemals machen, die Folgende Zeile ist daher ein Codesmell denn du anders schreiben solltest.
Die Indentation ist ja teil des Pythoncodes und wenn du genau hier ein Fehler hast, ist das Fehlen der Codetags besonders hinderlich.
Folgende Zeile stimmt nicht und muss um 4 Whitespaces nach links gerückt werden.
Code: Alles auswählen
property_set = ifc_file.create_entity(
"IfcPropertySet",
Global Id=ifcopenshell.guid.new(),
Name=sheet_name
)
Generell zu dein Code, wenn das die Codequalität von ChatGPT ist möchte ich das Problem zurück haben!
- Das Fängt bei den Importen an, D&C werden nicht verwendet.
- Von mathutils und math wird auch nichts gebraucht und * Importe in From sind immer ein Fehler denn hierbei kannst du nicht mehr sagen, ob die Funktion aus math oder mathutil kommt. Schlimmstenfalls können sich so Funktionen auch überlagern und somit die merkwürdigsten Effekte Produzieren.
- Entweder du importierst bpy oder du wählst einzelne Objekte mit From aus nicht beides.
Warum die *path Variablen RawStrings sein müssen ( r" ") erschließt sich mir nicht, aber es sieht Falsch aus.
Generell sollten python Programme eine main Funktion haben, und nicht einfach Code ausführen, wenn Sie gestartet werden. ungefähr so:
Code: Alles auswählen
def main():
pass
if __name__ == '__main__':
main()
Code: Alles auswählen
if not hasattr(element, "IsDefinedBy") or not element.IsDefinedBy:
element.IsDefinedBy = []
- __blackjack__
- User
- Beiträge: 13919
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@imonbln: Die *path-Variablen enthalten doch \-Zeichen also machen ”rohe” Zeichenkettenliterale schon Sinn.
@Emsalimaem: Ergänzend zu dem was imonbln schon geschrieben hat: Der Ausgabepfad sollte auch am Anfang des Moduls als Konstante definiert werden, wie die anderen beiden Dateipfade. Alle drei enthalten den gleichen Präfix, den man deshalb besser ebenfalls *einmal* als Konstante definiert. Zum zusammensetzen und generell manipulieren von Pfaden gibt es das `pathlib`-Modul. Der Pfad zur Exceldatei ist ja genau der gleiche wie der zur IFC-Datei, nur mit einer anderen Dateiendung. *Das* kann man mit einem `pathlib.Path`-Objekt genau *so* als Code formulieren.
Man sollte keine kryptischen Abkürzungen verwenden. `wb` ist okay in einer interaktiven Shell, aber in einem Programm sollte man `workbook` schreiben wenn das gemeint ist. Wobei man sich das auch sparen kann wenn man nicht den Umweg über die Namen/Titel der Arbeitsblätter geht, sondern einfach über das Objekt iteriert. Dann bekommt man nämlich auch die Arbeitsblätter. Den Namen kann man von den Arbeitsblättern als `title` abfragen, wenn man den braucht.
Das mit dem `iter_rows()` über eine Zeile, in eine Liste mit einem Element umwandeln, um das dann über den Index 0 aus dieser Liste zu holen ist ein bisschen umständlich. Da später dann über die folgenden Zeilen auch noch iteriert wird, würde man sich einfach einen Iterator über *alle* Zeilen erstellen, da mit `next()` die Kopfzeile abgreifen, und dann in einer Schleife über den Rest gehen.
Ich bin so gar kein Fan von ``continue``. Das ist ein unbedingter Sprung den man nicht an der Einrückung ablesen kann und es macht es schwerer am Ende jeder Iteration eine Aktion hinzuzufügen oder Teile aus einer Schleife in eigene Funktionen heraus zu ziehen. Und der Code ist für meinen Geschmack schon lang genug um den sinnvoll auf Funktionen aufzuteilen.
@Emsalimaem: Ergänzend zu dem was imonbln schon geschrieben hat: Der Ausgabepfad sollte auch am Anfang des Moduls als Konstante definiert werden, wie die anderen beiden Dateipfade. Alle drei enthalten den gleichen Präfix, den man deshalb besser ebenfalls *einmal* als Konstante definiert. Zum zusammensetzen und generell manipulieren von Pfaden gibt es das `pathlib`-Modul. Der Pfad zur Exceldatei ist ja genau der gleiche wie der zur IFC-Datei, nur mit einer anderen Dateiendung. *Das* kann man mit einem `pathlib.Path`-Objekt genau *so* als Code formulieren.
Man sollte keine kryptischen Abkürzungen verwenden. `wb` ist okay in einer interaktiven Shell, aber in einem Programm sollte man `workbook` schreiben wenn das gemeint ist. Wobei man sich das auch sparen kann wenn man nicht den Umweg über die Namen/Titel der Arbeitsblätter geht, sondern einfach über das Objekt iteriert. Dann bekommt man nämlich auch die Arbeitsblätter. Den Namen kann man von den Arbeitsblättern als `title` abfragen, wenn man den braucht.
Das mit dem `iter_rows()` über eine Zeile, in eine Liste mit einem Element umwandeln, um das dann über den Index 0 aus dieser Liste zu holen ist ein bisschen umständlich. Da später dann über die folgenden Zeilen auch noch iteriert wird, würde man sich einfach einen Iterator über *alle* Zeilen erstellen, da mit `next()` die Kopfzeile abgreifen, und dann in einer Schleife über den Rest gehen.
Ich bin so gar kein Fan von ``continue``. Das ist ein unbedingter Sprung den man nicht an der Einrückung ablesen kann und es macht es schwerer am Ende jeder Iteration eine Aktion hinzuzufügen oder Teile aus einer Schleife in eigene Funktionen heraus zu ziehen. Und der Code ist für meinen Geschmack schon lang genug um den sinnvoll auf Funktionen aufzuteilen.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown