CAD W RUCHU

FreeCAD bez okna: zespół STEP na osobne bryły w trzynastu linijkach

Skrypt w FreeCAD 1.1.3 rozbija STEP ze 169 bryłami na 169 plików OBJ z zachowanym położeniem. Odczyt 1,1 s, bez klikania, z jedną pułapką w trybie konsoli.

FreeCAD 1.1.3 potrafi rozbić zespół STEP na osobne bryły bez otwierania okna. Skrypt ma trzynaście linijek: czyta plik, przechodzi po bryłach, każdą siatkuje i zapisuje jako OBJ, a gabaryty i objętości odkłada do jednego pliku JSON. Przekładnia ze 169 bryłami: odczyt 1,1 s, potem siatkowanie i zapis.

import FreeCAD, Part, Mesh, MeshPart, os, sys, json
f = sys.argv[-1]; out = os.path.join(os.path.dirname(f), "mesh"); os.makedirs(out, exist_ok=True)
shape = Part.Shape(); shape.read(f)
info = {}
for i, s in enumerate(shape.Solids):
    b = s.BoundBox; vol = s.Volume
    m = MeshPart.meshFromShape(Shape=s, LinearDeflection=0.05, AngularDeflection=0.2, Relative=False)
    name = "p%02d" % i
    m.write(os.path.join(out, name + ".obj"))
    info[name] = {"vol": vol, "faces": m.CountFacets, "bbox": [b.XMin, b.YMin, b.ZMin, b.XMax, b.YMax, b.ZMax]}
json.dump(info, open(os.path.join(out, "parts.json"), "w"), indent=1)
print("solids", len(shape.Solids))

Położenie każdej bryły zostaje takie, jak w zespole, bo shape.Solids oddaje bryły w globalnym układzie pliku. To jest cała różnica między tym skryptem a eksportem „zapisz jako OBJ” z okna: tam wychodzi jedna siatka, tu 169 osobnych obiektów, które da się ruszać niezależnie.

Dwa parametry, które decydują o wadze

LinearDeflection=0.05 to maksymalne odchylenie siatki od powierzchni w milimetrach, AngularDeflection=0.2 to kąt między sąsiednimi ściankami w radianach. Przy tych wartościach przekładnia dała 452 tysiące ścianek, chwytak milion. Do filmu i do modelu na stronę wystarcza; do druku 3D wziąłbym gęściej, ale to inna droga.

parts.json przydaje się później: objętość mówi, która bryła jest rolką (małe), a która obudową (duże), i po tym skrypt Blendera przypisuje stal albo korpus bez oglądania każdej części.

Pułapka trybu bez okna

FreeCAD -c skrypt.py uruchamia skrypt, a potem zostaje w konsoli Pythona i czeka na wejście. Odpalony z automatu bez terminala wisi w nieskończoność; u mnie pierwsza próba wisiała ponad 6 minut, zanim to zrozumiałem. Rozwiązanie: podać puste wejście i zakończyć proces jawnie na końcu skryptu. Komunikat o brakującej bibliotece 3Dconnexion w logu jest nieszkodliwy, to sterownik myszy 3D, której nie mam.

Na Macu w pakiecie FreeCAD.app nie ma osobnego programu konsolowego, jest tylko jeden plik wykonywalny z przełącznikiem -c. Wersję sprawdzam w pliku Info.plist pakietu, bo --version w tej wersji nic nie wypisuje.

Ten skrypt to pierwszy krok każdego zlecenia: plik STEP od klienta, 169 albo 157 OBJ, i dopiero potem scenariusz ujęć. Bez okna, bez klikania, w minutę razem z siatkowaniem.