To run menu :
- download script (file with .py)
- open blender
- go to scripting workspace (top right)
- open script by pressing "Open" (file with .py)
- click run or ALT+P
- done, now you can close scripting workspace
Custom menu with BPY for basic operations such as:
- Add basic shapes
- select/unselect all objects
- delete selected obejct/s
- Move object
- Reset object postition
- Resize object
- Reset object size
- Enlarge or reduce the object by 2 times
- Rotate object
- Reset rotation of object
Author Daniel Charlak CS student
Menu made with official documentation :https://docs.blender.org/api/current/index.html#blender-3-2-python-api-documentation
Blender posiada wbudowany interpreter Pythona, który jest ładowany po jego uruchomieniu i pozostaje aktywny podczas jego pracy. Blender udostępnia swoje moduły Pythona, takie jak bpy i mathutils, wbudowanemu interpreterowi, dzięki temu możemy zaimportować je do skryptu i uzyskać dostęp do danych, klas i funkcji Blendera. Zapewnia on środowisko w którym możemy pisać i uruchamiać skrypty. W celu otworzenia menu skryptowego należy wybrać zakładkę "Scripting" z górnego menu Blendera. Będzie to miejsce w którym zostanie wykonana cała praca.
Bardzo ważną funkcją w tym wypadku jest execute(self,context), jest to funkcja w której określamy co robi nasz operator. Funkcja ta musi zwracać określny typ, ja będę używał głównie tych trzech : • CANCELLED - operator zakończył akcję ale nic się nie stało • FINISHED – operator pomyślnie zakończył akcję • PASS_THROUGH – zakończenie akcji bez żadnej akcji, może być użyte do sprawdzenia warunku np. czy obiekt istnieje Typ zwracany musi zostać umieszczony w {} i w apostrofach. Podobnie jak klasa Panel, klasa Operator musi zostać zarejestrowana przed użyciem. Dodatkowo potrzebujemy zdefiniować zmienne, które będą przekazywane do funkcji execute() za pośrednictwem referencji self. W Blenderze zamiast użycia tradycyjnych wartości float i int będziemy używać properties z klasy by.props. Pozwalają one na wstawienie elementów graficznych np. sliederów przez klasę bpy.props.FloatProperty(), czy checkboxa przez klasę bpy.props.BoolProperty(). Dodatkowo możemy nadać tym wartościom nazwę i opis. Pozwoli nam to w dalszym dodaniu operatora do naszego menu. Po manualnym teście okazuje się, że gdy obiekt jest skalowany w danej osi zostaje wywołany operator bpy.context.object.scale[0] = wartość. Podanie 0 jako argumentu zmienia wielkość w płaszczyźnie X, 1- Y i 2 – Z. Kiedy nasz operator jeszcze nie został dodany do menu możemy wywołać go tylko przez konsolę. Stworzenie klasy zaczyna się od nadania nazwy operatora. Ponieważ każdy operator musi posiadać kropkę w przedrostku dodałem "object" ponieważ odnosi się on do obiektów. Przedrostek może być dowolny. Cały operator został nazwany object.resize_selected więc przez konsolę mamy do niego dostęp używając by.ops.object.resize_selected(). W klasie zostały zadeklarowane 3 wartości bpy.props.FloatProperty(), które odpowiadają graficznemu stworzeniu slidera z liczbami zmiennoprzecinkowymi. W funkcji wykonującej pobierane są wartości ze slidera i wstawiane bezpośrednio do funkcji skalującej w danej osi. Wywołując operator jako argumenty musimy podać 3 wartości : size_x, size_y i size_z. Po wykonaniu powyższych kroków i zarejestrowaniu operatora został on dodany do Blendera. Stał się on pełnoprawną funkcją do wykonania i po zaznaczeniu opcji "developer extras" (Preferences -> Interface) jest on dostępny do wyszukania pod klawiszem F3 i także w konsoli. Testowe wywołanie nowego operatora na kuli Możemy zauważyć, że każda zmiana na sliderze wywołuje naszą funkcję z odpowiednimi parametrami. Gdy operator już działa możemy go dodać do naszego menu przez wywołanie .operator(nazwa operatora) na naszym elemencie do którego dodajemy przyciski. Tak samo jak w przypadku predefiniowanych operatorów.
Po kilku próbach testowych okazało się, że nowy operator nie działa zgodnie z oczekiwaniami. Zaznaczając kolejny obiekt nasz operator był wywoływany bez parametrów, a wartościom sliderów przypisywane było 0. Dodatkowo gdy zmieniliśmy wielkość jednego obiektu i uruchomiliśmy operator na drugim obiekcie przypisywane zostawały mu poprzednie wartości sliderów .Do rozwiązania tego problemu zastosowałem funkcję invoke. Funkcja operator.invoke służy do inicjalizacji operatora z kontekstu w momencie jego wywołania. invoke() jest zwykle używana do przypisywania właściwości, które są następnie wykorzystywane przez execute(). Definiuje się ją podobnie jak funkcję execute tylko z dodatkowym parametrem event : def invoke(self, context, event): . W funkcji pobrałem wartości x,y i z jakie obiekt ma w momencie wywołania i dodałem je do sliderów. W skutek czego problem został rozwiązany. Funkcja poll jest używana do sprawdzenia czy operator może się wykonać. W naszym przypadku jednym kryterium jest istnienie jakiegoś obiektu. W celu sprawdzenia, czy jakiś obiekt istnieje lub czy jest zaznaczony możemy w dokumentacji znaleźć gotową funkcję : Po dodaniu funkcji do klasy operatora w momencie, gdy nie ma żadnego obiektu przycisk odpowiadający operatorowi jest szary i nie jest możliwe wywołanie operatora.
