Preserving material groups in .obj Export
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 16/06/2004 at 13:47, xxxxxxxx wrote:
User Information:
Cinema 4D Version: 7.3
Platform: Windows ;
Language(s) : C++ ;---------
This may turn into a long question...
Problem:
C4D .obj Export routines (XL v7.3) seem to support the 'usemtl' labels when it Imports .obj files, but when you Export an .obj file, it ignores all the restriction tags and collapses all facets into the first material (Texture Tag) listed for any particular mesh.
Example:- Create an editable cube. - Create 6 materials (well, more than one) - Create a selection for each face of the cube (more than one face/selection grouping). - Assign the materials to the faces using the "Restrict to selection" option in the Texture dialog. - Export the cube as a Wavefront .obj file - Import that file. - Note that all of your materials except for the first one are now missing.
Discussion:
I am currently modelling a human character that will be used in other applications (Poser, for example). The main body, including the head is all one mesh. Within that mesh, I have designated multiple material areas that will use different textures/settings including: lips, nostrils, nipples, head skin, body skin, fingernails, toenails, eye sockets, etc. However each time I export my mesh for testing, I lose all of those material selections and everything gets glommed into the "lips" material (for example).
This is becoming a hassle for me, as I have to re-create all of my material selections using some external application (which is very difficult and/or tedious, since the exported mesh now has some tiny mesh-smoothed polys in hard to reach places).
I do have some material groupings which are part of disconnected meshes (eyebrows, eyelashes, teeth, tongue, eye balls, etc) so those are ok, but even with things like the eyes, if I want separate material groupings for the lens, iris, pupil, eye white, they would all have to be separate/disconnected meshes in order to use more than one material.
Solution(s) :
a). separate each material grouping into a new mesh, so it can have it's own material when exported. Then weld the seams back up in some external app (UV Mapper, for example).
b). continue using the lengthy/tedious process I've been using (involving more than one external app) to re-create the groupings each time.
c). write my own .obj Export plugin that preserves material groupings.
Option 'a' would work, but I'm not particularly fond of that because it would mess up my workflow within C4D (I'd have duplicate vertices along grouping edges to worry about, among other issues).
Option 'b' sucks.
And that leaves option 'c'. I guess the first question is - Has anyone already written a plugin that does what I need?
If not, that brings me to the implementation... I'm a (somewhat rusty now) C/C++ programmer, I have the SDK with the example STL writer code, I'm very familiar with the .obj file format and have sample code (from another project of mine) to write .obj format files.
I have spent a little bit of time looking into how I would go about the task, but am unclear on some issues. Here's basically what I want/need to do:From the BaseDocument, do a Polygonize() to make things simple. Itterate through the obects (separate meshes) and for each mesh: { create a 'default' material itterate through the Texture Tags and for each Texture/material: { if the Texture Tag is not restricted to a selection and I don't already have one yet: { make this the 'default' material. } else if the Texture Tag is restricted to a named selection: { retrieve the named Selection Tag and if it's a selection of polygons and not points [and assuming I can tell the difference]: { write out a new "usemtl" record in the .obj file for this material for each poly listed within that selection: { if this poly hasn't been written before: { write out an "f" (facet) record in the .obj file mark this poly as being written (each polygon can only belong to one material grouping in an .obj file, but polys can live in more than one C4D selection) } } } } } itterate through the polygon list (GetPolygonCount()/GetPolygon(), etc) and for each polygon: { if this poly hasn't been written before: { if I hadn't already done so: { write out a new "usemtl" record in the .obj file for the 'default' group } write out an "f" (facet) record in the .obj file } }
...or something like that ;).
Anyway, my questions are:- Suggestions for itterating through the TextureTags?
- Once I have a TextureTag, how do I get to the TextureKey?
- And, more importantly, how do I get the TEXTUREKEY_RESTRICTION data?
- Once I have a non-null string value from TEXTUREKEY_RESTRICTION, how would I go about finding the associated SelectionTag? and...
- How can I tell if it's a selection of polys vs a selection of points?
I guess that's enough questions for now... as you can tell, most of them are related to and prompted by my rusty C++ skills. Any help would be appreciated.
Thanks![there's no preview button that I see here, so I hope this formats ok..]
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 16/06/2004 at 13:51, xxxxxxxx wrote:
Sorry for the really long lines... ;(
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/06/2004 at 19:51, xxxxxxxx wrote:
1. You can use
TextureTag* ttag = NULL; LONG ttagi = 0; while (ttag = static_cast<TextureTag*>(BaseObject::GetTag(Ttexture, ttagi++))) { // do something with the ttag }
2/3. I don't see where texture keys come into it, unless you need to support animation of the restriction (in that case, use AnimateObject()). I assume you're looking for
String restr = ttag->GetDataInstance()->GetString(TEXTURETAG_RESTRICTION);
4. You could use
SelectionTag* stag = NULL; LONG stagi = 0; while (stag = static_cast<SelectionTag*>(BaseObject::GetTag(Tpolygonselection, stagi++)) && stag->GetName() == restr) {} if (stag) { // poly selection matching restr found, use stag }
Btw, if you use another browser than Internet Explorer, the forum does have a "Preview Post" function. I don't know of any way to enable it in IE, since the forum thinks that IE supports WYSIWYG editing.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 18/06/2004 at 11:16, xxxxxxxx wrote:
Thanks Mikael, that looks like just what I was looking for.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/06/2004 at 18:20, xxxxxxxx wrote:
...except that it doesn't all work ;). Basically, where I'm stuck now is the lack of information about SelectionTags. It doesn't have a GetName() function, or any other means of finding the name of the tag, that I can find, at least (maybe I need an updated SDK?).
If anyone can tell me how to find the string 'name' of a polygon selection tag, I'd appreciate it. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/06/2004 at 19:12, xxxxxxxx wrote:
Ok, I checked and I do have the latest v7.303 based SDK, so that's no help so far.
I'm sure there's some way to get the name string of a selection tag - I just need some help figuring it out.
Thanks. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/06/2004 at 21:59, xxxxxxxx wrote:
Sorry, I didn't notice you were using 7.3. Back then tags didn't have names, so the poly selection name was stored in stag->GetDataInstance()->GetString(POLYSELECTIONTAG_NAME);.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/06/2004 at 22:10, xxxxxxxx wrote:
Thanks for the reply... I actually found it a few minutes ago with:
stag->GetData().GetString(POLYSELECTIONTAG_NAME);
...I assume that's a valid thing to do?
Anyway, my code seems to be working so far, but now I'm trying to get at the UVW data (texture vertices). I was hoping to be able to grab an array of texture coordinates (like I did for the vertices with the baseobj->GetPoint() call) and an array of indices (like the polygon vertex indices), but it looks like I have to get the individual texture coordinates (UVWStructs) for every polygon. This means that I'd end up with tons and tons of duplicates and would need to compact them myself, if I wanted to make it lookup-based (like a wavefront .obj file format). Am I correct?
Thanks again for the help. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/06/2004 at 23:11, xxxxxxxx wrote:
Sorry, I don't think there are any shortcuts.