
Jak widać wyżej, dobrnęliśmy do końca. Ale wszyscy wiedzą, że praca nie kończy się nigdy. Nawet gdy coś już stoi to zwykle wymaga poprawek czy ulepszeń. Nam projekt ratusza służył za pole testowe programu do projektowania powtarzalnych elementów w formacie svg i wycinania ich laserowo. Zapis elementów staraliśmy się czynić jak najbardziej w sposób parametryczny. Oznacza to, że tutaj prostokąt to nie figura 100×50 ale rectangle={width:100, height:50}. Ot, taki sobie przykład.
Na koniec zwróciliśmy się o pomoc do sztucznej inteligencji. Skrócony zapis dyskusji z SI jest naszym podarunkiem dla Wszystkich wytrwałych, czyli tych, którzy doszli do tego miejsca.
Rozmowa z Gemini
- Przyjmijmy wstępne ograniczenie, że moduł w pliku OpenSCAD składa się z bloku difference(), gdzie pierwszy element tego bloku stanowi kontur zewnętrzny a kolejne to kontury, które należy w pierwszej kolejności wyciąć. Każdy element ma postać poligonu z tabelą punktów [[x1,y1],…,[xn,yn]] lub jest w formacie parametru d ścieżki svg. Zadanie polega na stworzeniu kodu w języku Python pyside6, który przekonwertuje tekst modułu z pliku .scad do formatu „M…” ścieżki path svg.
- Gemini: Oczywiście, oto kod w języku Python z użyciem PySide6, który konwertuje moduł OpenSCAD do formatu ścieżki SVG:
- Doprecyzujmy: plik .scad obsługuje instrukcję „polygon()” ale według mnie, nie zna instrukcji „path()”. Proponuję zastąpić ją instrukcją svgShape() z biblioteki pathbuilder.scad (biblioteka promowana przez OpenSCAD).
- G: Oczywiście, masz rację. Moja poprzednia odpowiedź była błędna, ponieważ OpenSCAD natywnie nie obsługuje instrukcji path(). Instrukcja svgShape() z biblioteki pathbuilder.scad jest odpowiednim zamiennikiem dla ścieżek SVG.
Oto zaktualizowany kod, który uwzględnia instrukcję svgShape(): - Kontynuujmy naszą pracę: zrezygnujmy z instrukcji eval. Nie łącz poszczególnych ścieżek w jedną rozbudowaną ścieżkę ale zachowaj je w tablicy. Nie konwertuj tablicy punktów poligonu na instrukcje M i L ścieżki, ponieważ plik svg przyjmie je w postaci <polygon points=”” />. Zastosuj zmianę kolejności, ponieważ dla potrzeb cięcia, pierwszy element instrukcji difference() zawiera kontur zewnętrzny i wynikowo musi pojawić się jako ostatni. Wszystkie pozycje utworzonej tablicy przekonwertuj do dopuszczalnych form na wyjściu jako <polygon points=”” /> dla poligonów i <path d=”” /> dla svgShape.
- G: Oczywiście, oto zaktualizowany kod, który spełnia Twoje wymagania:
- Fragment re.search(r’difference\(\)\s*\{(..+?)\} zgłasza w PyCharm błąd „Redundant character escape '\}’ in RegExp”. Czy w tym miejscu nie powinien wystąpić podwójny backslash lub powinien on być całkowicie usunięty czy jest to tylko nadinterpretacja PyCharm?
- G: Masz rację, PyCharm zgłasza błąd „Redundant character escape ’}’ in RegExp”, ponieważ w wyrażeniu regularnym znak } nie wymaga ucieczki (ang. escaping) za pomocą backslasha \.
Rozwiązanie:
Możesz bezpiecznie usunąć backslash przed znakiem } w wyrażeniu regularnym: - Instrukcja svgShape() w pliku scad ma postać svgShape(„M … „) bez parametru d. Skoryguj RegExp dla przypadku elif contour_type == 'svgShape’ .
- G: Jasne, przepraszam za niedopatrzenie. Jeśli instrukcja svgShape() w pliku .scad ma postać svgShape(„M … „) bez parametru d, musimy dostosować wyrażenie regularne, aby wyodrębnić ścieżkę SVG bezpośrednio z ciągu znaków.
- Dla potrzeb testu przyjąłem treść pliku scad w postaci: scad_code = („module test() {\n\tdifference() {” „\n\t\tlinear_extrude(1) polygon=([[0,0], [100,0], [100,50], [0,50]]);” „\n\t\tlinear_extrude(1) svgShape(\”M10,10 H20 L10,10 Z \” );” „\n\t}\n}”) i w wyniku otrzymałem: Elementy SVG: <path d=”M10,10 H20 L10,10 Z ” /> . Dlaczego brakuje zamykającego transformację kodu poligonu?
- G: Oczywiście, masz całkowitą rację! Przeoczyłem fakt, że wyciągam tylko wewnętrzną zawartość polygon, a nie całą instrukcję. Problem polega na tym, że wyrażenie regularne w funkcji scad_to_svg_elements nie uwzględniało linear_extrude i samego słowa polygon.
Oto poprawiony kod, który powinien rozwiązać ten problem: - Poprawiasz się ale odczyt i konwersja poligonu jest błędna. W wyniku otrzymuję: <polygon points=”[0,0″ /> .
- G: Przepraszam za ten błąd. Masz całkowitą rację, kod niepoprawnie wyodrębniał punkty z poligonu. Wynikało to z niedokładnego wyrażenia regularnego, które nie uwzględniało wszystkich możliwych formatów punktów.
Oto poprawiony kod, który powinien rozwiązać ten problem: - Może i kod powinien być poprawny ale teraz wynik zmienił się na: <polygon points=”0,0″ />. Dlaczego znikają kolejne trzy punkty? Zmieńmy testowy string na: scad_code = („module test() {\n\tdifference() {” „\n\t\tlinear_extrude(1) polygon([[0,0], [100,0], [100,50], [0,50]]);” „\n\t\tlinear_extrude(1) svgShape(\”M10,10 H20 L10,10 Z \” );” „\n\t}\n}”) co zastosowałem wcześniej.
- G: Masz absolutną rację! Przepraszam za ciągłe błędy. Problem polega na tym, że moje wyrażenie regularne nie uwzględniało przypadku, gdy punkty w polygon są podawane bezpośrednio jako lista list, bez points=.
Oto poprawiony kod, który uwzględnia oba przypadki: - Spróbujmy ograniczyć RegExp dla poligonu tylko do przypadku bez wyrażenia „points=” oraz wprowadźmy rozdzielenie par koordynat pozyskanych punktów spacjami dla większej czytelności, chociaż stosowane dotąd przecinki nie eliminują rozwiązania.
- G: Oczywiście, oto zaktualizowany kod, który spełnia Twoje wymagania:
- Super. Zrobiliśmy duży krok do przodu chociaż do finału jeszcze daleko. Dziękuję.
- G: Cieszę się, że kod spełnia Twoje oczekiwania i że zrobiliśmy postęp. Oczywiście, zdaję sobie sprawę, że mamy jeszcze wiele do zrobienia, aby osiągnąć pełną funkcjonalność.
Jeśli masz jakiekolwiek dalsze pytania, sugestie lub potrzebujesz pomocy w kolejnych krokach, daj mi znać. Jestem tutaj, aby Ci pomóc.
No i co tam nasze wszelkie poprzednie dokonania. Dopiero teraz czujemy się w pełni dowartościowani. Dziękujemy za obecność i poświęconą nam uwagę.
Autor: Ian Bosweek
(to zbiorowy nick członków Gildii Python Designers grającej na świecie D)