Makro Bounding-Box für STL importierte Teile und für Punktewolken

In diesem Forum Fragen und Diskussionen in Deutsch
Forum rules
Foren-Regeln und hilfreiche Informationen

WICHTIG: Bitte zuerst lesen, bevor Sie posten
freecad-heini-1
Posts: 7353
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby freecad-heini-1 » Mon May 08, 2017 3:24 pm

Ich arbeite noch immer an den gescannten Daten die ich heute bekam. Leider liegt das Koordinatensystem total verdreht im Raum.
Da dachte ich mir ich nutze Mario's Skript Bounding-Box. Für selbst konstruierte schiefe Dinger funktioniert das Skript erstklassig, nicht für importierte Stl-Daten oder Punktewolken.
https://www.freecadweb.org/wiki/Macro_B ... ox_Tracing

@Mario52, falls Du das liest, gibt es eine Möglichkeit das Skript auch für Mesh oder Punktewolken abzuändern?
Das wäre spitze.

Ich erhalte Folgende Meldung:

Code: Select all

Traceback (most recent call last):
  File "/home/userxyz/.FreeCAD/Macro/bounding-box.py", line 34, in <module>
    s = objs[0].Shape
Last edited by freecad-heini-1 on Mon May 08, 2017 5:48 pm, edited 1 time in total.
wmayer
Site Admin
Posts: 16633
Joined: Thu Feb 19, 2009 10:32 am

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby wmayer » Mon May 08, 2017 4:57 pm

Code: Select all

if len(objs) >= 1:
    if hasattr(objs[0], "Shape"):
        s = objs[0].Shape
    elif hasattr(objs[0], "Mesh"):
        s = objs[0].Mesh
    elif hasattr(objs[0], "Points"):
        s = objs[0].Points
freecad-heini-1
Posts: 7353
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby freecad-heini-1 » Mon May 08, 2017 5:46 pm

Vielen Dank Werner.
Ich nahm die stl die wir aktuell von einem fragwürdigen Filehoster herunter geladen hatten.
Egal ob stl oder Punktewolke, es wird leider keine Boundingbox mit Deinem Skript erzeugt.

Hier der Faden mit der stl:
https://forum.freecadweb.org/viewtopic. ... 47#p172547

Im Ausgabefenster steht:

Code: Select all

Traceback (most recent call last):
  File "/home/userxyzl/.FreeCAD/Macro/bounding-box.py", line 1, in <module>
    if len(objs) >= 1:
<type 'exceptions.NameError'>: name 'objs' is not defined
Ich hatte mich oben verschrieben, Step statt STL.
STL war aber gemeint, deswegen auch Mesh.
wmayer
Site Admin
Posts: 16633
Joined: Thu Feb 19, 2009 10:32 am

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby wmayer » Mon May 08, 2017 6:49 pm

Das komplette Skript sieht so aus:

Code: Select all

import FreeCAD, FreeCADGui, Draft, Part
App = FreeCAD

createVol = 1            # give 1 for create Volume # mettre a 1 pour creer un volume

selEx = FreeCADGui.Selection.getSelectionEx()
objs = [selobj.Object for selobj in selEx]
if len(objs) >= 1:
    if hasattr(objs[0], "Shape"):
        s = objs[0].Shape
    elif hasattr(objs[0], "Mesh"):
        s = objs[0].Mesh
    elif hasattr(objs[0], "Points"):
        s = objs[0].Points

    # LineColor
    red   = 1.0  # 1 = 255
    green = 0.0  #
    blue  = 0.0  #

    # boundBox
    boundBox_ = s.BoundBox
    boundBoxLX = boundBox_.XLength
    boundBoxLY = boundBox_.YLength
    boundBoxLZ = boundBox_.ZLength

    a = str(boundBox_)
    a,b = a.split('(')
    c = b.split(',')
    oripl_X = float(c[0])
    oripl_Y = float(c[1])
    oripl_Z = float(c[2])

    App.Console.PrintMessage(str(boundBox_)+"\r\n")
    App.Console.PrintMessage("Rectangle      : "+str(boundBox_.XLength)+" x "+str(boundBox_.YLength)+" x "+str(boundBox_.ZLength)+"\r\n")

    if (createVol == 1) and (boundBoxLX > 0) and (boundBoxLY > 0) and (boundBoxLZ > 0):  # Create Volume
        BDvol = App.ActiveDocument.addObject("Part::Box","BoundBoxVolume")
        #BDvol.Label = "BoundBoxVolume"
        BDvol.Length.Value = boundBoxLX
        BDvol.Width.Value  = boundBoxLY
        BDvol.Height.Value = boundBoxLZ
        BDvol.Placement=App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(App.Vector(0,0,1),0), App.Vector(0,0,0))
        FreeCADGui.ActiveDocument.getObject(BDvol.Name).LineColor  = (red, green, blue)
        FreeCADGui.ActiveDocument.getObject(BDvol.Name).PointColor = (red, green, blue)
        FreeCADGui.ActiveDocument.getObject(BDvol.Name).ShapeColor = (red, green, blue)
        FreeCADGui.ActiveDocument.getObject(BDvol.Name).Transparency = 80
        App.Console.PrintMessage("BoundBoxVolume : " + str(BDvol.Shape.Volume)+"\r\n")
    else:
        App.Console.PrintMessage("Not BoundBox possible"+"\r\n")
    App.Console.PrintMessage("_____________________"+"\r\n")

    ##### 
    try:
        if (boundBox_.XLength and boundBox_.YLength) > 0.0:
            pl_0 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,0.0))
            double = Draft.makeRectangle(length=boundBox_.XLength,height=boundBox_.YLength,placement=pl_0,face=False,support=None) #OK
            double.Label = "BoundBoxRectangle_Bo"
            FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
#        else:
#            App.Console.PrintError("not value 0"+"\n")
    except:
        App.Console.PrintError("not done 0"+"\n")
    try:
        if (boundBox_.XLength and boundBox_.YLength) > 0.0:
            pl_1 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z+boundBoxLZ), App.Rotation(0.0,0.0,0.0))
            double = Draft.makeRectangle(length=boundBox_.XLength,height=boundBox_.YLength,placement=pl_1,face=False,support=None) #Ok
            double.Label = "BoundBoxRectangle_To"
            FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
#        else:
#            App.Console.PrintError("not value 1"+"\n")
    except:
        App.Console.PrintError("not done 1"+"\n")
    try:
        if (boundBox_.XLength and boundBox_.ZLength) > 0.0:
            pl_2 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(0.0,0.0,90))
            double = Draft.makeRectangle(length=boundBox_.XLength,height=boundBox_.ZLength,placement=pl_2,face=False,support=None) #Ok
            double.Label = "BoundBoxRectangle_Fr"
            FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
#        else:
#            App.Console.PrintError("not value 2"+"\n")
    except:
        App.Console.PrintError("not done 2"+"\n")
    try:
        if (boundBox_.XLength and boundBox_.ZLength) > 0.0:
            pl_3 = App.Placement(App.Vector(oripl_X,oripl_Y+boundBoxLY,oripl_Z), App.Rotation(0.0,0.0,90))
            double = Draft.makeRectangle(length=boundBox_.XLength,height=boundBox_.ZLength,placement=pl_3,face=False,support=None) #Ok
            double.Label = "BoundBoxRectangle_Re"
            FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
#        else:
#            App.Console.PrintError("not value 3"+"\n")
    except:
        App.Console.PrintError("not done 3"+"\n")
    try:
        if (boundBoxLY and boundBox_.ZLength) > 0.0:
            pl_4 = App.Placement(App.Vector(oripl_X,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
            double = Draft.makeRectangle(length=boundBoxLY,height=boundBox_.ZLength,placement=pl_4,face=False,support=None) #Ok
            double.Label = "BoundBoxRectangle_Le"
            FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
#        else:
#            App.Console.PrintError("not value 4"+"\n")
    except:
        App.Console.PrintError("not done 4"+"\n")
    try:
        if (boundBoxLY and boundBoxLZ) > 0.0:
            pl_5 = App.Placement(App.Vector(oripl_X+boundBoxLX,oripl_Y,oripl_Z), App.Rotation(90,0.0,90))
            double = Draft.makeRectangle(length=boundBoxLY,height=boundBoxLZ,placement=pl_5,face=False,support=None) #Ok
            double.Label = "BoundBoxRectangle_Ri"
            FreeCADGui.activeDocument().activeObject().LineColor = (red, green, blue)
#        else:
#            App.Console.PrintError("not value 5"+"\n")
    except:
        App.Console.PrintError("not done 5"+"\n")
    #####
    App.ActiveDocument.recompute()
else:
    App.Console.PrintMessage("Select an object !"+"\n")
Funktioniert bei mir tadellos, wenn ein Part-, Mesh- oder Points-Objekt selektiert ist.
mario52
Posts: 3217
Joined: Wed May 16, 2012 2:13 pm

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby mario52 » Mon May 08, 2017 7:31 pm

hi wmayer freecad-heini-1

many thanks i upgrade the macro with your addition
ps: this macro is include in the WorkFeatures macro i contact rentlau_64 for upgrade

thanks
mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting, Dialog creation. My macros on Gist.github.
freecad-heini-1
Posts: 7353
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby freecad-heini-1 » Mon May 08, 2017 8:20 pm

Tausend Dank Werner. Ich bin der Meinung das ist Spitze - und hoch hüpf, wie einst Hans Rosenthal. 8-)
Danke auch an Mario - ihr seid ein Spitzenteam.
punktewolke-bounding-box.gif
punktewolke-bounding-box.gif (751.57 KiB) Viewed 714 times
Viele Grüße
Wilfried
freecad-heini-1
Posts: 7353
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby freecad-heini-1 » Mon May 08, 2017 8:48 pm

Da habe ich mich leider zu früh gefreut. Die Box nimmt Bezug zum falsch in Raum liegenden Koordinatensystem, siehe:
punktewolke-bounding-box1.gif
punktewolke-bounding-box1.gif (895.53 KiB) Viewed 711 times
Was ich wollte ist, dass die Kanten erkannt werden und die Box so generiert wird, dass alles was nahezu eben ist von der Box eingeschlossen wird. Ich hätte mir dann Bezugspunkte exakt in die Mitte gelegt, dann Ebenen durch und auf diese Weise das Teil richtig zum Koordinatensystem gedreht und verschoben.
User avatar
microelly2
Posts: 4690
Joined: Tue Nov 12, 2013 4:06 pm
Contact:

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby microelly2 » Mon May 08, 2017 8:58 pm

Willst du die "optimale bounding box"?
Ich habe da mal vor etwa einem Jahr eine Simulation laufen lassen, welche berechnet, wo die BB klein wird.
https://youtu.be/cIjbNz20LZU
wmayer
Site Admin
Posts: 16633
Joined: Thu Feb 19, 2009 10:32 am

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby wmayer » Mon May 08, 2017 9:44 pm

Die normale BB ist natürlich parallel zu den Achsen des Weltkoordinatensystems.

Wenn man die "optimale" BB haben will, gibt es zwei Möglichkeiten:
  1. minimales Volumen: der dafür schnellste Algorithmus hat eine Laufzeit von O(n^3), ist also sehr, sehr langsam
  2. minimale Ausdehnung in eine Richtung: i.d.R. entspricht diese Lösung annähernd der obigen und die Laufzeit ist O(n), also linear
Die Lösung in der 2. Möglichkeit entspricht den Eigenvektoren der sog. Kovarianzmatrix. Da die Kovarianzmatrix symmetrisch ist, stehen die Eigenvektoren jeweils senkrecht zueinander und eignen sich daher als lokales Koordinatensystem.
freecad-heini-1
Posts: 7353
Joined: Tue Jan 07, 2014 11:10 am
Contact:

Re: Makro Bounding-Box für STL importierte Teile und für Punktewolken

Postby freecad-heini-1 » Tue May 09, 2017 6:17 am

Hab gestern Nachmittag noch den Dienstleister kontaktiert, ob deren Software mir die Mitten bestimmen kann. Antwort heute morgen, erst mal Handbücher lesen, diese Anforderung war bisher noch nie erforderlich.

Ich muss die Fläche später auf einen Solid kopieren, dabei müssen die Achsen aufeinander stimmen.
Gemessen wird im 2µm Bereich, da muss alles stimmen.

Optimale Bounding-Box nennt man das was ich benötige, wieder was gelernt.
Ich warte den Tag ab, ob der Dienstleister das mit den Achsen geregelt bekommt.