execute_cadwork_command
Execute cwapi3d Python scripts inside Cadwork to read and create 3D geometry, returning structured JSON results.
Instructions
Führt cwapi3d-Python-Code in Cadwork aus und liefert das Ergebnis.
Du (Claude) generierst den Python-Code als String und übergibst ihn hier. Der Code wird im Cadwork-Prozess ausgeführt, wo alle cwapi3d-Module verfügbar sind.
Konvention: Weise das Endergebnis der Variable result zu — sie wird
als JSON zurückgegeben. Beispiel:
result = ec.get_all_identifiable_element_ids()
Bei Multi-Bridge-Betrieb (mehrere Cadwork-Instanzen parallel): vor Arbeitsbeginn get_document_info aufrufen und den Dokumentnamen prüfen, damit Code nicht in der falschen Datei landet. Ist serverseitig OPEN_MCP_CAD_EXPECT_DOC gesetzt, wird diese Prüfung automatisch erzwungen.
Verfügbare Module (Voll-Namen + Aliase): element_controller (ec) utility_controller (uc) attribute_controller (ac) geometry_controller (gc) file_controller (fc) visualization_controller (vc) material_controller (mc) bim_controller (bc) scene_controller (sc) list_controller (lc) cadwork (cw, Typen) ... weitere via get_cadwork_api_help()
Sicherheit: Imports von os, subprocess, shutil, socket, urllib, requests sowie import sind blockiert (Best-Effort). Datei-Operationen sollten ausschließlich über cwapi3d-Funktionen laufen.
Verifizierte Code-Beispiele liefert get_working_examples() — bei Holzbau- Operationen zuerst dort nachschauen statt zu raten.
Für komplette Konstruktionsdetails (AW-Decken-Anschluss, Ecken, IW-Stoss usw.) gibt es get_detail(): zuerst get_detail(list_types=True) für die Übersicht, dann get_detail(type=..., variant=...) für Code + Detail-Regeln.
Achtung Klassiker: Panels: thickness ist die z_local-Dimension, NICHT
die phys. Plattendicke (kann 2700mm Wandhöhe sein). Kerven nur via
ec.subtract_elements_with_undo([pfette], [sparren], False) — nie
cut_shoulder oder cut_elements_with_overmeasure.
Bei Timeout NICHT blind wiederholen: get_connection_status() sagt, ob der Auftrag noch läuft (dann warten), ob die Verbindung pausiert ist oder ob der Cadwork-Hauptthread hängt. Ein Timeout heisst nicht "nicht ausgeführt".
Args:
code: cwapi3d-Python-Code. Endergebnis bitte in result schreiben.
description: Kurzer Klartext, WAS der Auftrag baut ("Fensterwand Süd
erzeugen"). Wird im Fenster "Open MCP CAD Verbindungen" angezeigt,
solange der Auftrag läuft, und landet im Log. Bitte immer setzen —
sonst steht dort nur "execute_cwapi3d".
Liefert: {"ok": True, "result": , "stdout": , "vars": [...]} oder Fehlerobjekt mit "error", "message", "details".
=== BEKANNTE PROBLEME + WORKAROUNDS ===
Reine Berechnungen NICHT ueber die Bridge - blockiert UI und Timeout: Python-Berechnungen lokal mit bash_tool ausfuehren.
cut_element_with_plane erzeugt Artefakt-Vertex wenn Schnittebene auf Elementkante liegt: Element mit Ueberstand erstellen (15-20mm ueber die Schnittlinie hinaus), dann cut_element_with_plane, dann mit stretch_start/end_facet auf die exakte Laenge kuerzen.
cut_element_with_plane behaelt die ANTI-Normal-Seite: Formel: dot(punkt, normal) < distance = Punkt bleibt. Normal immer IN Richtung des Materials zeigen das ENTFERNT werden soll.
Material-Zuweisung im selben Batch wie Erstellung funktioniert nicht zuverlaessig: Material IMMER in einem separaten execute_cadwork_command-Aufruf zuweisen.
stretch_start/end_facet wirkt bei vertikalen Elementen in Z, nicht X/Y: Fuer Y/X-Positionsaenderung vertikaler Elemente: ec.move_element() statt stretch.
Bridge-Timeouts bei grossen Operationen fuehren zu Duplikaten: Kleinere Batches (max 15-20 Elemente pro Schleife). Nach Timeout: Inventar pruefen bevor man wiederholt.
cadwork.ifc_predefined_type() Konstruktor funktioniert nicht: Bestehenden Predefined Type holen: pt = bc.get_ifc_predefined_type(existing_eid), modifizieren, zuruecksetzen.
create_rectangular_panel_vectors: width und thickness sind NICHT was man denkt: Liegende Platte (XY-Ebene): width=Dicke(Z), thickness=Breite(Y). Vertikale Wandplatte (XZ): width=Dicke(Y), thickness=Hoehe(Z). IMMER mit Vertex-Check verifizieren!
create_rectangular_beam_vectors: Startpunkt ist Mitte Querschnitt am ANFANG, length geht AB dort: Startpunkt-Z bei vertikalen Staedern = UK (nicht Mitte!). Startpunkt-X/Y bei horizontalen Schwellen = Anfang + Mitte des Querschnitts.
Vertex-Anzahl ist KEIN zuverlaessiger Indikator fuer Bearbeitungen: Visuell pruefen oder spezifische Koordinaten an der Auflagerstelle vergleichen.
Bridge-Timeout: Rechtsklick in Cadwork-Viewport kann Bridge wieder freigeben: Bei Bridge-Timeout: Rechtsklick ins Cadwork-Viewport, dann 30 Sekunden warten.
p1=START ist der HAEUFIGSTE wiederholte Fehler - trotz Dokumentation!: CHECKLISTE vor JEDEM create:
stretch_start/end_facet wirkt NUR in xl-Richtung (Laengenachse)!: Fuer Width: gc.set_width_real([id], neuer_wert). Fuer Height: gc.set_height_real(). Beide aendern symmetrisch um Mitte, ggf. move_element noetig.
slice_elements_with_plane: IDs aendern sich nach Schnitt - neu suchen!: Nach jedem Schnitt: get_all_identifiable_element_ids() aufrufen und Elemente ueber Filter neu identifizieren.
Verschachtelte Funktionen (def in def) verursachen NameError in Bridge: Keine verschachtelten Funktionen verwenden. Alle Werte als Parameter uebergeben oder Code flach schreiben.
join_elements hat keine Wirkung - solder_elements verwenden: Immer solder_elements statt join_elements verwenden.
set_width_real / set_height_real aendert symmetrisch um Mitte: Nach set_width_real: Versatz berechnen (delta_width/2) und mit ec.move_element korrigieren.
cut_shoulder / cut_heel_shoulder / cut_double_shoulder frieren die Bridge ein (modale Dialoge): cut_shoulder NICHT ueber execute_cadwork_command aufrufen. Versaetze stattdessen mit cut_element_with_plane (Doppelschraege moeglich) selbst konstruieren, oder manuell in Cadwork. Falls Bridge haengt: Dialog bestaetigen (Default 30/0/W) oder Plugin neu starten.
cut_element_with_plane kann keinen innenliegenden Ausschnitt (Fenster) erzeugen: Innenliegende Oeffnungen (Fenster) via solder_elements (C-/Rahmen-Form aus Teilplatten) ODER via subtract mit durchstechendem Element.
Bridge-exec: Funktionen UND Generator-Ausdruecke sehen keine Top-Level-Variablen: Code FLACH schreiben: keine Helfer-Funktionen, keine lambdas, keine Comprehensions/genexpr die eigene Variablen referenzieren. Werte inline berechnen oder als Parameter uebergeben (Funktion ohne freie Variablen).
cut_elements_with_overmeasure hat bei einfachen Durchdringungen keinen Effekt: Fuer gezielte Schnitte cut_element_with_plane oder subtract verwenden.
Bridge liefert nach Timeout veraltete Antwort (Response-Desync): In jeden wichtigen Aufruf einen eindeutigen Marker ins result schreiben (z.B. result={'marker':778899,...}) und pruefen ob er zurueckkommt. Stimmt der Marker nicht -> Antwort verwerfen, Aufruf wiederholen. Nach Timeout zuerst Inventar via ec.get_all_identifiable_element_ids() pruefen bevor weitergebaut wird.
cut_double_tenon wirkungslos ohne Katalog - friert aber NICHT ein; Zapfen via Endtyp GEHT: Bevorzugt: Zapfen via endtype_controller.set_endtype_id_end(balken_id, 376683). Vorhandene IDs holen mit etc.get_existing_tenon_ids(). Fallback ohne Katalog: Zapfen geometrisch mit 4x subtract (je eine Wange einzeln) bauen. ACHTUNG: cut_*_lap (Blattungen) NICHT ungeprueft aufrufen - nutzen 'current 3D options' und koennten wie cut_shoulder Dialoge oeffnen.
stretch nimmt nur den Laengsanteil; doppelschraege Facette wird beim Stretchen plattgebuegelt: Verbreitern/Hoehe aendern: gc.set_width_real / gc.set_height_real (symmetrisch um Mitte). Reine Laenge symmetrisch: gc.set_length_real. Einseitig nur in Laengsachse: stretch_start/end_facet. Doppelschraege am Ende NICHT per stretch nachfuehren - neu schneiden (cut_element_with_plane).
ec.solder_elements gibt eine LISTE zurueck, nicht eine ID: sid = sol[0] if isinstance(sol,(list,tuple)) else sol. Danach Attribute auf sid setzen. Bei Crash nach Solder: Ist-Stand scannen (Solder lief), nicht blind wiederholen.
IFC2x3-Typ setzen via cadwork.ifc_2x3_element_type(); Getter braucht TYP-OBJEKT nicht ID: Setzen: t=cadwork.ifc_2x3_element_type(); t.set_ifc_member(); bc.set_ifc2x3_element_type([eid],t). Lesen: bc.get_ifc2x3_element_type_display_string(bc.get_ifc2x3_element_type(eid)). Verfuegbare Setter: set_ifc_member/plate/covering/beam/column/wall/slab/footing/building_element_part/proxy u.a.
Katalog/JSON-eingebettete Code-Strings NUR per Skript schreiben, nie Edit-Tool: Code-Strings immer per Python-Skript schreiben (json.dump), nie mit dem Edit-Werkzeug. Nach dem Schreiben json.load-Validierung dass alle Details intakt sind. Vollstaendigen Funktions-Code INLINE einbetten (Server kann tools/ nicht importieren).
move_element bei Timeout oft trotzdem ausgefuehrt -> relativ nachschieben verdoppelt: Nach Timeout NIE relativ nachschieben. Ist-Position auslesen und ABSOLUT zielen: delta=ziel-aktuell; ec.move_element([id], point_3d(delta,0,0)). Marker im result zum Erkennen alter Antworten.
Katalog-Varianten NIE per Box-Kopie aus gedumpten w/h/l/p1 ableiten: Varianten aus dem KORRIGIERTEN Builder regenerieren, nie per Box-Kopie. Ausklinkung IMMER per Volumen (gc.get_volume bzw. offline _exp-Split-Volumen) pruefen, nie per Bounding-Box. Regressionstest: tools/_eck_12varianten_test.py (Eck2 volumen-vollstaendig korrekt 351/0).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ||
| description | No |