简体   繁体   English

iOS从.obj文件中删除面和顶点

[英]iOS remove faces and vertices from .obj file

I use SceneKit to display .obj file. 我使用SceneKit来显示.obj文件。 But to get an .obj file I use SDK from a sensor, so this sensor scans the arm of a man and returns the .obj file as a result. 但是要获取.obj文件,我使用了一个传感器的SDK,因此该传感器扫描了一个人的手臂并返回了.obj文件。 But when I load the .obj file, there are a lot of not proper parts (part of chair, part of the surface and so on), I need to remove these parts of the object, so as a result I has to see only the arm of the man. 但是,当我加载.obj文件时,有很多不合适的部分(椅子的一部分,表面的一部分等等),我需要删除对象的这些部分,因此,我只能看到男人的手臂。

So for example I want to select a rectangle or a sphere and to remove all vertices and faces in this sphere. 因此,例如,我想选择一个矩形或一个球体,并删除该球体中的所有顶点和面。

Are there any SDK or frameworks in iOS to do that? iOS中是否有任何SDK或框架可以做到这一点?

PS I tried nineveh and some other frameworks, but they can only view objects, they can't edit them. PS我尝试了nineveh和其他一些框架,但它们只能查看对象,而不能编辑它们。

Edit 编辑

I found the code to manipulate vertices (it merges vertices from different child nodes) in SceneKit. 我发现了在SceneKit中操纵顶点(合并来自不同子节点的顶点)的代码。 Can I use the same approach to find vertices I need to remove (that are inside my rectangle) or it will be very slow with 65 K vertices? 我是否可以使用相同的方法来查找需要删除的顶点(位于矩形内),否则在使用65 K顶点时会很慢?

 // // VertexManager.m // Test // #import "VertexManager.h" #import <SceneKit/SceneKit.h> #import <GLKit/GLKit.h> @implementation VertexManager + (SCNNode *) flattenNodeHierarchy:(SCNNode *) input { SCNNode *result = [SCNNode node]; NSUInteger nodeCount = [[input childNodes] count]; if(nodeCount > 0){ SCNNode *node = [[input childNodes] objectAtIndex:0]; NSArray *vertexArray = [node.geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticVertex]; SCNGeometrySource *vertex = [vertexArray objectAtIndex:0]; SCNGeometryElement *element = [node.geometry geometryElementAtIndex:0]; //todo: support multiple elements NSUInteger primitiveCount = element.primitiveCount; NSUInteger newPrimitiveCount = primitiveCount * nodeCount; size_t elementBufferLength = newPrimitiveCount * 3 * sizeof(int); //nTriangle x 3 vertex * size of int int* elementBuffer = (int*)malloc(elementBufferLength); /* simple case: here we consider that all the objects to flatten are the same In the regular case we should iterate on every geometry and accumulate the number of vertex/triangles etc...*/ NSUInteger vertexCount = [vertex vectorCount]; NSUInteger newVertexCount = vertexCount * nodeCount; SCNVector3 *newVertex = malloc(sizeof(SCNVector3) * newVertexCount); SCNVector3 *newNormal = malloc(sizeof(SCNVector3) * newVertexCount); //assume same number of normal/vertex //fill NSUInteger vertexFillIndex = 0; NSUInteger primitiveFillIndex = 0; for(NSUInteger index=0; index< nodeCount; index++){ @autoreleasepool { node = [[input childNodes] objectAtIndex:index]; NSArray *vertexArray = [node.geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticVertex]; NSArray *normalArray = [node.geometry geometrySourcesForSemantic:SCNGeometrySourceSemanticNormal]; SCNGeometrySource *vertex = [vertexArray objectAtIndex:0]; SCNGeometrySource *normals = [normalArray objectAtIndex:0]; if([vertex bytesPerComponent] != sizeof(float)){ NSLog(@"todo: support other byte per component"); continue; } float *vertexBuffer = (float *)[[vertex data] bytes]; float *normalBuffer = (float *)[[normals data] bytes]; SCNMatrix4 t = [node transform]; GLKMatrix4 matrix = MyGLKMatrix4FromCATransform3D(t); //append source for(NSUInteger vIndex = 0; vIndex < vertexCount; vIndex++, vertexFillIndex++){ GLKVector3 v = GLKVector3Make(vertexBuffer[vIndex * 3], vertexBuffer[vIndex * 3+1], vertexBuffer[vIndex * 3 + 2]); GLKVector3 n = GLKVector3Make(normalBuffer[vIndex * 3], normalBuffer[vIndex * 3+1], normalBuffer[vIndex * 3 + 2]); //transform v = GLKMatrix4MultiplyVector3WithTranslation(matrix, v); n = GLKMatrix4MultiplyVector3(matrix, n); newVertex[vertexFillIndex] = SCNVector3Make(vx, vy, vz); newNormal[vertexFillIndex] = SCNVector3Make(nx, ny, nz); } //append elements //here we assume that all elements are SCNGeometryPrimitiveTypeTriangles SCNGeometryElement *element = [node.geometry geometryElementAtIndex:0]; const void *inputPrimitive = [element.data bytes]; size_t bpi = element.bytesPerIndex; NSUInteger offset = index * vertexCount; for(NSUInteger pIndex = 0; pIndex < primitiveCount; pIndex++, primitiveFillIndex+=3){ elementBuffer[primitiveFillIndex] = offset + _getIndex(inputPrimitive, bpi, pIndex*3); elementBuffer[primitiveFillIndex+1] = offset + _getIndex(inputPrimitive, bpi, pIndex*3+1); elementBuffer[primitiveFillIndex+2] = offset + _getIndex(inputPrimitive, bpi, pIndex*3+2); } } } NSArray *sources = @[[SCNGeometrySource geometrySourceWithVertices:newVertex count:newVertexCount], [SCNGeometrySource geometrySourceWithNormals:newNormal count:newVertexCount]]; NSData *newElementData = [NSMutableData dataWithBytesNoCopy:elementBuffer length:elementBufferLength freeWhenDone:YES]; NSArray *elements = @[[SCNGeometryElement geometryElementWithData:newElementData primitiveType:SCNGeometryPrimitiveTypeTriangles primitiveCount:newPrimitiveCount bytesPerIndex:sizeof(int)]]; result.geometry = [SCNGeometry geometryWithSources:sources elements:elements]; //cleanup free(newVertex); free(newNormal); } return result; } //helpers: GLKMatrix4 MyGLKMatrix4FromCATransform3D(SCNMatrix4 transform) { GLKMatrix4 m = {{transform.m11, transform.m12, transform.m13, transform.m14, transform.m21, transform.m22, transform.m23, transform.m24, transform.m31, transform.m32, transform.m33, transform.m34, transform.m41, transform.m42, transform.m43, transform.m44}}; return m; } GLKVector3 MySCNVector3ToGLKVector3(SCNVector3 vector) { GLKVector3 v = {{vector.x, vector.y, vector.z}}; return v; } @end 

否。您将需要使用Blender,Maya,3ds Max或Cheetah 3D之类的3d工具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM