Support Forum

[Frage] Arbeit mit Bewehrungseisen - Positionsnummern und Geometrie [Gelöst]

Schlagworte:
  • Python
  • ElementAdapter

Hallo zusammen,

ich arbeite gerade daran, aus eine verlegten Bewehrung verschiede Informationen rauszuziehen.
Ich nutze die Version 25 und selektiere über die MultiElementSelectInteractor mehrere Eisen.

Das funktioniert auch soweit, nun möchte ich verschiede Funktionen mit meinem selektierten Eisen in einer Schleife machen.

1. Ich möchte die Funktion GetPosition nutzen.
Hier scheitere ich allerdings daran, das Element als richtigen ElementAdapter einzugeben.

Ich habe erst naiv versucht das Element mit AllplanRebar.BarPositionData.GetPosition(ele) auszuwerten, was aber eben eine Fehlermeldung ausgibt. Daher habe ich nach dem passendem ElementAdapter gesucht und auch den Elementadapter BarsRepresentation_TypeUUID und BarsDefinition_TypeUUID genutzt. Daher meine Frage, wie arbeite ich mit der Bewehrung weiter, um daraus die Positionsnummer ziehen zu können.

2. Nun möchte ich eine MinMaxBox um das selektierte Eisen setzten um dann wiederum ein Polygon um das Eisen zu setzten.
Auch hier bekomme ich leider ein ElementAdapter Fehler.

Ich hoffe ich konnte mein Problem verständlich erklären, und würde mich über Hilfe freuen. Im Anhang ist die .py File.

Die Grundlage des Scripts ist von Bart basierend auf diesem Post von mir

Gruss Sebastian

Anhänge (1)

Typ: application/zip
225-mal heruntergeladen
Größe: 1,83 KiB

Lösung anzeigen Lösung verbergen

Hi Sebastian.

Ich habe dein Skript analysiert. Du hast fast alles richtig gemacht:

  • in start_input() startest du die selektion
  • in start_next_input() addierst du alle nicht beschriftete Eisen zu deinem MinMaxBox
  • in execute() erzeugst du eine Polylinie, um diese Eisen hervorzuehben

der MinMax box wurde in deinem Skript richtig erzeugt, nur die Polylinie nicht und zwar deshalb, weil die execute() Methode vom Framework nie aufgerufen wird. Und sie wurde nie aufgerufen, weil du die Selektion immer wieder neu startest (bzw. sie nie beendest).

Um es klarzusetellen: die execute() methode wird nur dann ausgeführt, wenn kein input läuft. D.h. wenn das property self.script_object_interactor = None. In deinem Skript wird diese property in start_input() belegt (das ist i.O.) aber nach erfolgreichem selektieren, in start_next_input() nicht geleert (nicht i.O.). Welche methoden (start_input, start_next_input, execute) in welcher Reihenfolge ausgeführt werden, ist auf diesem Flow-Diagramm dargestellt.

Um ScriptObject architektur zu verwenden ist es wichtig zu verstehen, welche Methode deines ScriptObject-Klasse in welcher Reihenfolge und unter welchen voraussetzungen ausgeführt wird. Der Flow-Diagramm stellt das visuell dar also immer drauf schauen.

Ich füge das korrigierte Skript bei, nur als txt.

Ich hoffe, das hilft dir weiter.
Grüße,
Bart

Anhänge (1)

Typ: text/plain
44-mal heruntergeladen
Größe: 7,47 KiB

Hallo Sebastian,

ich würde an deiner Stelle beim MultiSelectInteractor den Filter setzen, dass nur BarsRepresentationLine_TypeUUID selektiert wird. Diese dann im Nachhinein inspizieren, indem du rekursiv die Parent-Elemente holst, bis du den BarsDefinition_TypeUUID erreichst. Diesen dann in eine separate BaseElementAdapterList packen - das ist die Liste aller von dir markierten Bewehrungspositionen. Dann kannst du die Positionsnummer, Anzahl, usw. mit BarPositionData auslesen.

Zu der anderen Frage: Ein Adapter des Typs BarsRepresentationLine_TypeUUID hat immer eine Geometrie von Polyline2D. Du kannst also von jedem Adapter die Polylinie holen, deren Punkte du in deine MinMax-Box addierst. Am Ende kannst du das Polygon aus der MinMax-Box holen, worum es dir vermutlich geht.

Im Anhang findest du ein Beispiel. Markiere ein paar Eisen im Grundriss oder in einem Schnitt. In Trace werden die Positionen ausgegeben und im Viewport wird ein Rechteck um sie gezeichnet.

Viele Grüße, Bart

Anhänge (1)

Typ: application/zip
205-mal heruntergeladen
Größe: 1,78 KiB

Zitiert von: bmarciniec
Hallo Sebastian,
ich würde an deiner Stelle beim MultiSelectInteractor den Filter setzen, dass nur BarsRepresentationLine_TypeUUID selektiert wird. Diese dann im Nachhinein inspizieren, indem du rekursiv die Parent-Elemente holst, bis du den BarsDefinition_TypeUUID erreichst. Diesen dann in eine separate BaseElementAdapterList packen - das ist die Liste aller von dir markierten Bewehrungspositionen. Dann kannst du die Positionsnummer, Anzahl, usw. mit BarPositionData auslesen.
Zu der anderen Frage: Ein Adapter des Typs BarsRepresentationLine_TypeUUID hat immer eine Geometrie von Polyline2D. Du kannst also von jedem Adapter die Polylinie holen, deren Punkte du in deine MinMax-Box addierst. Am Ende kannst du das Polygon aus der MinMax-Box holen, worum es dir vermutlich geht.
Im Anhang findest du ein Beispiel. Markiere ein paar Eisen im Grundriss oder in einem Schnitt. In Trace werden die Positionen ausgegeben und im Viewport wird ein Rechteck um sie gezeichnet.
Viele Grüße, Bart

Hallo Bart,

ich habe mich mal dran gesetzt und es will leider nicht wirklich funktinieren, zumindest, mit der MinMax Box. Ich habe sehr viel aus deinem Code übernommen, leider wird bei mir keine Box erzeugt. Zudem bekomme ich keine Fehlermeldung. Also vermute ich, dass er versucht einen Polygon aus einer leeren Polygonliste zu erstellen.

Ich habe mal im Anhang meine .py file angehängt und hoffe, du kannst mir sagen, warum keine MinMax Box kreiert wird. Ich bekomme es leider nicht raus.

Gruss Sebastian

Anhänge (1)

Typ: application/zip
91-mal heruntergeladen
Größe: 2,42 KiB

Hi Sebastian.

Ich habe dein Skript analysiert. Du hast fast alles richtig gemacht:

  • in start_input() startest du die selektion
  • in start_next_input() addierst du alle nicht beschriftete Eisen zu deinem MinMaxBox
  • in execute() erzeugst du eine Polylinie, um diese Eisen hervorzuehben

der MinMax box wurde in deinem Skript richtig erzeugt, nur die Polylinie nicht und zwar deshalb, weil die execute() Methode vom Framework nie aufgerufen wird. Und sie wurde nie aufgerufen, weil du die Selektion immer wieder neu startest (bzw. sie nie beendest).

Um es klarzusetellen: die execute() methode wird nur dann ausgeführt, wenn kein input läuft. D.h. wenn das property self.script_object_interactor = None. In deinem Skript wird diese property in start_input() belegt (das ist i.O.) aber nach erfolgreichem selektieren, in start_next_input() nicht geleert (nicht i.O.). Welche methoden (start_input, start_next_input, execute) in welcher Reihenfolge ausgeführt werden, ist auf diesem Flow-Diagramm dargestellt.

Um ScriptObject architektur zu verwenden ist es wichtig zu verstehen, welche Methode deines ScriptObject-Klasse in welcher Reihenfolge und unter welchen voraussetzungen ausgeführt wird. Der Flow-Diagramm stellt das visuell dar also immer drauf schauen.

Ich füge das korrigierte Skript bei, nur als txt.

Ich hoffe, das hilft dir weiter.
Grüße,
Bart

Anhänge (1)

Typ: text/plain
44-mal heruntergeladen
Größe: 7,47 KiB

Hallo Bart,

danke für die Hilfe. Das der Interactor leer sein muss, macht absolut Sinn, habe ich aber so auch nicht gewusst und an die Flow Chart habe ich auch nicht gedacht. Werde diese jetzt bei ScriptObjects immer mit im Hinterkopf haben.

Zitiert von: bmarciniec
Hi Sebastian.
Ich habe dein Skript analysiert. Du hast fast alles richtig gemacht:
in start_input() startest du die selektion
in start_next_input() addierst du alle nicht beschriftete Eisen zu deinem MinMaxBox
in execute() erzeugst du eine Polylinie, um diese Eisen hervorzuehben
der MinMax box wurde in deinem Skript richtig erzeugt, nur die Polylinie nicht und zwar deshalb, weil die execute() Methode vom Framework nie aufgerufen wird. Und sie wurde nie aufgerufen, weil du die Selektion immer wieder neu startest (bzw. sie nie beendest).
Um es klarzusetellen: die execute() methode wird nur dann ausgeführt, wenn kein input läuft. D.h. wenn das property self.script_object_interactor = None. In deinem Skript wird diese property in start_input() belegt (das ist i.O.) aber nach erfolgreichem selektieren, in start_next_input() nicht geleert (nicht i.O.). Welche methoden (start_input, start_next_input, execute) in welcher Reihenfolge ausgeführt werden, ist auf diesem Flow-Diagramm dargestellt.
Um ScriptObject architektur zu verwenden ist es wichtig zu verstehen, welche Methode deines ScriptObject-Klasse in welcher Reihenfolge und unter welchen voraussetzungen ausgeführt wird. Der Flow-Diagramm stellt das visuell dar also immer drauf schauen.
Ich füge das korrigierte Skript bei, nur als txt.
Ich hoffe, das hilft dir weiter.

Grüße,

Bart

Hallo Bart,

mir ist aufgefallen, dass ich, wenn ich die Selektion beende, die Execution Funktion wie zwei mal ausgeführt wird. Ich habe zum Test einige Printbefehle reingesetzt und alle Prints der Execution werden doppelt ausgegeben. Kannst du mir sagen, warum das passiert?

Gruss Sebastian

Zitiert von: TheSocialPotwal
Hallo Bart,
mir ist aufgefallen, dass ich, wenn ich die Selektion beende, die Execution Funktion wie zwei mal ausgeführt wird. Ich habe zum Test einige Printbefehle reingesetzt und alle Prints der Execution werden doppelt ausgegeben. Kannst du mir sagen, warum das passiert?
Gruss Sebastian

ScriptObject funktioniert einfach so. Laut diesem diagramm wird die execute() funktion immer wieder aufgerufen, bis ESC gedrückt wird. Die Aktionen, die du hier implementierst sollten dafür ausgelegt sein. Willst du eine Aktion einmal durchführen, implementiere es woanders. Z.B. beim Button-click -> im on_control_event. Nach der Eingabe (z.B. Selektion) -> in start_next_input. Vor der ersten eingabe -> start_input, usw...

Grüße,
Bart