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.
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 if
s 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.
This is Objective-C code, why is the question tagged with [swift] ?
– Martin R
Apr 10 '15 at 13:37