[Frage] Attribute an vorhandene Objekte anhängen

Schlagworte:
  • PythonParts
  • Interactor
  • Attribute
  • Allplan
  • 2022

Hallo zusammen.

Mein Ziel ist es mit einem PythonPart (PP) mehrere Attribute mit entsprechenden Attribut-Werten an bereits existierende Elemente (Stützen, Decken, Wände, 3D-Körper etc.) anzuhängen. Dafür benötigt man anscheinend einen Interactor. Einen solchen „TestInteractor“ habe ich aus dem PythonPart-Beispiel \LinesFromFileInteractor.py bzw. \...pyp abgeleitet. Die Allplan PythonParts Dokumentation verweist ebenfalls auf dieses Beispiel (die erste von zwei Methoden einen Interactor umzusetzen).

Zur Benutzung (siehe Bild 1 Anhang):
Mit Start des PP in Allplan soll zuerst der Attribut-Wert in ein Textfeld eingetragen werden (1 Expander). Anschließend kann das entsprechende Attribut ausgewählt werden (2 Expander). Beispielhaft habe ich das Attribut Langtext (Attribut- ID: 208) voreingestellt. Abschließend kann nach Auswahl eines Objektes/Elementes ein Button gedrückt werden der das Attribut + Attribut-Wert anhängt (3 Expander). Der Interactor startet mit dem PP und wird mit diesem beendet. Das PP soll so eine mehrmalige Ausführung ermöglichen, d.h. es sollen immer wieder Attribute an verschiedene Bauteile angehängt werden können.

Konkrete Problemstellung (siehe Bild 2 Anhang):
In meiner TestInteractor.py – Datei habe ich in der Klasse InteractorTest die Methoden (neben den notwendigen Standard-Methoden eines Interactors) „create_attibute_list“ welche das jeweilige Attribut einschließlich Wert (als Liste) zurückrück gibt und die Methode „on_control_event“ die bei der event-id des Buttons aktiv wird. Mein Ansatz ist mit der Attribut-Liste und eventuell mit der ElementUUID des Objektes die Attribute anzuhängen. Aber hier fehlen mir die notwendigen Befehle… bisher sind meine Versuche fehlgeschlagen.

Hat jemand ein ähnliches PythonPart schonmal erstellt und kann mir helfen oder auf ein Beispiel aus den PythonPartsExampleScripts verweisen welches ähnlich ist?

Das PP habe ich angehängt bzw. das .py-Skript im .txt-Format. Das PythonPart funktioniert aber nur in Allplan 2022. Mit dem Framework bzw. der API kenne ich mich nicht gut aus und Programmierer bin ich auch nicht also wäre ich über jede Hilfe und jeden Tipp sehr dankbar. Wenn mein Ansatz bzw. das gesamte Vorhaben zum scheitern verurteilt sind bitte auch kurz Bescheid geben.

Danke im Voraus.

Anhänge (3)

Typ: image/jpeg
106-mal heruntergeladen
Größe: 356,74 KiB
Typ: text/xml
719-mal heruntergeladen
Größe: 3,59 KiB
Typ: text/plain
731-mal heruntergeladen
Größe: 8,05 KiB

Hallo.

Schau mal nach dem ElementAttributeService.Da gibts eine Funtkion ChangeAttributes.

AllplanBaseElements.ElementsAttributeService.ChangeAttributes(self.dict_attributeTuples[name],ele_list)

Du brauchst lediglich eine Liste mit den Allplanelementen, die du attributieren willst, und eine Liste mit den Attributen (tuple mit Attributnummer und Attributwert.

Zitiert von: gHoepp
Hallo zusammen.

Mein Ziel ist es mit einem PythonPart (PP) mehrere Attribute mit entsprechenden Attribut-Werten an bereits existierende Elemente (Stützen, Decken, Wände, 3D-Körper etc.) anzuhängen. Dafür benötigt man anscheinend einen Interactor.
...

Wie der BimBimBoris bereits erwähnt hat, um die Attribute an bereits existierende Elemente anzuhängen, wird die Methode

AllplanBaseElements.ElementsAttributeService.ChangeAttributes(attributeDataList, elements)

verwendet. Und die benötigt zwei Argumente:

attributeDataList
Eine Liste von Tuples. Ein Tuple steht für ein Attribut und besteht aus Attributnummer und dessen Wert.
Beispiel:
(207, "Beispiel") -> so weist man den Text "Beispiel" dem Attribut Kurztext zu
Mit der Funktion ChangeAttributes kann man einem Objekt mehrere Attribute auf einmal zuweisen. Dafür baut man eine Liste von solchen Tuples zusammen. Es handelt sich hier um normale Listen und Tuples, die generell im Python vorhanden sind.

elements
Die im Model existierende Objekte, an die wir die o.g. Attribute anhängen wollen. Wir übergeben hier eine BaseElementAdapterList. Wie der Name schon sagt, handelt sich hier um eine Liste, in der mehrere Objekte vorhanden seien können. In dem Skript wird jedoch die Methode GetSelectedElement() verwendet, die nur EINEN selektierten Objekt (BaseElementAdapter) ergibt. Den müssen wir trotzdem an die Liste anhängen, weil die ChangeAttributes-Methode eben nur eine Liste akzeptiert.

Die Implementierung des o.g. könnte z.B. so aussehen:

...

def create_attribute_list(self):
        """
        Create an attribute list

        Returns:
            List containing tuples:
            (attribute_id as Int, attribute_value as Any)
        """
        attribute_list = []
        attribute_list.append((self.current_attribute_id, self.current_attribute_value))

        return  attribute_list


    def on_control_event(self, event_id):

        if event_id == 1000:

            #create a list of attributes that are supposed to be assigned to the model objects
            attribute_list = self.create_attribute_list()

            # create a list containing the object the user has selected in the model
            base_element_adapter_list = AllplanElementAdapter.BaseElementAdapterList()
            base_element_adapter_list.append(self.current_selected_element)

            #assign the attribute values to the selected objects
            AllplanBaseElements.ElementsAttributeService.ChangeAttributes(attribute_list, base_element_adapter_list)

            self.palette_service.update_palette(-1, False)

            return True

Im Anhang der komplette Skript für Euch zum Anschauen.

Anhänge (1)

Typ: application/zip
658-mal heruntergeladen
Größe: 2,72 KiB

Vielen Dank für die Antwort.
Den Post von BIMBIMBORIS hatte ich natürlich auch beachtet und die Methode ausprobiert.
Dies hat aber leider zu Fehlern geführt.
Ich werde bei Gelegenheit das Skript ausprobieren und alles nachzuvollziehen.