SceneKit : extraire data from SCNGeometryElement


SceneKit : extraire data from SCNGeometryElement



I am using SceneKit, and I have an issue:



How can I extract the data from a SCNGeometryElement object ?
I use this method :


SCNGeometryElement


- (void)geometryElements:(SCNNode *)node {
for (int indexElement = 0; indexElement < node.geometry.geometryElementCount; indexElement++) {
SCNGeometryElement *currentElement = [node.geometry geometryElementAtIndex:indexElement];

NSLog(@"n");
NSLog(@"bytes per index : %d", currentElement.bytesPerIndex);
NSLog(@"number element : %d", currentElement.primitiveCount);
NSLog(@"data lenght : %d", currentElement.data.length);

for (int indexPrimitive = 0; indexPrimitive < currentElement.primitiveCount; indexPrimitive++) {
int array[3];
memset(array, 0, 3);

[currentElement.data getBytes:&array range:NSMakeRange(indexPrimitive * 3, (currentElement.bytesPerIndex * 3))];

NSLog(@"currentelement : %d %d %d", array[0], array[1], array[3]);
}
}



The result is not good :


2015-04-10 15:10:25.183 IKTest[1234:244778] currentelement : 14539995 -1068223968 -379286778
2015-04-10 15:10:25.183 IKTest[1234:244778] currentelement : 14737374 -1068223968 -379286778
2015-04-10 15:10:25.183 IKTest[1234:244778] currentelement : 14934753 -1068223968 -379286778



Thanks in advance.





This is Objective-C code, why is the question tagged with [swift] ?
– Martin R
Apr 10 '15 at 13:37





I believe you should be using uint instead of int. Can you try? (also print with %u instead of %d)
– gbuzogany
Apr 10 '15 at 13:38






From the documentation: "An element’s data is an array of index values identifying vertices in a geometry source. SceneKit interprets the data as an array of unsigned integers, whose size is specified by the bytesPerIndex property.". I have no experience with SCNGeometryElement, but according to the docs it could be 8-, 16-, 32- or 64-bit unsigned integers.
– Martin R
Apr 10 '15 at 13:40






Doesn't work with uint type.
– user2724028
Apr 10 '15 at 13:50





I can't find some example on internet.
– user2724028
Apr 10 '15 at 13:54




2 Answers
2



a few notes:


geometryElement.primitiveType


3


SCNGeometryPrimitiveTypeTriangles


geometryElement.bytesPerIndex


3 * sizeof(int)


numberOfIndicesPerPrimitive * geometryElement.bytesPerIndex





Thanks, but it didn't save me. i replace all variable. it seems impossible to get something clear.
– user2724028
Apr 10 '15 at 15:40





i tried with : "CFSwapInt16((ushort)([data4 bytes]));" still not working. I passed 3 days on it, i think it's impossible.
– user2724028
Apr 13 '15 at 8:02





CFSwapInt16 changes the endianness of an integer, so it's useless here. What you need to do is to check what bytesPerIndex is, and make sure (with ifs or a case) that you are always dealing with the right type.
– mnuages
Apr 13 '15 at 10:44



CFSwapInt16


bytesPerIndex


if


case



As mnuages said, you should confirm primtive type and data type of index first.
Your code only work if index type is int.


int



Here is some code work for me. I only deals that geometry consisted of triangles.


void extractInfoFromGeoElement(NSString* scenePath){
NSURL *url = [NSURL fileURLWithPath:scenePath];
SCNScene *scene = [SCNScene sceneWithURL:url options:nil error:nil];
SCNGeometry *geo = scene.rootNode.childNodes.firstObject.geometry;
SCNGeometryElement *elem = geo.geometryElements.firstObject;
NSInteger componentOfPrimitive = (elem.primitiveType == SCNGeometryPrimitiveTypeTriangles) ? 3 : 0;
if (!componentOfPrimitive) {//TODO: Code deals with triangle primitive only
return;
}
for (int i=0; i<elem.primitiveCount; i++) {
void *idxsPtr = NULL;
int stride = 3*i;
if (elem.bytesPerIndex == 2) {
short *idxsShort = malloc(sizeof(short)*3);
idxsPtr = idxsShort;
}else if (elem.bytesPerIndex == 4){
int *idxsInt = malloc(sizeof(int)*3);
idxsPtr = idxsInt;
}else{
NSLog(@"unknow index type");
return;
}
[elem.data getBytes:idxsPtr range:NSMakeRange(stride*elem.bytesPerIndex, elem.bytesPerIndex*3)];
if (elem.bytesPerIndex == 2) {
NSLog(@"triangle %d : %d, %d, %dn",i,*(short*)idxsPtr,*((short*)idxsPtr+1),*((short*)idxsPtr+2));
}else{
NSLog(@"triangle %d : %d, %d, %dn",i,*(int*)idxsPtr,*((int*)idxsPtr+1),*((int*)idxsPtr+2));
}
//Free
free(idxsPtr);
}
}






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV