Hi Sebastian,
Du bist dabei, einen ScriptObject zu implementieren. Du solltest also von der BaseScriptObject vererben, nicht vom BaseInteractor (machst du ja auch in deinem beigefügten Script). Und wenn du dir die BaseScriptObject-Klasse anschaust - da gibt es keine on_preview_draw-Methode. In anderen worten: ALLPLAN erwartet von dir nicht, dass du diese methode implementierst und wird diese auch nicht aufrufen.
Wenn dein Workflow aber so ist, wie du es beschrieben hast, brauchst du eigentlich nur MultiElementSelectInteractor um die Elemente zu selektieren. Um den TextElement einfach in einem Punkt abzusetzen, brauchst du den PointInputInteractor nicht. Stattdessen, leere einfach das self.script_object_interactor nach der Selektion.
Warum? Schau mal auf diesen Flow diagramm. Wenn self.script_object_interactor leer ist, ruft ALLPLAN deine execute-Methode auf. Der Output dieser Methode ist eine instanz von CreateElementResult. Dieses Objekt beschreibt, was und wie erstellt werden soll. Wenn es so definiert is:
return CreateElementResult(model_ele_list, placement_point=insert_point_3d)
wo
model_ele_list nur dein TextElement im
lokalen Koordinatensystem (also Referenzpunkt 0,0,0) beinhaltet, kümmert sich ALLPLAN darum, diesen am Fadenkreuz zu hängen, Vorschau zu generieren, usw. Als ob du ein Standard-PythonPart erstellt hättest.
Also mach folgendes:
Das Ende der execute() Methode soll so aussehen:
text = AllplanBasisEle.TextElement(
self.common_props_standard,
text_prop_besch,
text_str,
AllplanGeo.Point2D(),
)
model_ele_list.append(text)
return CreateElementResult(model_ele_list)
Kein Absetzpunkt in CreateElementResult. model_ele_list hat nur TextElement und diese ist am 0,0,0 definiert.
Die start_next_input soll so aussehen:
def start_next_input(self):
"""Checks selected element and continues the interaction"""
print("Starte Next Input")
# Phase 1: Selektion abgeschlossen
self.text_list = []
for ele in self.interaction_result.sel_elements:
attr_dict = dict(ele.GetAttributes(BaseElements.eAttibuteReadState.ReadAll))
if 507 not in attr_dict:
continue
self.text_list.append(str(attr_dict[507]))
self.script_object_interactor = None
Diese wird nach der erfolgreichen selektion der Elemente aufgerufen. Also attribut 507 durchgehen und selektion beenden bzw. zu einem StandardPythonPart-modus wechseln indem self.script_object_interactor wieder auf None gesetzt wird.
Das wär's. Um Vorschau kümmert sich ALLPLAN.
Angepasstes Skript habe ich beigefügt. Dort erstelle ich aber einfach einen "Test"-Text. Bitte mit deiner Business-Logik ersetzen.
Grüße,
Bart