• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

JavaFX TriangleMesh Issue

 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can somebody please help me?

I am trying to render an .obj file in JavaFX using TriangleMesh and the issue I encounter is that I always see in the console the following warning

"The values in the faces array must be within the range of the number of vertices in the points array (0 to points.length / 3 - 1) for the point indices, within the range of the number of vertices in the normals array (0 to normals.length / 3 - 1)"

and the mesh is not rendered.

There are 400 vertices and the sphere is triangulated.

It only renders it when I duplicate the last vertex in the file (sphere.obj), but then some faces of the mesh(sphere) get distorted.

I created the sphere in Maya and exported it in .obj file type. Meshlab renders the exported file with no issue.

I tried looking into what could be causing this issue with the debugger but I see nothing.

I also tried to render the cube from the following website http://paulbourke.net/geometry/roundcube/ but the issue is the same.

I don't know which way to go next.
 
Stevens Miller
Bartender
Posts: 1377
28
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ben, can you dump the .obj file in a readable format and see if any of the faces attempt to refer to points outside the range limit? A sphere and a cube are closed surfaces, but it might be the case that your .obj file somehow describes them as open surfaces with a closed seam somewhere, and the seam points are getting lost.

Just a wild-eyed guess from me, but your problem reminds me of some similar issues I confronted when writing graphics code a long time ago.
 
Stevens Miller
Bartender
Posts: 1377
28
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just did a little reading up on the .obj file format. It's human-readable by design. If you can create a small .obj file that produces the same problem, Ben, post it here.
 
Stevens Miller
Bartender
Posts: 1377
28
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ben Taylor wrote:I also tried to render the cube from the following website http://paulbourke.net/geometry/roundcube/ but the issue is the same.

Just looked at that in more detail. I'd use material from that source with caution. Regarding the "roundcube" mesh:
Paul Bourke wrote:The normals are straightforward to calculate, they are just the vectors to the vertices of the roundcube centered at the origin.

I can't parse that statement in any way other than to have it mean he is calculating the normals for a sphere in every case. They won't be unitized, the way he's doing it, but surface normals aren't necessarily unit normals, and they don't change direction even when you do unitize them.

What Bourke calls a "roundcube" is maybe better known as a "superquadric." A good treatment, with both math and code, is here.

Post some of that .obj and we'll have a look.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The code I'm using is:



and the method used to render the mesh is:


I attached the sphere.obj file in this post. I only have faces and vertices inside the file.
Also a picture showing the rendering in JavaFX and the rendering in MeshLab.

Notice that in the JavaFX rendering there are also faces created inside the sphere which is not supposed to happen.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I could not upload pictures, therefor I am sharing my dropbox link https://www.dropbox.com/sh/i7ahfgxyt434us7/AAD8XeJncbtCpfDiU_XhQgAra?dl=0 with the sphere and 2 pictures one is the rendering in meshlab and the other one in JavaFX.
Thank you.

 
Stevens Miller
Bartender
Posts: 1377
28
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Looks like you've got two problems, Ben. First, your faces all refer to both a vertex and a texture location at each point. Any face entry of the form:

f V1/T1 V2/T2 V3/T3

refers to entries in the points array and in the texture array. You don't seem to have a texture array.

Second, it looks from the values you are using for T1, T2, and T3, that you really intend to refer to entries in your points array, as though they were also normal vector components. That may actually be due to the line I quoted from Bourke's essay which, like I said, I think is in error, but, more to the point, in a .obj file, when you refer to normal vector components, you must be referring to a normal array. You don't seem to have one of those, either.

Entries in a normal array look like this:

vn x y z

where x, y, and z are real numbers defining the components of normal vectors. You can refer to these by skipping the part of a face entry that refers to a texture array, and adding references to the entries in the normal array, like this:

f V1//N1 V2//N2 V3//N3

I didn't look at your code, but see if you can create a normal array of the format I've described, and add the extra "/" to your face entries that will turn the texture array references you've got now into normal array references.

Let me know how that works out.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Texture array is not needed, I tested with other objects and it works ok.

What I did:

I made a file parser for the .obj file which works like this:
it scans every line in the file and when it finds the letter V then the 3 coordinates X Y Z are added to a list of floats. This list is then converted into an array of floats in order to conform with TriangleMesh ex:mesh.getPoints().addAll(arrayOfPoints);

when it finds the letter F then this means it is a face which means that the coordinates for the face are added to the listOfFacesFromObjFile.

Normals(vn) or Textures, I think are not needed, because other objects work with the basic 1,1 for all the faces.

 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here is a lower resolution of the sphere rendered correctly on the "sides", however on the top and bottom it is somehow opened and the top vertices create faces with the opposite vertices.

I was able to render it only after I copied and pasted the last vertex one more time, else I would receive the warning in the console. Can Maya be the issue here? I create the Sphere in Maya and then export it, however Meshlab renders with no problem.
Screen Shot 2016-05-17 at 22.41.01.jpg
[Thumbnail for Screen Shot 2016-05-17 at 22.41.01.jpg]
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suspect there is a vertex array reading problem here, that is why I always need to duplicate the last vertex(or other vertex) in the .obj file.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Here are 2 pictures with the rendering in Maya which is ok and the rendering in JavaFX which is distorted. I used here an Icosahedron Obj file exported from Maya.
Again here I was able to render it only after I duplicated the last vertex while editing the .obj file.

Can it be that when the vertices get loaded in the array of floats in the TriangleMesh, the face POINT nr 42 can not be found in that array? I mean the index of the array lets say index 42(which actually corresponds to 3 coordinates in the array because it counts then from 3 to 3 in a row)?
ico.jpg
[Thumbnail for ico.jpg]
OBJfile.jpg
[Thumbnail for OBJfile.jpg]
 
Stevens Miller
Bartender
Posts: 1377
28
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't see a problem in your code, but something's wrong somewhere. Let's try a couple of things.

First, instead of duplicating the last vertex, try adding a valid vertex record, but for a vertex that's not part of your icosahedron, like this:

v .1 .2 .3

If that changes how it is rendered, we know it is being read somehow. I'm guessing it won't change, which suggests we're missing an off-by-one error in either how the list of points is first loaded, or how it is converted to the point array in your second method.

Next, try eliminating all the vertices your icosahedron faces don't use. That way, we can add some debugging code to your createMesh2 method, and find out what vertices the faces are actually using. Also, I think I see why you didn't need texture references: you're adding them in your createMesh2 method. Until we get it working, I'd suggest you take all that out. Debugging is easiest when you have stripped down your code to the smallest number of lines (and your data to the smallest number of records) that still produces the error.

Do those things and let me know what happens.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well I've rewritten the whole project again and if I duplicate the first vertex(not the last) it renders the .obj perfect.
I think there is an indexing issue here in the array, but I can't say for sure.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I uploaded some samples from different angles. Still I can not see the issue, why if I duplicate the first vertex in .obj file it renders it ok.
1.jpg
[Thumbnail for 1.jpg]
2.jpg
[Thumbnail for 2.jpg]
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
And now with the first vertex duplicated MeshLab does not render it correctly, but JavaFX renders ok.
 
Ben Taylor
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Finally !!! I solved it !!!

The issue was Maya!

Maya exported the faces starting from value 1 to max which means that after my program parsed the .obj file to get the list of points and vertices, it wasn't reading the index 0 in the points array, it was always starting from 1(because nr 1 was the first point of the face).This is why duplicating the first vertex in the .obj file worked.

The solution I found was to substract -1 from every face point, which moves the index back with one position.

Thank you.
 
Stevens Miller
Bartender
Posts: 1377
28
C++ Java Netbeans IDE Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ben Taylor wrote:Finally !!! I solved it !!!

The issue was Maya!

Maya exported the faces starting from value 1 to max which means that after my program parsed the .obj file to get the list of points and vertices, it wasn't reading the index 0 in the points array, it was always starting from 1(because nr 1 was the first point of the face).This is why duplicating the first vertex in the .obj file worked.

The solution I found was to substract -1 from every face point, which moves the index back with one position.

Thank you.


Well done, Ben! Glad you found the solution. Your sense that it was an off-by-one error appears to have been correct. When dealing with a lot of data, you can often make debugging easier if you reduce your data set to the smallest number of records that still shows the problem. You were able to solve it this time without doing that, but do keep that notion in mind for the future. Someimes, your problem will involve more records than you can print. Paring down the problem to something you can fit on one page is frequently a good path to an answer.

Good work!
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic