[Frage] Programmabsturz bei nicht zulässigen Parametern verhindern [Gelöst]

Schlagworte:
  • Allplan
  • PythonAPI
  • PythonParts
  • Programmabsturz

Hallo.

Ich verwende in meinem Python Script die Boolsche Operation MakeSubtraction. Hier wird aus einem beliebigem Polygon ein Loch ausgeschnitten. Das funktioniert so weit so gut. Wenn jedoch die Geometrie des Lochs größer ist als das gesamte Polygon stürzt Allplan ab - was ja auch logisch ist denn die Funktion kann so nicht funktionieren. Nun wollte ich das "abfangen". Mein Ziel ist, dass selbst wenn der User eine ungültige Eingabe trifft, das Skript darauf reagiert und nicht einfach abstürzt. Das hab ich mit dem folgenden Skript probiert:
(head ist das Polygon und hole ist der Cylinder - beide Geometrien wurden als BreP3D definiert)

err, head = AllplanGeo.MakeSubtraction(head, hole)  
if  not err == AllplanGeo.eGeometryErrorCode.eOK:
   return

Jedoch stürzt Allplan immer noch ab wenn die Geometrie des Lochs zu groß gewählt wird. Was hab ich hier falsch gemacht? Bzw. was kann ich machen, um den Programmabsturz zu verhindern? In C# kann ich auf ungültige Ausgaben mit einem Try-Catch Konstrukt reagieren - wäre so etwas hier auch umsetzbar?
Ich bin über jede Hilfe dankbar!

Lösung anzeigen Lösung verbergen

Das Problem besteht darin, dass Allplanbeim Zeichnen des Previews nicht auf Gültigkeit des BReps prüft.
Denn genau hier passiert der Absturz. (s. pp_absturz.png)
Bei mir stürzt aber nur das PythonPart ab, und nicht das gesamte Allplan!
Ich habe aber als Beipiel (s. PlateWithHole.zip) scheinbar einen Interactor benutzt, und kein modifizierbares PythonPart.

@Allplan
Die fehlende Prüfung hat wahrscheinlich Performance-Gründe, sollte aber überdacht werden!

Wie kann man das verhindern?
Da der Absturz in einer anderen Python-Componente passiert, kann man die Exception im PythonPart-Code nicht fangen.
Dazu gibt es in Python try und except

@Allplan
try und except könnte man aber im Interactor BuilingElementInput.py an Zeile 438 und 882 einbauen!

Was kannst Du tun?
Da der ErrorCode nicht "meldet", dass das Ergebnis-Brep ungültig ist, sollte man noch eine zusätzliche Prüfung auf Validität einbauen:

        err,brepResult = AllplanGeo.MakeSubtraction(brepPlate,brepCylind)
        if  err == AllplanGeo.eGeometryErrorCode.eOK:
            if brepResult.IsValid():
                self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepResult))
            else:
                err,brepResult = AllplanGeo.MakeSubtraction(brepCylind,brepPlate)
                if  err == AllplanGeo.eGeometryErrorCode.eOK and brepResult.IsValid():
                    self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepResult))
                else:
                    self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepPlate))
                    self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepCylind))
        else:
            self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepPlate))
            self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepCylind))

...dann passiert nichts! Jedenfals nichts "Pöses"

Anhänge (2)

Typ: image/png
39-mal heruntergeladen
Größe: 127,55 KiB
Typ: application/zip
724-mal heruntergeladen
Größe: 2,07 KiB

Das Problem besteht darin, dass Allplanbeim Zeichnen des Previews nicht auf Gültigkeit des BReps prüft.
Denn genau hier passiert der Absturz. (s. pp_absturz.png)
Bei mir stürzt aber nur das PythonPart ab, und nicht das gesamte Allplan!
Ich habe aber als Beipiel (s. PlateWithHole.zip) scheinbar einen Interactor benutzt, und kein modifizierbares PythonPart.

@Allplan
Die fehlende Prüfung hat wahrscheinlich Performance-Gründe, sollte aber überdacht werden!

Wie kann man das verhindern?
Da der Absturz in einer anderen Python-Componente passiert, kann man die Exception im PythonPart-Code nicht fangen.
Dazu gibt es in Python try und except

@Allplan
try und except könnte man aber im Interactor BuilingElementInput.py an Zeile 438 und 882 einbauen!

Was kannst Du tun?
Da der ErrorCode nicht "meldet", dass das Ergebnis-Brep ungültig ist, sollte man noch eine zusätzliche Prüfung auf Validität einbauen:

        err,brepResult = AllplanGeo.MakeSubtraction(brepPlate,brepCylind)
        if  err == AllplanGeo.eGeometryErrorCode.eOK:
            if brepResult.IsValid():
                self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepResult))
            else:
                err,brepResult = AllplanGeo.MakeSubtraction(brepCylind,brepPlate)
                if  err == AllplanGeo.eGeometryErrorCode.eOK and brepResult.IsValid():
                    self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepResult))
                else:
                    self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepPlate))
                    self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepCylind))
        else:
            self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepPlate))
            self.model_ele_list.append(AllplanBasisElements.ModelElement3D(com_prop,3,3, brepCylind))

...dann passiert nichts! Jedenfals nichts "Pöses"

Anhänge (2)

Typ: image/png
39-mal heruntergeladen
Größe: 127,55 KiB
Typ: application/zip
724-mal heruntergeladen
Größe: 2,07 KiB

Danke für die schnelle Antwort!
Schade, dass es hier keinen effektiveren/besseren Weg gibt...

Hier noch das Ganze als modifizierbares PythonPart.
Der Absturz passiert immer noch an derselben Stelle, beim Preview!

Anhänge (1)

Typ: application/zip
686-mal heruntergeladen
Größe: 4,72 KiB