处理OBJ提取顶点 [英] Processing OBJ extract vertex

查看:182
本文介绍了处理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);

translation(width / 2,height / 2);形状(x,0,0); }

}


解决方案

I建议先看看



这里是示例>基础>形状的示例的修改版本> LoadDisplayOBJ

  / ** 
*加载并显示OBJ形状。
*
* loadShape()命令用于将简单的SVG(可缩放矢量图形)
*文件和OBJ(对象)文件读取到处理草图中。本示例加载火箭的
* OBJ文件并将其显示在屏幕上。
* /


PShape火箭;

浮动资金;

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 face:,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();

平移(width / 2,height / 2 + 100,-200);
rotationZ(PI);
rotationY(ry);
//形状(火箭);
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 ++){
顶点(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网格的面的数量:





如果您不关心面/结构而只想访问顶点(将其渲染为四边形或您喜欢的任何形状),则可以编写一个递归函数来遍历PShape并且它是孩子,并将所有顶点附加到平面列表中:

  / ** 
*加载并显示OBJ形状。
*
* loadShape()命令用于将简单的SVG(可缩放矢量图形)
*文件和OBJ(对象)文件读取到处理草图中。本示例加载火箭的
* OBJ文件并将其显示在屏幕上。
* /


PShape火箭;

浮动资金;

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

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

rocket = loadShape( rocket.obj);

getVertices(火箭,顶点);
println(vertices);
}

/ *
*递归地从PShape
*中检索顶点* @arg PShape形状-要遍历的PShape实例(必须不为null)
* @arg ArrayList< PVector> vertices-将值添加到
* /
的顶点列表void getVertices(PShape shape,ArrayList< PVector>顶点){
//对于当前网格物体中的每个面
(int i = 0; i< shape.getChildCount(); i ++){
//获取每个子元素
PShape child = shape.getChild(i);
int numChildren = child.getChildCount();
//如果具有嵌套元素,则递归
if(numChildren> 0){
for(int j = 0; j< numChildren; j ++){
getVertices(child .getChild(j),vertices);
}
}
//否则附加子顶点
else {
//获取每个顶点并附加
for(int j = 0; j < child.getVertexCount(); j ++){
vertices.add(child.getVertex(j));
}
}
}
}

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

平移(width / 2,height / 2 + 100,-200);
rotationZ(PI);
rotationY(ry);
//形状(火箭);
drawVerticesSelection();

ry + = 0.02;
}

void drawVerticesSelection(){
beginShape(POINTS);
for(int i = startVertexIndex; i< vertices.size(); i ++){
PVector v = vertices.get(i);
顶点(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);
}

以下是在网格中显示/隐藏顶点的预览:
< a href = https://i.stack.imgur.com/4e4QZ.gif rel = nofollow noreferrer>



请记住,这会忽略 vertexCodes()



此外,如果您不如果不想更改.obj文件本身及其呈现方式,则应查看GLSL并阅读处理PShader教程。它的级别较低,但效率更高,并且在渲染过程中具有更大的灵活性。


How can i get, and print vertex of an OBJ on processing?

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); }

}

解决方案

I recommend first having a look at the OBJ format and at your mesh.(More details on Paul Bourke's site)

You should be able to easily inspect the topology using a free 3D editor (such as Blender, Wings3D, etc.). (e.g. mesh -> triangles or quads -> vervices)

The idea is to have a clear understanding how your file is structured (does it use triangle, quad faces or a combination, are there any nested structures, etc.)

Once you know how your model is structured it will be much easier to access each face and it's vertices. As Kevin mentioned, just use Processing's PShape functions to traverse the mesh. For example:

  • getChildCount() to count the number of PShape child instances (handy for traversing deeply nested tree structures)
  • getChild() to retrieve a PShape child instance at a given instance
  • getVertexCount() to count vertices in a PShape instance
  • getVertex() to get a PShape instance vertex at a given (valid index)

Be sure to always check how many PShape children are available before traversing and how many vertices are available to avoid NullPointerReference errors.

Here's a modified version of the sample from Examples > Basics > Shape > 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);
  }
}

Running the demo you can drag the mouse on X axis to control how many faces of the .obj mesh are drawn:

If you don't care about the faces/structure and just want to access the vertices (to render them as quads or any shape you like), you could write a recursive function to traverse the PShape and it's children and append all vertices to a flat list:

/**
 * 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);
}

Here's a preview showing/hiding vertices in a mesh:

Bare in mind this ignores vertexCodes().

Additionally, if you don't want to change the .obj file itself and just how it's rendered, you should look into GLSL and read the Processing PShader tutorial. It's lower level, but will be a lot more efficient and you'll have a lot more flexibility over the rendering process.

这篇关于处理OBJ提取顶点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆