icon

[Вопрос] Bezugspunkt liegt am Nullpunkt und nicht am PythonPart

Теги:
  • Visual scripting

Hallo,
ich habe ein Script für ein PhytonPart erstellt mit dem Problem, dass der Bezugspunkt (roter Griff) immer am NUllpunkt ist und nicht wie bei 3D objekten direkt am Objekt dran.
Gibt es da eine Möglichkeit das noch zu scripten? Ich kann nichts finden.

Danke!

Вложения (1)

Type: image/png
Загружено 97 раз
Size: 2,73 KiB

Hallo,
gibt's dazu schon eine Lösung? lch habe gerade genau das gleiche Problem.

Antwort der KI :

Lösung:
Bezugspunkt im PythonPart-Script setzen

im PythonPart-Script den Bezugspunkt explizit festlegen, mit der Methode SetInsertionPoint . Das funktioniert so:
Im Konstruktor der Klasse (meist Element oder ähnlich) kannst du den Bezugspunkt setzen, z.B.:
self.insertion_point = AllplanGeo.Point3D(x, y, z)

Im Create()-Methode (oder wo du die Objekte erzeugst), kannst du dann:
pythonpart = PythonPart(
...,
insertion_point=self.insertion_point,
...
)

Alternativ:
Falls du direkt mit der PythonPart-Klasse arbeitest, kannst du die Methode SetInsertionPoint verwenden:
pythonpart.SetInsertionPoint(AllplanGeo.Point3D(x, y, z))

Best Practice:
Setze den Bezugspunkt möglichst an eine logische Stelle deines Objekts, z.B. an eine Ecke, den Mittelpunkt oder einen anderen charakteristischen Punkt.
Dokumentiere im Script, wo der Bezugspunkt liegt, damit andere Nutzer das PythonPart intuitiv verwenden können.

Beispiel:

import NemAll_Python_Geometry as AllplanGeo
import NemAll_Python_BaseElements as AllplanBaseElements

class MyPythonPart:
    def __init__(self):
        self.insertion_point = AllplanGeo.Point3D(1000, 0, 0)  # Beispielkoordinaten

    def Create(self, ...):
        # Erzeuge Geometrie
        ...
        # Setze Bezugspunkt
        pythonpart = AllplanBaseElements.PythonPart(
            ...,
            insertion_point=self.insertion_point,
            ...
        )
        return [pythonpart]

Hinweis:
Seit Allplan 2024 ist die explizite Angabe des Bezugspunkts im PythonPart-Objekt möglich und wird empfohlen.

Allplan Webentwicklung

Private messages must be private. No support request via Private message.

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
        )

https://www.soil-parts.at
https://www.soil-parts.at/kontakt/