We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
Page Index Toggle Pages: 1
Save as 3ds (Read 1947 times)
Save as 3ds
Jul 28th, 2007, 2:36pm
 
I just started working on a 3ds filesaver, so the 3D model I created in processing can be saved as 3ds, then imported into wings3D or Google earth sketchup etc.

Found information on the 3ds file format on
http://www.wotsit.org/

There seem to be lot of opensource written 3ds loaders, but could not find any 3ds saver yet.

My first attempts will be saving a triangle.

-Work in Progress- update #0.4

-edit- working code is posted now below -edit-

This is the first time I'm using the saveBytes routine, and stuff I still got to figure out is like how to convert the word(2 bytes) and floats (4 bytes) and calculating the chunk length.
Re: Save as 3ds
Reply #1 - Jul 28th, 2007, 3:23pm
 
elout, if you have 3dsmax, check the sdk it has a 3ds imp/exp
along with others like .ase
you might find it very helpful
Re: Save as 3ds
Reply #2 - Jul 28th, 2007, 4:52pm
 
I don't have 3Dmax and using Wings3D and a hex-editor at the moment to analyze the 3ds files. For me it's important to save a 3ds file created in processing.

Just figured out how the ox4110 chunk works.
Still gotta lookup how I can split a float into 4 different bytes, or a word into 2 different bytes.
And ofcourse get the other chunks working.
Re: Save as 3ds
Reply #3 - Jul 28th, 2007, 6:06pm
 
why split a float into 4 bytes ?
Re: Save as 3ds
Reply #4 - Jul 28th, 2007, 6:55pm
 
Updated: wings crashed on this 3ds file, and sketchup cant load it eather, anyway still fiddeling with it, maybe will add more information like objectname etc.

Crmx > I use the saveBytes routine, so somehow I got to convert a float into 4 seperate bytes in this array.
Re: Save as 3ds
Reply #5 - Jul 29th, 2007, 1:55am
 
for this situation, i'd recommend using java's DataOutputStream class rather than saveBytes. it'll mean a lot less maintenance along the way because you can just write the file linearly. it would go something like this:

String path = savePath("filename.3ds");
FileOutputStream fos = new FileOutputStream(path);

then you'd use fos.writeInt() or fos.writeFloat() to write individual bits of info.
Re: Save as 3ds
Reply #6 - Jul 29th, 2007, 2:37pm
 
Simple 3ds saver - Version #0.7
Saves 2 triangles now you can upload in wings3D or sketchup etc.

I split it up in 2 parts, since the message will be too big, and cant post it then on the forum

--------------------------Part 1--------------------
Code:

// simple .3ds saver - Elout de Kok 2007 - update #7
// info on 3ds fileformat - http://www.wotsit.org/list.asp?fc=2

void setup()
{
save3ds();
println("saved the 3ds-file");
}

void save3ds()
{
int number_of_points=4;
int number_of_triangles=2;

float [] xyzpoints = {-10.0f,-5.0f,1.0f, 10.0f,-5.0f,1.0f, 1.0f,10.0f,1.0f, -1.0f, -4.0f, -10.0f};
int [] vertexes = {0,1,2, 1,3,2};


int [] mesh_version = {0x3D3E, 0x000A, 0x0000,0x0003,0x0000,0xAFFF,0x0080, 0x0000, 0xA000, 0x000E, 0x0000, 0x6564, 0x6166,0x6C75, 0x0074, 0xA030, 0x0018, 0x0000, 0x0011, 0x0009, 0x0000, 0xFFFF, 0x12FF, 0x0900, 0x0000, 0xFF00, 0xFFFF, 0xA040, 0x000E, 0x0000, 0x0030, 0x0008, 0x0000, 0x0000, 0xA020, 0x0018, 0x0000, 0x0011, 0x0009, 0x0000, 0xFFFF, 0x12FF, 0x0900, 0x0000, 0xFF00, 0xFFFF, 0xA050, 0x000E, 0x0000, 0x0030, 0x0008, 0x0000, 0x0000, 0xA010, 0x0018, 0x0000, 0x0011, 0x0009, 0x0000, 0xFFFF, 0x12FF, 0x0900, 0x0000, 0xFF00, 0xFFFF, 0xA100, 0x0008, 0x0000, 0x0003, 0x0100, 0x000A, 0x0000, 0x0000, 0x3F80};
int [] chunk_4160 = {0x4160, 0x0036, 0x0000, 0x0000, 0x3F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3F80, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000};

int totalbytes=
6 // 0x4D4D Main chunk
+10 // header data
+148 // 0x3D3E Mesh version
+ 6 // 0x3D3D 3D editor chunk
+ 6 // 0x4000 Object block (with name of your object)
+ 6 // name
+ 6 // 0x4100 Triangular mesh
+ 54 // 4160 matrix chunk
+ ((number_of_points*3)*4)+4+4 // ox4110 points 44
+ ((number_of_triangles*8)+4+4) // ox4120 faces 16
+ 16 + (number_of_triangles*2) // 4130 material
+ 6+(number_of_triangles*4); // 4150 smoothing groups

byte[] nums = new byte[totalbytes]; // for the moment

int step=0;

writeshort(nums, step, (short) 0x4D4D); step+=2; //main chunk
writeshort(nums, step, (short) totalbytes); step+=2; //size of next chunks
writeshort(nums, step, (short) 0); step+=2;

writeshort(nums, step, (short) 0x0002); step+=2; // header data
writeshort(nums, step, (short) 0x000A); step+=2;
writeshort(nums, step, (short) 0x0000); step+=2;
writeshort(nums, step, (short) 0x0003); step+=2;
writeshort(nums, step, (short) 0x0000 ); step+=2;

writeshort(nums, step, (short) 0x3D3D); step+=2; //3D editor chunk
writeshort(nums, step, (short) (totalbytes-16) ); step+=2; //size of next chunks
writeshort(nums, step, (short) 0); step+=2;

for (int i=0;i<mesh_version.length;i++)
{
writeshort(nums, step, (short) mesh_version[i]); step+=2; //0x3D3E Mesh version
}

writeshort(nums, step, (short) 0x4000); step+=2; //Object block chunk
writeshort(nums, step, (short) (totalbytes-170) ); step+=2; //size of next chunks
writeshort(nums, step, (short) 0); step+=2;

writeshort(nums, step, (short) 0x7563); step+=2; //write name
writeshort(nums, step, (short) 0x6562); step+=2;
writeshort(nums, step, (short) 0x0031); step+=2;



Re: Save as 3ds
Reply #7 - Jul 29th, 2007, 2:37pm
 
--------------------------Part 2--------------------
Code:


writeshort(nums, step, (short) 0x4100); step+=2; //Triangular mesh chunk
writeshort(nums, step, (short) (totalbytes-182) ); step+=2; //size of next chunks
writeshort(nums, step, (short) 0); step+=2;

for (int i=0;i<chunk_4160.length;i++)
{
writeshort(nums, step, (short) chunk_4160[i]); step+=2; //0x4160 matrix chunk
}

writeshort(nums, step, (short) 0x4110); step+=2; //Vertices chunk

int vertice_blocksize=((number_of_points*3)*4)+4+4; //((3*xyz)*float_4bytes) +no of points = 36 + 4 + 4 == 44

writeshort(nums, step, (short) vertice_blocksize); step+=2; //Vertices chunk
writeshort(nums, step, (short) 0); step+=2;
writeshort(nums, step, (short) number_of_points); step+=2; // no of points

int pointstep=0;
for (int i=0;i<number_of_points;i++)
{
writefloat(nums, step, xyzpoints[pointstep++]); step+=4; // x
writefloat(nums, step, xyzpoints[pointstep++]); step+=4; // y
writefloat(nums, step, xyzpoints[pointstep++]); step+=4; // z
}

writeshort(nums, step, (short) 0x4120); step+=2; //Faces chunk

int face_chunksize = (number_of_triangles*8)+4+4 +(16+(number_of_triangles*2))+ (6+(number_of_triangles*4));

writeshort(nums, step, (short) face_chunksize); step+=2; // chunk block size
writeshort(nums, step, (short) 0); step+=2;
writeshort(nums, step, (short) number_of_triangles); step+=2; // number of triangles

int vertexpos=0;
for (int i=0;i<number_of_triangles;i++)
{
writeshort(nums, step, (short)vertexes[vertexpos++]); step+=2;//1st triangle
writeshort(nums, step, (short)vertexes[vertexpos++]); step+=2;//2nd triangle
writeshort(nums, step, (short)vertexes[vertexpos++]); step+=2;//3nd triangle
writeshort(nums, step, (short)0x0007); step+=2;//flags: all visible
}

writeshort(nums, step, (short) 0x4130); step+=2; //Faces material list
writeshort(nums, step, (short) (16+(number_of_triangles*2)) ); step+=2; //size of chunk
writeshort(nums, step, (short) 0x0000); step+=2;
writeshort(nums, step, (short) 0x6564); step+=2;
writeshort(nums, step, (short) 0x6166); step+=2;
writeshort(nums, step, (short) 0x6C75); step+=2;
writeshort(nums, step, (short) 0x0074); step+=2;
writeshort(nums, step, (short) number_of_triangles); step+=2; // number of faces
for (int i=0;i<number_of_triangles;i++)
{
writeshort(nums, step, (short) i); step+=2;
}

writeshort(nums, step, (short) 0x4150); step+=2; // Smoothing groups
writeshort(nums, step, (short) (6+(number_of_triangles*4)) ); step+=2; // size of chunk
writeshort(nums, step, (short) 0x0000); step+=2;

for (int i=0;i<number_of_triangles;i++)
{
writeshort(nums, step, (short) 0x0001); step+=2;
writeshort(nums, step, (short) 0x0000); step+=2;
}

saveBytes("Test01.3ds", nums); // save file

}

void writeshort(byte output[], int position, short value)
{
byte b1 = (byte) (value & 0xff);
byte b2 = (byte) ((value >> 8) & 0xff);
output[position]=b1;
output[position+1]=b2;
}

void writefloat(byte output[], int position, float value)
{
int float_to_int=Float.floatToIntBits(value);
byte b1 = (byte) (float_to_int & 0xff);
byte b2 = (byte) ((float_to_int >> 8) & 0xff);
byte b3 = (byte) ((float_to_int >> 16) & 0xff);
byte b4 = (byte) ((float_to_int >> 24) & 0xff);
output[position]=b1;
output[position+1]=b2;
output[position+2]=b3;
output[position+3]=b4;
}

Re: Save as 3ds
Reply #8 - Jul 29th, 2007, 2:47pm
 
Thanks for the tips, and Fry I tried DataOutputStream, but somehow saving short or floats. Resulted that they shown at wrong place in the 3ds data. Like 0000 ffff <-instead of-> ffff 0000
Re: Save as 3ds
Reply #9 - Jul 29th, 2007, 6:36pm
 
ah, that's an endian issue.. java uses motorola or "network" byte ordering, as opposed to intel/x86 byte order that has things flipped around backwards. to fix this you can find a "little endian" version of dataoutputstream on the net.

...or you can use the saveBytes() model, it's just that it's less fun when you have to do that much work to babysit the byte placement into the array.
Re: Save as 3ds
Reply #10 - Jul 29th, 2007, 10:17pm
 
Well I'm glad I got it somehow to work now, but next will be saving more complex 3d models with 1000th+ of points and X ammount of faces, and hope it it still works. but that's more a thing for tommorow, and not today.

I used a hex editor, to explore the different chunks/3D models and data, saved by wings3d, not sure several chunks can be left out. But for me it was important to succesfull load the model in google-sketchup and wings3D the same time, without a crash or error message.
Re: Save as 3ds
Reply #11 - Jul 30th, 2007, 1:22am
 
If you're looking to load into Wings3D, then .obj will be much much easier, since it's plain text.
Re: Save as 3ds
Reply #12 - Jul 30th, 2007, 3:09am
 
For me the main focus was saving it as 3ds; so google sketchup users can import 3D-models I created with processing.
Re: Save as 3ds
Reply #13 - Jul 31st, 2007, 12:13am
 
elout wrote on Jul 30th, 2007, 3:09am:
For me the main focus was saving it as 3ds; so google sketchup users can import 3D-models I created with processing.


If SketchUp, then why not use DXF  The included library does work, and SketchUp will load those DXF's without error.  If you're bothered by the difference in coordinate systems you can try this modified version instead: http://www.davebollinger.com/works/p5/rawdxf_rhzu/

It should also work well for 3dsMax, for example: http://www.flickr.com/photos/davebollinger/877869639/
Re: Save as 3ds
Reply #14 - Aug 5th, 2007, 1:08am
 
Thanks Davbol for the tip, to be honest never worked with dxf before, and it seems to work even better/easier.
Page Index Toggle Pages: 1