2016-12-02 119 views
0

如何获得并打印处理OBJ的顶点?处理OBJ提取顶点

PShape x; 

void setup(){ size(600,600,P3D); x = loadShape("x.obj"); 

} void draw(){ 

    for (int i = 0; i < x.getVertexCount(); i++) { PVector v = 
x.getVertex(i); 

translate(width/2,height/2); shape(x,0,0); } 

} 
+0

如果你告诉我们这段代码是干什么的,那将会很有帮助。此外,如果你可以提供一个链接到你的'x.obj'文件。 –

回答

0

我建议可以先看看我们的OBJ format,并在您的网格。(上Paul Bourke's site更多细节)

你应该能够很容易地检查使用免费的3D编辑器(如BlenderWings3D等拓扑)。 (如mesh -> triangles or quads -> vervices

的想法是有一个清醒的认识你的文件是如何构建的(它使用三角形,方形脸或组合,有没有嵌套结构,等等)

一旦你知道你的模型是如何构造的,访问每个人脸和它的顶点会更容易。正如凯文提到的,只需使用Processing的PShape函数来遍历网格。例如:

  • getChildCount()算PShape子实例的数量(方便遍历深度嵌套的树形结构)
  • getChild()在给定的情况下
  • getVertexCount()检索PShape子实例来计算一个顶点PShape例如
  • getVertex()获得在给定的(有效索引)一PShape实例顶点

要河畔e至总是检查在遍历之前有多少PShape子项可用,以及有多少个顶点可用于避免NullPointerReference错误。

Processing sample rocket.obj in Wings3D Editor

下面是例子>基本>形状> LoadDisplayOBJ

/** 
* Load and Display an OBJ Shape. 
* 
* The loadShape() command is used to read simple SVG (Scalable Vector Graphics) 
* files and OBJ (Object) files into a Processing sketch. This example loads an 
* OBJ file of a rocket and displays it to the screen. 
*/ 


PShape rocket; 

float ry; 

int startFaceIndex = 0; 
int stopFaceIndex; 

int maxFaceIndex; 

public void setup() { 
    size(640, 360, P3D); 

    rocket = loadShape("rocket.obj"); 

    maxFaceIndex = rocket.getChildCount(); 
    stopFaceIndex = maxFaceIndex; 

    println("total faces:",rocket.getChildCount()); 
    println("faces[0] vertices count:",rocket.getChild(0).getVertexCount()); 
    println("faces[0] vertices[0]",rocket.getChild(0).getVertex(0)); 
    println("faces[0] vertices[1]",rocket.getChild(0).getVertex(1)); 
    println("faces[0] vertices[2]",rocket.getChild(0).getVertex(2)); 
} 

public void draw() { 
    background(0); 
    lights(); 

    translate(width/2, height/2 + 100, -200); 
    rotateZ(PI); 
    rotateY(ry); 
    //shape(rocket); 
    drawFaceSelection(); 

    ry += 0.02; 
} 

void drawFaceSelection(){ 
    beginShape(TRIANGLES); 
    for(int i = startFaceIndex; i < stopFaceIndex; i++){ 
    PShape face = rocket.getChild(i); 
    int numVertices = face.getVertexCount(); 
    for(int j = 0; j < numVertices; j++){ 
     vertex(face.getVertexX(j),face.getVertexY(j),face.getVertexZ(j)); 
    } 
    } 
    endShape(); 
} 

void mouseDragged(){ 
    if(keyPressed){ 
    startFaceIndex = (int)map(mouseX,0,width,0,maxFaceIndex-1); 
    startFaceIndex = constrain(startFaceIndex,0,maxFaceIndex-1); 
    }else{ 
    stopFaceIndex = (int)map(mouseX,0,width,1,maxFaceIndex-1); 
    stopFaceIndex = constrain(stopFaceIndex,0,maxFaceIndex-1); 
    } 
} 

样本的修改版本运行演示,您可以拖动鼠标X轴,以控制多少面孔的。OBJ网格绘制:

rocket.obj partial triangles rendered in Processing

如果你不关心的面孔/结构,只是想访问的顶点(使它们为四边形或任何你喜欢的形状),你可以写一个递归功能遍历PShape和它的孩子和所有的顶点追加到平面列表:

/** 
* Load and Display an OBJ Shape. 
* 
* The loadShape() command is used to read simple SVG (Scalable Vector Graphics) 
* files and OBJ (Object) files into a Processing sketch. This example loads an 
* OBJ file of a rocket and displays it to the screen. 
*/ 


PShape rocket; 

float ry; 

ArrayList<PVector> vertices = new ArrayList<PVector>(); 
int startVertexIndex = 0; 

public void setup() { 
    size(640, 360, P3D); 
    strokeWeight(9); 

    rocket = loadShape("rocket.obj"); 

    getVertices(rocket,vertices); 
    println(vertices); 
} 

/* 
* recursively retrieves vertices from a PShape 
* @arg PShape shape - the PShape instance to traverse (must be not null) 
* @arg ArrayList<PVector> vertices - the list of vertices to add values to 
*/ 
void getVertices(PShape shape,ArrayList<PVector> vertices){ 
    //for each face in current mesh 
    for(int i = 0 ; i < shape.getChildCount(); i++){ 
    //get each child element 
    PShape child = shape.getChild(i); 
    int numChildren = child.getChildCount(); 
    //if has nested elements, recurse 
    if(numChildren > 0){ 
     for(int j = 0 ; j < numChildren; j++){ 
     getVertices(child.getChild(j),vertices); 
     } 
    } 
    //otherwise append child's vertices 
    else{ 
     //get each vertex and append it 
     for(int j = 0 ; j < child.getVertexCount(); j++){ 
     vertices.add(child.getVertex(j)); 
     } 
    } 
    } 
} 

public void draw() { 
    background(255); 
    lights(); 

    translate(width/2, height/2 + 100, -200); 
    rotateZ(PI); 
    rotateY(ry); 
    //shape(rocket); 
    drawVerticesSelection(); 

    ry += 0.02; 
} 

void drawVerticesSelection(){ 
    beginShape(POINTS); 
    for(int i = startVertexIndex; i < vertices.size(); i++){ 
    PVector v = vertices.get(i); 
    vertex(v.x,v.y,v.z); 
    } 
    endShape(); 
} 

void mouseDragged(){ 
    startVertexIndex = (int)map(mouseX,0,width,0,vertices.size()-1); 
    startVertexIndex = constrain(startVertexIndex,0,vertices.size()-1); 
} 

这里有一个预览显示/隐藏顶点网格: PShape Vertices preview

在裸无视这个问题vertexCodes()

此外,如果您不想更改.obj文件本身及其呈现方式,则应该查看GLSL并阅读Processing PShader tutorial。它的层次较低,但效率会更高,并且在渲染过程中您将拥有更多的灵活性。

0

the Processing forum

根据该文件,在getVertexCount()getVertex()功能都只能在你通过调用函数vertex()添加顶点的工作,而不是从形状你从文件加载。

但是有一种方法可以(至少有时)到达形状文件中的顶点:首先必须遍历形状文件的子节点,然后从这些子节点获取顶点。

PShape shape = loadShape("x.obj"); 
PShape child = shape.getChild(0); 
PVector vertex = child.getVertex(0); 

咨询the reference的功能,它会让你遍历每个孩子PShape,然后在每个孩子的顶点循环。