Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
For the fun, a Photos cube
-
-
dataWithBytes_length_ expects sizeof(verts_array)
datIndexes = ObjCClass('NSData').dataWithBytes_length_(indexes_array,sizeof(indexes_array))
as a check:
geometry.geometryElements()[0].data()
-
@JonB Thanks for the correction but obviously not the only error because still blank Scene...
-
@momorprods Eureka, same code but with other vertices shows a triangle
One more time, thanks to @JonB without whom we would never solve these problems.
verts = [SCNVector3(0, 0, 1), SCNVector3(1, 0, 0), SCNVector3(0, 1, 0)]
-
guys you are genius. Not sure why the vertex order did change something, probably it needs to be defined clockwise or something like that.
Thanks for all of your help, you are awesome!
-
@momorprods Be careful, indexes need to be 32 bits long, thus use c_int
In a previous post, I said the first index must be the number of points, that's true but for polygons, not for triangles, sorry for thatindexes = [3,0,1,2] indexes_array = (c_int*len(indexes))(*indexes) datIndexes = ObjCClass('NSData').dataWithBytes_length_(indexes_array,sizeof(indexes_array)) # primitiveType = 0 for SCNGeometryPrimitiveTypeTriangles # 4 for SCNGeometryPrimitiveTypePolygon # primitiveCount = 1 e = ObjCClass('SCNGeometryElement').geometryElementWithData_primitiveType_primitiveCount_bytesPerIndex_(datIndexes,4,1,sizeof(c_int))
-
@momorprods I don't think we need a particular order for vertices but if the plane of the triangle contains the camera, you don't see the element, try by turning the triangle with one finger
-
@momorprods Sorry, you were right about vertices sequence, see here
-
@cvp I think there is still something weird, as the coordinates of the vertices really don’t match what’s expected. The triangle totally disappear if I just scale the Z value of the 1st vertice, which is not normal.
And overall the size of the triangle is not what it should be (confirmed this by overlapping a cube box and also by estimating through the ARKit rendering).
Since it shows the triangle, the indexing part of the code must be ok - it probably deals with the SCNVector3 array. Perhaps I’m wrong, but SCNVector3 looks like an ObjC class, not a C record?
-
ah sorry my bad, In my tests I tweaked badly my SCNVector3 using c_double instead of c_float. Fixed and working now.
-
@momorprods This works also:
verts = [SCNVector3(0, 1, 0), SCNVector3(-0.5, 0, 0.5), SCNVector3(0.5, 0, 0.5), SCNVector3(0.5, 0, -0.5), SCNVector3(-0.5, 0, -0.5), SCNVector3(0, -1, 0)] SCNVector3Array3 = SCNVector3 * len(verts) verts_array = SCNVector3Array3(*verts) SCNGeometrySource = ObjCClass('SCNGeometrySource') s = SCNGeometrySource.geometrySourceWithVertices_count_(byref(verts_array), len(verts), restype=c_void_p, argtypes=[POINTER(SCNVector3Array3), c_ulong],) indexes = [3,3,3,3,3,3,3,3, 0, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 0, 1, 5, 2, 2, 5, 3, 3, 5, 4, 4, 5, 1] indexes_array = (c_int*len(indexes))(*indexes) datIndexes = ObjCClass('NSData').dataWithBytes_length_(indexes_array,sizeof(indexes_array)) # primitiveType = 0 for SCNGeometryPrimitiveTypeTriangles # 4 for SCNGeometryPrimitiveTypePolygon # primitiveCount = 1 e = ObjCClass('SCNGeometryElement').geometryElementWithData_primitiveType_primitiveCount_bytesPerIndex_(datIndexes,4,8,sizeof(c_int)) geometry = ObjCClass('SCNGeometry').geometryWithSources_elements_([s],[e]) ```
-
For info SCNVector3 is 3 c_float not c_double
Tryfrom objc_util import * import ctypes import ui import math from ImageColor import getrgb load_framework('SceneKit') SCNView, SCNScene, SCNBox, SCNNode, SCNMaterial, SCNCamera, SCNLight, SCNAction, SCNLookAtConstraint = map(ObjCClass, ['SCNView', 'SCNScene', 'SCNBox', 'SCNNode', 'SCNMaterial', 'SCNCamera', 'SCNLight', 'SCNAction', 'SCNLookAtConstraint' ]) class SCNVector3(Structure): _fields_ = [('x', c_float), ('y', c_float), ('z', c_float)] @on_main_thread def demo(): main_view = ui.View() main_view_objc = ObjCInstance(main_view) scene_view = SCNView.alloc().initWithFrame_options_(((0, 0),(100, 50)), None).autorelease() scene_view.setAutoresizingMask_(18) scene_view.setAllowsCameraControl_(True) main_view_objc.addSubview_(scene_view) main_view.name = 'SceneKit Demo' scene = SCNScene.scene() scene_view.setScene_(scene) root_node = scene.rootNode() camera = SCNCamera.camera() camera_node = SCNNode.node() camera_node.setCamera(camera) camera_node.setPosition((0,0,5)) root_node.addChildNode_(camera_node) #https://medium.com/@zxlee618/custom-geometry-in-scenekit-f91464297fd1 verts = [ SCNVector3(0, 1, 0), SCNVector3(-0.5, 0, 0.5), SCNVector3(0.5, 0, 0.5), SCNVector3(0.5, 0, -0.5), SCNVector3(-0.5, 0, -0.5), SCNVector3(0, -1, 0)] SCNVector3Array3 = SCNVector3 * len(verts) verts_array = SCNVector3Array3(*verts) SCNGeometrySource = ObjCClass('SCNGeometrySource') s = SCNGeometrySource.geometrySourceWithVertices_count_(byref(verts_array), len(verts), restype=c_void_p, argtypes=[POINTER(SCNVector3Array3), c_ulong],) indexes = [3,3,3,3,3,3,3,3, 0, 1, 2, 2, 3, 0, 3, 4, 0, 4, 1, 0, 1, 5, 2, 2, 5, 3, 3, 5, 4, 4, 5, 1] indexes_array = (c_int*len(indexes))(*indexes) datIndexes = ObjCClass('NSData').dataWithBytes_length_(indexes_array,sizeof(indexes_array)) # primitiveType = 0 for SCNGeometryPrimitiveTypeTriangles # 4 for SCNGeometryPrimitiveTypePolygon # primitiveCount = 1 e = ObjCClass('SCNGeometryElement').geometryElementWithData_primitiveType_primitiveCount_bytesPerIndex_(datIndexes,4,8,sizeof(c_int)) geometry = ObjCClass('SCNGeometry').geometryWithSources_elements_([s],[e]) #print(geometry.geometryElements()[0].data()) # to check Material = SCNMaterial.material() Material.contents = ObjCClass('UIColor').colorWithRed_green_blue_alpha_(1,0.9,0.9,1.0) geometry.setMaterials_([Material]) geometry_node = SCNNode.nodeWithGeometry_(geometry) root_node.addChildNode_(geometry_node) e2 = [] Materials = [] colors = ['red','blue','green','yellow','orange','pink','cyan','orchid'] for i in range(0,8): j = 8 + i*3 indexes2 = [indexes[j],indexes[j+1],indexes[j+2]] indexes_array2 = (c_int*len(indexes2))(*indexes2) datIndexes2 = ObjCClass('NSData').dataWithBytes_length_(indexes_array2,sizeof(indexes_array2)) e = ObjCClass('SCNGeometryElement').geometryElementWithData_primitiveType_primitiveCount_bytesPerIndex_(datIndexes2,0,1,sizeof(c_int)) e2.append(e) rgb = getrgb(colors[i]) r,g,b = tuple(c/255.0 for c in rgb) Material = SCNMaterial.material() Material.contents = ObjCClass('UIColor').colorWithRed_green_blue_alpha_(r,g,b,1.0) Materials.append(Material) geometry2 = ObjCClass('SCNGeometry').geometryWithSources_elements_([s],e2) geometry2.setMaterials_(Materials) geometry2_node = SCNNode.nodeWithGeometry_(geometry2) tx,ty,tz = (-1.5,0,0) x = (1,0,0,0, 0,1,0,0, 0,0,1,0, tx,ty,tz,1) # translation geometry2_node.setPivot_(x) root_node.addChildNode_(geometry2_node) # Add a constraint to the camera to keep it pointing to the target geometry constraint = SCNLookAtConstraint.lookAtConstraintWithTarget_(geometry_node) constraint.gimbalLockEnabled = True camera_node.constraints = [constraint] light_node = SCNNode.node() light_node.setPosition_((100, 0, -10)) light = SCNLight.light() light.setType_('directional') light.setCastsShadow_(True) light.setColor_(UIColor.whiteColor().CGColor()) light_node.setLight_(light) root_node.addChildNode_(light_node) rotate_action = SCNAction.repeatActionForever_(SCNAction.rotateByX_y_z_duration_(0, math.pi*2, 0, 10)) geometry_node.runAction_(rotate_action) geometry2_node.runAction_(rotate_action) main_view.present(hide_title_bar=True) demo()
-
-
great job @cvp ! currently working onto loading collada files, might take most of my upcoming oversea flight! I’ll keep you posted.