Das liegt daran, dass du deine Geometrie direkt im globalen Allplan-Koordinatensystem erzeugst. Dadurch haben die Punkte im PythonPart dieselben Koordinaten wie im Projekt. Sinnvoller ist es, konsequent mit einem lokalen Koordinatensystem zu arbeiten, um große Wertebereiche und Folgeprobleme zu vermeiden.
Vorgehen:
Jeder PythonPart besitzt eine Einfügematrix. Du kannst sie über get_insert_matrix aus dem BuildingElement auslesen.
Im Interactor passt du diese Matrix an, sobald der PythonPart per Mausklick platziert wird (matrix.SetTranslation).
Erzeugte Geometrien definierst du immer relativ zum lokalen Koordinatensystem des PythonParts.
Falls du globale Eingaben hast (z. B. Polylinie per Mausklick), wandelst du sie mit einer invertierten Kopie der Einfügematrix ins lokale System um (matrix.Reverse()).
Beim Erzeugen des PythonParts und beim Preview gibst du die Einfügematrix jeweils mit. Wenn du die Einfügematrix des BuildingElements nutzt, wird sie im PythonPart gespeichert und steht bei späteren Modifikationen wieder zur Verfügung.
Ich habe dir ein minimales Interactor-Beispiel mit deutschsprachigen Kommentaren zusammengestellt, damit die Abläufe klarer werden.
Wenn du dein Wissen zu PythonParts vertiefen möchtest, melde dich. Wir bieten dafür auch gezielte Schulungen an.
class Interactor(BaseInteractor):
"""Definition der Interactor Klasse."""
...
@property
def insert_matrix(self) -> AllplanGeo.Matrix3D:
"""Hier holst du dir die Einfügematrix.
Damit wandelst du lokale Koordinaten in globale um.
"""
return self.build_ele_list[0].get_insert_matrix()
@property
def local_matrix(self) -> AllplanGeo.Matrix3D:
"""Hier holst du dir die lokale Matrix des PythonParts.
Damit wandelst du globale Koordinaten in lokale um.
"""
local_matrix = AllplanGeo.Matrix3D(self.insert_matrix)
local_matrix.Reverse()
return local_matrix
def process_mouse_msg(self, mouse_msg: int, pnt: AllplanGeo.Point2D, msg_info: AllplanIFW.AddMsgInfo) -> bool:
"""Hier siehst du wie du die Einfügematrix bearbeitest und wie du globale koordinaten umrechnest."""
# Hier modifizieren wir die Einfügematrix des PythonParts
input_pnt = self.coord_input.GetInputPoint(mouse_msg, pnt, msg_info).GetPoint()
trans_vec = AllplanGeo.Vector3D(input_pnt)
self.insert_matrix.SetTranslation(trans_vec)
...
# Hier rechnen wir die globalen Koordinaten des Fadenkreuzes auf die lokalen Koordianten des PythonParts um
global_pnt = self.coord_input.GetInputPoint(mouse_msg, pnt, msg_info).GetPoint()
local_pnt = AllplanGeo.Transform(global_pnt, self.local_matrix)
def get_model_elements(self) -> list:
"""So erzeugst du den PythonPart."""
pyp_util = PythonPartUtil()
rectangle = AllplanGeo.Polygon2D.CreateRectangle(
AllplanGeo.Point2D(0.0, 0.0),
AllplanGeo.Point2D(1000.0, 1000.0),
)
rectangle_element = AllplanBasisElements.ModelElement2D(
AllplanBaseElements.CommonProperties(),
rectangle
)
pyp_util.add_pythonpart_view_2d(rectangle_element)
return pyp_util.create_pythonpart(
self.build_ele_list,
self.local_matrix,
self.insert_matrix
)
def create(self) -> None:
"""Platzhalter in dem gezeigt wird wie man Elemente erzeugt."""
model_elements = self.get_model_elements()
pyp_transaction = PythonPartTransaction(self.coord_input.GetInputViewDocument())
pyp_transaction.execute(
placement_matrix=self.insert_matrix, # <----- hier übergibst du die Einfügematrix
view_world_projection=self.coord_input.GetViewWorldProjection(),
model_ele_list=model_elements,
modification_ele_list=self.modify_uuid_list
)
def draw_preview(self) -> None:
"""Platzhalter in dem gezeigt wird wie man das Preview zeichnet."""
model_elements = self.get_model_elements()
AllplanBaseElements.DrawElementPreview(
self.coord_input.GetInputViewDocument(),
self.insert_matrix, # <----- hier übergibst du die Einfügematrix
model_elements,
True,
None
)