3D drawing with SceneKit in Pythonista

I found a script that can draw 3D only on iOS by using SceneKit with objc_util of Pythonista, so I will introduce it.

Original article

3d-omz.py Note: If you don't add load_framework (‘SceneKit’), you will get an error. https://github.com/tdamdouni/Pythonista/blob/master/scenes/3d-omz.py

3D in Pythonista https://forum.omz-software.com/topic/1686/3d-in-pythonista

Execution image



from objc_util import *

Allows you to directly call the functionality provided by the objc_util module.

Since the objc_util module is based on the standard module ctypes, this one line also allows you to use the Structure etc. provided by the ctypes module.


Load the SceneKit framework so that it can be manipulated programmatically.

Since it was not described in 3d-omz.py, it may not have been necessary to call it in the past, but in iPadOS13, when converting the SCNView class etc. provided by SceneKit to a format that can be used in Python with ObjCClass I get angry with the error no Objective-C class named'xxxx' found.

SCNView, SCNScene, SCNBox, SCNText, SCNNode, SCNLight, SCNAction, UIFont = map(ObjCClass, ['SCNView', 'SCNScene', 'SCNBox', 'SCNText', 'SCNNode', 'SCNLight', 'SCNAction', 'UIFont'])

The classes provided by SceneKit are converted to a format that can be used in Python using obj_util.ObjCClass.

It's easy to use the standard function map because you can write the same process all at once.

class SCNVector3 (Structure):
    _fields_ = [('x', c_float), ('y', c_float), ('z', c_float)]

Use ctypes.Structure to define a structure with three attributes (x, y, z) of type float. The structure defined here will be used later to get the BoundingBox of Text.

    main_view = ui.View()
    main_view_objc = ObjCInstance(main_view)

I'm getting a pointer to access from Objective-C by creating an empty ui.View and passing that View instance to objc_util.ObjCInstance.

It seems that you can later hang the SceneKit View as a child of this main_view so that you can see the SceneKit drawings inside the Pythonista ui.View. (Details are not understood due to lack of study)

    scene_view = SCNView.alloc().initWithFrame_options_(((0, 0),(400, 400)), None).autorelease()

Create an instance of SCNView by calling the alloc () method. It then calls initWithFrame: options: to initialize it to size (400,400) at position (0,0). Finally, by calling autorelease () on the instance, it is set to automatically destroy the memory when it is no longer needed.

SCNView.initWithFrame:options: https://developer.apple.com/documentation/scenekit/scnview/1524215-initwithframe?language=objc

setAutoresizeMask_ is a method to set what to do when the size of the parent View changes. The number 18 is the logical sum of 2 for flexibleWidth and 16 for flexibleHeight, and by setting this, the width and height will be tracked when the size of the parent View changes.

It's easy to imagine that this is the same as the flex attribute of the View class of the Pythonista ui module.

UIView.AutoresizingMask https://developer.apple.com/documentation/uikit/uiview/1622559-autoresizingmask

Setting setAllowsCameraControl_ to True allows you to swipe the screen and rotate the camera. It is convenient and good to set this to True for some viewers and early development checks.

	scene = SCNScene.scene()
	node_root = scene.rootNode()

Cameras, lights, and drawings managed by SceneKit are all layered by Node. The SCNScene rootNode is the parent of that hierarchy.

After this, by adding various nodes to rootNode, what will be displayed on the screen and how will be decided.

Recommended Posts

3D drawing with SceneKit in Pythonista
Working with 3D data structures in pandas
Defeat ui.View.flex in Pythonista3
Until drawing a 3D graph in Python on windows10
Drawing a tree structure with D3.js in Jupyter Notebook
2D plot in matplotlib
Real-time drawing with matplotlib
Drawing with Python Tinker
3D display with plotly
3D plot with matplotlib
3D or D with Py
[Small story] [Python] Replace strings in 2D arrays with numbers
Let's play with 4D 4th
Use "$ in" operator with mongo-go-driver
Drawing candle charts in python
Drawing GoogLeNet with caffe's draw_net
Working with LibreOffice in Python
Scraping with chromedriver in python
Create 3d gif with python3
Redo Python in Pythonista3 (1) --appex
Graph drawing method with matplotlib
Working with sounds in Python
Scraping with Selenium in Python
Solve ABC175 D in Python
Scraping with Tor in Python
3D scatter plot with PyQtGraph
Bidirectional file transfer with Pythonista 3
Combined with permutations in Python
Graph drawing with IPython Notebook
Interpolate 2D data with scipy.interpolate.griddata
How to display legend marks in one with Python 2D plot