Skip to main content

[JAVA3D-INTEREST] Can I get an IndexedGeometryArray from a Shape3D?

7 replies [Last post]
Anonymous

Hi,All!

I load a VRML model using VrmlLoader in VRML97.jar.
the geometry node in .wrl file which includes 9 points is as follow:

geometry DEF Bone_LeftUpperArm-FACES IndexedFaceSet {
coord DEF Bone_LeftUpperArm-COORD Coordinate { point [
5 5 5, 5 5 -5, 5 -5 -5, 5 -5 5, 250 0.5 0.5,250 0.5 -0.5, 250 -0.5 -0.5, 250 -0.5 0.5, 0 0 0]
}
coordIndex [
4, 7, 5, -1, 6, 5, 7, -1, 1, 5, 2, -1, 6, 2, 5, -1, 0, 4, 1, -1, 5, 1, 4, -1, 7, 3, 6, -1,
2, 6, 3, -1, 4, 0, 7, -1, 3, 7, 0, -1, 8, 0, 1, -1, 8, 1, 2, -1, 8, 2, 3, -1,8, 3, 0, -1]
}

And in my java3d application, the code I used to retrieve the node is follow:
...
Shape3D myShape=new Shape3D();
myShape= (Shape3D) objTG.getChild(0);
//objTG is a TransformGroup which is the Bone_LeftUpperArm-FACES in .wrl file
GeometryArray g;
g = (GeometryArray) myShape.getGeometry();
int vertexNum=g.getValidVertexCount(); //get the VertexCount,but vertexNum=42,not 9!!!
Point3f[] tt=new Point3f[vertexNum];
for (int i=0;i

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
cs

java3d-interest,您好!

I try the ObjectFile,but the result of "indexedGeoArray.getValidVertexCount()" is 32 too!

btw:I can not load your obj file.and I convert the .wrl to the .obj in 3dsmax 6.
the .obj as below:
# Max2Obj Version 6.0 Jul 29th, 2003
#
# object Bone_LeftUpperArm-FACES01 to come ...
#
v 250.0 0.5 0.5
v 250.0 -0.5 0.5
v 250.0 0.5 -0.5
v 250.0 -0.5 -0.5
v 5.0 5.0 -5.0
v 5.0 -5.0 -5.0
v 5.0 5.0 5.0
v 5.0 -5.0 5.0
v 0.0 0.0 0.0
# 9 vertices

g Bone_LeftUpperArm-FACES01
f 1 2 3
f 4 3 2
f 5 3 6
f 4 6 3
f 7 1 5
f 3 5 1
f 2 8 4
f 6 4 8
f 1 7 2
f 8 2 7
f 9 7 5
f 9 5 6
f 9 6 8
f 9 8 7
# 14 faces

      

======= 2004-11-29 06:41:00 您在来信中写道:=======

>Did you try to load it as WaveFront obj instead VRML ?
>
>#start arm.obj file *************
># Wavefront OBJ file
>#
># mtllib arm.mtl
># object Bone_LeftUpperArm-FACES
>
>g Bone_LeftUpperArm_FACES
>v 5 5 5
>v 5 -5 5
>v 5 -5 -4
>v 5 5 -4
>v 250 0.5 1.5
>v 250 -0.5 1.5
>v 250 -0.5 0.5
>v 250 0.5 0.5
>v 0 0 0
>
># 9 verticies
># usemtl Material__1
>f 6 8 5
>f 8 6 7
>f 3 6 2
>f 6 3 7
>f 2 5 1
>f 5 2 6
>f 7 4 8
>f 4 7 3
>f 8 1 5
>f 1 8 4
>f 2 1 9
>f 3 2 9
>f 4 3 9
>f 1 4 9
>
>#end file ************************
>---
>[Message sent by forum member 'aces' (Alessandro Borges)]
>
>http://www.javadesktop.org/forums/thread.jspa?messageID=40933鿥
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
>For additional commands, e-mail: interest-help@java3d.dev.java.net

= = = = = = = = = = = = = = = = = = = =

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

aces
Offline
Joined: 2003-07-17

I was visiting some old source codes and I found it :

[code]
/**
convert Shape3D geometry to IndexedArrayGeometry
**/
public void convert(Shape3D shp)
{
Enumeration enum = shp.getAllGeometries();
while (enum.hasMoreElements())
{
GeometryArray geo = (GeometryArray)enum.nextElement();
shp.removeGeometry(geo);

GeometryInfo gi = new GeometryInfo(geo);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);

IndexedGeometryArray iga = gi.getIndexedGeometryArray(true);

shp.addGeometry(iga);
}
}
[/code]

Please, check GeometryInfo JavaDocs.

I hope it helps.
Alessandro

aces
Offline
Joined: 2003-07-17

Upgrades :D

[code]
/**
* convert Shape3D's geometryArrays using GeometryInfo.
* @param shp - the Shape3D target
* @param indexed - creates a indexed GeometryArray
* @param compact - compact, if indexed.
* @param byRef - create a BY_REFERENCE geometry
* @param interleaved - create a INTERLEAVED geometry
* @param useCoordIndexOnly - force USE_COORD_INDEX_ONLY in indexed Geometries
* @param nio - Use NIO buffers
*/
public void convert(Shape3D shp,boolean indexed,
boolean compact,
boolean byRef,
boolean interleaved,
boolean useCoordIndexOnly,
boolean nio)
{
Enumeration enum = shp.getAllGeometries();
while (enum.hasMoreElements())
{
GeometryArray geo = (GeometryArray)enum.nextElement();
shp.removeGeometry(geo);
GeometryInfo gi = new GeometryInfo(geo);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
GeometryArray ga;
if (indexed)
{
ga = gi.getIndexedGeometryArray(compact,
byRef,
interleaved,
useCoordIndexOnly,
nio);
}
else
{
ga = gi.getGeometryArray(byRef,interleaved,nio);
}
shp.addGeometry(ga);
}
}

/**
* Some Basic info about a Shape3D
* @param shp
*/
public void printInfo(Shape3D shp)
{
Enumeration enum = shp.getAllGeometries();
while (enum.hasMoreElements())
{
Object obj = enum.nextElement();
if (obj instanceof GeometryArray)
{
GeometryArray geo = (GeometryArray)enum.nextElement();
System.out.println("Geometry " + geo.getClass().getName());

int vertexFormat = geo.getVertexFormat();

System.out.println("VertexCount: " + geo.getVertexCount() );
System.out.println("ValidVertexCount: " + geo.getValidVertexCount() );

boolean isReference = bInA(GeometryArray.BY_REFERENCE,vertexFormat) ;
boolean isTC2 = bInA(GeometryArray.TEXTURE_COORDINATE_2,vertexFormat);
boolean isTC3 = bInA(GeometryArray.TEXTURE_COORDINATE_3,vertexFormat);
boolean isTC4 = bInA(GeometryArray.TEXTURE_COORDINATE_4,vertexFormat);
boolean isInterleaved = bInA(GeometryArray.INTERLEAVED,vertexFormat);
boolean isUSE_NIO_BUFFER = bInA(GeometryArray.USE_NIO_BUFFER,vertexFormat);
boolean isUSE_COORD_INDEX_ONLY = bInA(GeometryArray.USE_COORD_INDEX_ONLY,vertexFormat);
boolean isNORMALS = bInA(GeometryArray.NORMALS,vertexFormat);

System.out.println("Is BY_REFERENCE: " + isReference );
System.out.println("Is TEXCOORD2: " + isTC2 );
System.out.println("Is TEXCOORD3: " + isTC3 );
System.out.println("Is TEXCOORD4: " + isTC4 );
System.out.println("Is INTERLEAVED: " + isInterleaved );
System.out.println("Is USE_NIO_BUFFER: " + isUSE_NIO_BUFFER );
System.out.println("Is USE_COORD_INDEX_ONLY: " + isUSE_COORD_INDEX_ONLY );
System.out.println("Has isNORMALS: " + isNORMALS );
}
}
}

/**
* Check if b values is ORed in a
* @param b checking value
* @param a ORed value
* @return true if b is ORed in a
*/
private boolean bInA(int b, int a)
{
return (a & b) == b;
}
[/code]

Alessandro

Matthew Hilliard

To paraphrase, the problem here is that although there are only 9 UNIQUE
vertices, they are stored redundantly because the geometry created isn't
indexed, so you see all 42 (there would be 42 indexes in an indexed
geometry, but only 9 coordinates to index from). Is that correct?

You can translate non-indexed to indexed very easily.
This is a Java 1.5 code block to do it for you, if you need Java 1.4 its
not hard to move it back, its just less convenient:

[pre]
// 42 vertices from the VRML loader
Point3d[] vertices = getNonIndexedVerticesFromShape3D();

// 9 unique coordinates representing the unique VRML vertices
List coordinates = new ArrayList();

// 42 new indices into the unique coordinates
List indices = new ArrayList( vertices.length );

for ( Point3d vertex : vertices ) {
// flag indicating vertex was found in coordinates
boolean match = false;
for ( int i = 0; i < coordinates.size(); i++ ) {
if ( vertex.equals( coordinates.get( i ) ) ) {
indices.add( i );
match = true;
break;
}
}
if ( !match ) {
indices.add( coordinates.size() );
coordinates.add( vertex );
}
}

// at this point you're done the extraction, you can move the
Lists into arrays
// or continue using them as Lists or do with them whatever you like

[/pre]

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

Alessandro Borges

You can convert your geometry to IndexedGeometry using GeometryInfo utility. Check Javadocs.

Alessandro

cs wrote:
Hi,All!

I load a VRML model using VrmlLoader in VRML97.jar.
the geometry node in .wrl file which includes 9 points is as follow:

geometry DEF Bone_LeftUpperArm-FACES IndexedFaceSet {
coord DEF Bone_LeftUpperArm-COORD Coordinate { point [
5 5 5, 5 5 -5, 5 -5 -5, 5 -5 5, 250 0.5 0.5,250 0.5 -0.5, 250 -0.5 -0.5, 250 -0.5 0.5, 0 0 0]
}
coordIndex [
4, 7, 5, -1, 6, 5, 7, -1, 1, 5, 2, -1, 6, 2, 5, -1, 0, 4, 1, -1, 5, 1, 4, -1, 7, 3, 6, -1,
2, 6, 3, -1, 4, 0, 7, -1, 3, 7, 0, -1, 8, 0, 1, -1, 8, 1, 2, -1, 8, 2, 3, -1,8, 3, 0, -1]
}

And in my java3d application, the code I used to retrieve the node is follow:
...
Shape3D myShape=new Shape3D();
myShape= (Shape3D) objTG.getChild(0);
//objTG is a TransformGroup which is the Bone_LeftUpperArm-FACES in .wrl file
GeometryArray g;
g = (GeometryArray) myShape.getGeometry();
int vertexNum=g.getValidVertexCount(); //get the VertexCount,but vertexNum=42,not 9!!!
Point3f[] tt=new Point3f[vertexNum];
for (int i=0;i g.getCoordinates(0,tt);
...

the problem is that in my application the number of vertice is not equal to that of the .wrl file. because in .wrl file the num is 9,while in the j3d application the virable "vertexNum" is 42! For example, in .wrl file there are four points A B C D which make up 2 triangles (ABC, BCD), after it was loaded to java3d I retrained a total of SIX vertices (3 for each triangle). So getVertexCount() returns 6.
In my code above,the 42 vertices are stored in java3d as follow:
4, 7, 5, 6, 5, 7, 1, 5, 2, 6, 2, 5, 0, 4, 1, 5, 1, 4, 7, 3, 6, 2, 6, 3, 4, 0, 7, 3, 7, 0, 8, 0, 1, 8, 1, 2, 8, 2, 3, 8, 3, 0
(the above numbers are the indices of the vertices)

I found VRML loader from Sun does stripify the data.So there will be no relation between the VRML vertex and the J3D one.
In Java3d there is a class "IndexedGeometryArray" which does not stripify the data .If i get a IndexedGeometryArray so the problem will be solved.

..
Shape3D myShape=new Shape3D();
myShape= (Shape3D) objTG.getChild(0);
//objTG is a TransformGroup which is the Bone_LeftUpperArm-FACES in .wrl file
IndexedGeometryArray g; //it is IndexedGeometryArray,not GeometryArray!!
g = (IndexedGeometryArray) myShape.getGeometry();//IndexedGeometryArray!!

but i got a exception:java.lang.ClassCastException.

so How can I obtain the origin vertice coordinates and the index information from the loaded VRML model??

thanks for reply!

regrads.
Martin

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
[att1.html]

cs

Thank Alessandro, a real enthusiastic man!
I had tested the code you offered but the result is not my expected.
I loaded that simple vrml as below:
Shape {
geometry DEF Bone_LeftUpperArm-FACES IndexedFaceSet {
coord DEF Bone_LeftUpperArm-COORD Coordinate { point [
5 5 5, 5 5 -5, 5 -5 -5, 5 -5 5, 250 0.5 0.5,250 0.5 -0.5, 250 -0.5 -0.5, 250 -0.5 0.5, 0 0 0]
}
coordIndex [
4, 7, 5, -1, 6, 5, 7, -1, 1, 5, 2, -1, 6, 2, 5, -1, 0, 4, 1, -1, 5, 1, 4, -1, 7, 3, 6, -1,
2, 6, 3, -1, 4, 0, 7, -1, 3, 7, 0, -1, 8, 0, 1, -1, 8, 1, 2, -1, 8, 2, 3, -1,8, 3, 0, -1]
}
}
when I inserted the function " convert(shape,true,true,true,true,true,true);", the expected number of the points is not 9,but 32!
convert(shape,true,true,true,true,true,true);
indexedGeoArray=(IndexedGeometryArray)shape.getGeometry();
vertexNum=indexedGeoArray.getValidVertexCount(); //not 9,but 32!

it puzzled me...

       

======= 2004-11-26 12:54:00 您在来信中写道:=======

>Upgrades :D
>
>[code]
> /**
> * convert Shape3D's geometryArrays using GeometryInfo.
> * @param shp - the Shape3D target
> * @param indexed - creates a indexed GeometryArray
> * @param compact - compact, if indexed.
> * @param byRef - create a BY_REFERENCE geometry
> * @param interleaved - create a INTERLEAVED geometry
> * @param useCoordIndexOnly - force USE_COORD_INDEX_ONLY in indexed Geometries
> * @param nio - Use NIO buffers
> */
> public void convert(Shape3D shp,boolean indexed,
> boolean compact,
> boolean byRef,
> boolean interleaved,
> boolean useCoordIndexOnly,
> boolean nio)
> {
> Enumeration enum = shp.getAllGeometries();
> while (enum.hasMoreElements())
> {
> GeometryArray geo = (GeometryArray)enum.nextElement();
> shp.removeGeometry(geo);
> GeometryInfo gi = new GeometryInfo(geo);
> NormalGenerator ng = new NormalGenerator();
> ng.generateNormals(gi);
> GeometryArray ga;
> if (indexed)
> {
> ga = gi.getIndexedGeometryArray(compact,
> byRef,
> interleaved,
> useCoordIndexOnly,
> nio);
> }
> else
> {
> ga = gi.getGeometryArray(byRef,interleaved,nio);
> }
> shp.addGeometry(ga);
> }
> }
>
> /**
> * Some Basic info about a Shape3D
> * @param shp
> */
> public void printInfo(Shape3D shp)
> {
> Enumeration enum = shp.getAllGeometries();
> while (enum.hasMoreElements())
> {
> Object obj = enum.nextElement();
> if (obj instanceof GeometryArray)
> {
> GeometryArray geo = (GeometryArray)enum.nextElement();
> System.out.println("Geometry " + geo.getClass().getName());
>
> int vertexFormat = geo.getVertexFormat();
>
> System.out.println("VertexCount: " + geo.getVertexCount() );
> System.out.println("ValidVertexCount: " + geo.getValidVertexCount() );
>
> boolean isReference = bInA(GeometryArray.BY_REFERENCE,vertexFormat) ;
> boolean isTC2 = bInA(GeometryArray.TEXTURE_COORDINATE_2,vertexFormat);
> boolean isTC3 = bInA(GeometryArray.TEXTURE_COORDINATE_3,vertexFormat);
> boolean isTC4 = bInA(GeometryArray.TEXTURE_COORDINATE_4,vertexFormat);
> boolean isInterleaved = bInA(GeometryArray.INTERLEAVED,vertexFormat);
> boolean isUSE_NIO_BUFFER = bInA(GeometryArray.USE_NIO_BUFFER,vertexFormat);
> boolean isUSE_COORD_INDEX_ONLY = bInA(GeometryArray.USE_COORD_INDEX_ONLY,vertexFormat);
> boolean isNORMALS = bInA(GeometryArray.NORMALS,vertexFormat);
>
> System.out.println("Is BY_REFERENCE: " + isReference );
> System.out.println("Is TEXCOORD2: " + isTC2 );
> System.out.println("Is TEXCOORD3: " + isTC3 );
> System.out.println("Is TEXCOORD4: " + isTC4 );
> System.out.println("Is INTERLEAVED: " + isInterleaved );
> System.out.println("Is USE_NIO_BUFFER: " + isUSE_NIO_BUFFER );
> System.out.println("Is USE_COORD_INDEX_ONLY: " + isUSE_COORD_INDEX_ONLY );
> System.out.println("Has isNORMALS: " + isNORMALS );
> }
> }
> }
>
> /**
> * Check if b values is ORed in a
> * @param b checking value
> * @param a ORed value
> * @return true if b is ORed in a
> */
> private boolean bInA(int b, int a)
> {
> return (a & b) == b;
> }
> [/code]
>
>Alessandro
>---
>[Message sent by forum member 'aces' (Alessandro Borges)]
>
>http://www.javadesktop.org/forums/thread.jspa?messageID=40618麪
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
>For additional commands, e-mail: interest-help@java3d.dev.java.net

= = = = = = = = = = = = = = = = = = = =

---------------------------------------------------------------------
To unsubscribe, e-mail: interest-unsubscribe@java3d.dev.java.net
For additional commands, e-mail: interest-help@java3d.dev.java.net

aces
Offline
Joined: 2003-07-17

Did you try to load it as WaveFront obj instead VRML ?

#start arm.obj file *************
# Wavefront OBJ file
#
# mtllib arm.mtl
# object Bone_LeftUpperArm-FACES

g Bone_LeftUpperArm_FACES
v 5 5 5
v 5 -5 5
v 5 -5 -4
v 5 5 -4
v 250 0.5 1.5
v 250 -0.5 1.5
v 250 -0.5 0.5
v 250 0.5 0.5
v 0 0 0

# 9 verticies
# usemtl Material__1
f 6 8 5
f 8 6 7
f 3 6 2
f 6 3 7
f 2 5 1
f 5 2 6
f 7 4 8
f 4 7 3
f 8 1 5
f 1 8 4
f 2 1 9
f 3 2 9
f 4 3 9
f 1 4 9

#end file ************************