Red-i Productions Presents:
Riptide v1.0
Wavefront .Obj Import/Export Plugin
for Maxon's Cinema 4D

Copyright © 2004 by Keith Young
(a.k.a. Spanki)
http://www.skinprops.com

Aug. 06, 2004

Table of Contents:

  • Introduction
  • End User License
  • Disclaimer
  • Revision History
  • Requirements
  • Installation
  • Detailed File List
  • Usage Information, Notes and Tips
  • Background
  • C4D .obj Export Issues
  • C4D .obj Import Issues
  • Implementation
  • Group Tag
  • Region Tag
  • Tag implementation/background
  • .obj Export Plugin
  • .obj Import Plugin
  • Wavefront .mtl file notes
  • Limitations
  • Acknowledgements
  • Final Comments
  •  

    Introduction

    I got frustrated by the inflexible way that C4D handles .obj files and decided that I could do a better job of it - this plugin package is the result...

    Included in this package is a "Wavefront .obj File Format Import/Export Filter Plugin". The current plugin consists of 2 new tags - a "Group Tag" and a "Region Tag" used to (optionally) specify 'Groups' and 'UVMapper Regions', along with the Import and Export filters with extensive output/formatting options. The plugin was written for/using the v7.303 and v8.5 C++ SDKs (PC ONLY - sorry) and has been tested in C4D v7.303, v8.207 and v8.503.

    See the "Usage Information, Notes and Tips" section below for operational details and background information.

    [top]

    End User License

    While this package and contents are being distributed free of charge, it remains Copyright © by Keith Young. You are free to use this package on one or many installations, but you may not decompile or otherwise reverse-engineer this product or use any parts of it in your own products. You are free to distribute the package provided no fee is charged over and above the cost of the delivery medium (ie. the nominal price of a CD and postage) and that the package and all contents including copyright notices remain intact, as published. Any questions regarding this license can be directed to: * Click Here *

    [top]

    Disclaimer

    While every effort has been made to insure the intended and safe operation of this utility and there are no known disastrous error conditions, we can not anticipate every situation and therefore can not guarantee 100% error-free operation. By using this software, the user agrees not hold Red-i Productions, it's employees or agents or Keith Young responsible for any loss of work, loss of time, mental stress, or any other actual or perceived damages caused by the use of this software. In short, this utility comes with NO WARRANTEE, EITHER EXPRESSED OR IMPLIED - USE AT YOUR OWN RISK.

    [top]

    Revision History

    v1.0

    • First release version.

    [top]

    Requirements

    To fully utilize this package you will need the following:

    • Cinema 4D v7.303 or later.
    • A desire for more flexibility in your .obj file output ;).

    [top]

    Installation

    This plugin is currently written for two main versions of Cinema 4D...

    • The archive named "riptide_v7x.zip" is designed to be used in C4D v7.3 as well as C4D v8.0/v8.1/v8.2 versions.
    • The archive named "riptide_v85.zip" is designed to be used in C4D v8.5 or later versions.

    1. Copy the appropriate zip file into the "Plugins" folder of your C4D installation and unzip it there.
    2. A new "Riptide" folder will be created, with everything needed to run the plugin.
    3. Restart the C4D application to load the new plugin(s).
    4. See the "Usage Information, Notes and Tips" section below for usage details.

    [top]

    Detailed File List

    ..\Riptide\
      Riptide.cdl
      Riptide_Readme.txt
    
    ..\Riptide\res\
      redilogo.tif
      RegionTag.tif
      GroupTag.tif
      c4d_symbols.h
      riptide.tif
    
    ..\Riptide\res\dialogs\
      dlg_grouptag.res
      dlg_regiontag.res
      dlg_impfile.res
      dlg_expfile.res
    
    ..\Riptide\res\strings_us\
      c4d_strings.str
    
    ..\Riptide\res\strings_us\dialogs\
      dlg_grouptag.str
      dlg_regiontag.str
      dlg_expfile.str
      dlg_impfile.str
    
    ..\Riptide\res\strings_de\
      c4d_strings.str
    
    ..\Riptide\res\strings_de\dialogs\
      dlg_grouptag.str
      dlg_regiontag.str
      dlg_expfile.str
      dlg_impfile.str
    
    ..\Riptide\res\strings_fr\
      c4d_strings.str
    
    ..\Riptide\res\strings_fr\dialogs\
      dlg_grouptag.str
      dlg_regiontag.str
      dlg_expfile.str
      dlg_impfile.str

    [top]

    Usage Information, Notes and Tips

    Background

    I guess I should start by describing some of the reasoning/issues behind writing this plugin... I primarily use C4D to produce clothing/props/models to be used in Poser. Poser supports several 3D formats, but I'm very familiar with the Wavefront .obj format, it's very flexible, it's ASCII (easily accessible) and it's become the somewhat de facto standard among Poser artists. However, C4D's implementation of the format leaves some things to be desired...

    [top]

    C4D .obj Export Issues

    • All 'materials' from a particular mesh are condensed and combined into the first material listed on the mesh. This is probably the biggest problem I continually ran into. I might have a dozen or more material selections defined on a single mesh (skinhead, lips, nostrils, eyesockets, innermouth, gums, skinbody, fingernails, toenails, nipples, etc), but when I export the model, I was LOSING all of those material selections and had to recreate them using some external application (UVMapper, for example). It's very easy to define these selections within C4D and can be quite a pain to do in other applications... so losing them all on export sucks.
    • No real 'group' support and/or inflexible group support, where it exists. Basically, C4D creates ONE group record for each 'mesh' (a separate group of polygons) contained in the document and the group name is basically made up from all of the grouping hierarchy used within the C4D tree, so you might end up with something like:

      Hyper_NURBS:Symmetry:Eye_Base:Left_Eye

    ...as a group name in the .obj file (note that the ':'s are added by C4D on import - they are spaces in the .obj file).

    This is perfectly valid and probably a reasonable approach (C4D is a general-purpose 3D editor and not designed around the .obj file format), but the file format allows for MULTIPLE groups per mesh, which can all share the same set of vertices (see the import section below for additional issues related to this).

    Anyway, a typical Poser humanoid character might have dozens of groups within the same 'mesh' (head, neck, chest, abdomen, hip, left collar, right collar, left shoulder, right shoulder, left forearm, right forearm, lots-o-finger-segments, you get the idea...). Short of creating separate 'meshes' for each of these 'groups', there's no way of defining them within C4D currently.

    • Normals are 'reversed'. This one is no big deal really... they had to pick a direction, but the one they picked doesn't happen to coincide with Poser's idea of which way they should face (or even C4D's, for that matter, so I guess they get a 'bonk' for this one as well ;). Anyway, the normals can be flipped around on import to Poser, export from UVMapper or prior to export in C4D, but the new plugin makes it easy to get it right to start with.
    • No support for UVMapper 'regions'. As far as I know, 'regions' are something Steve Cox (author of UVMapper) came up with and implemented as an extension to the .obj format (using comment fields), so this issue is clearly not an omission with the C4D code, but I thought it would be handy to be able to define these while modelling, to help with UV Mapping and layout later on (these 'regions' are just another way of grouping polygons together, but they are separate from and can 'span' across group boundaries, which makes them very useful).

    [top]

    C4D .obj Import Issues

    • Material import... while C4D drops the ball on exporting materials, it actually does retain/recreate the proper polygon selections on import. I guess my only real issues/complaints here is the choice of naming of those selections ("Selection 1" .. "Selection 2" .. "Selection 3", etc.). Why not just use the material name(s)? And the fact that it makes no attempt to actually read the .mtl file and reproduce any of the desired material settings.
    • Groups. This is a tough one and I can't really cast to much blame for this one. Programmatically, it's very difficult (very time-comsuming, at the least) to determine the 'intent' of how a .obj file should be broken up upon import into separate meshes. There are a couple of obvious choices...

    a) create one big mesh, and create polygon selection tags for each 'group' record.
    b) create a separate mesh for each group record.

    ...C4D chose option 'b'. Unfortunately, neither of those options is optimal in all situations, though option 'a' would have been less 'destructive'. By that, I'm referring to the fact that implementing option 'b' means creating new vertices at the seams between what used to be group selections of the same mesh. This can screw up vertex ordering, for things like morph files.

    • Loss of UVMapper regions. Again, I'm not casting blame on this one, but an import filter could preserve (recreate) these as polygon selections.
    • Lack of additional import options. There are no options to flip normals or textures or.. well, any options, aside from
      the scaling factor.

    [top]

    Implementation

    Ok, so now you know some of the issues I was trying to address and while I was at it, I came up with some additional features to add flexibility. The plugin itself is made up of two new Tags, as well as an Import and Export plugins. Below I will describe the role and function of each.

    Group Tag

    This is a new tag that can be attached to your polygonal mesh objects (Editable Meshes). To add one, right-click on the mesh name in the Objects Tab, then select "New Tag->Plugin Tags->Group Tag" (or just "New Tag->Group Tag" in v8.x) from the menu. A dialog will open, displaying all available/current (and named, btw) 'Polygon Selection Tags'. You can move these from the 'Available' to the 'Selected' list (and back) by highlighting them with the mouse and clicking on the appropriate arrow gadgets.

    By moving a selection to the 'Selected' list, you are basically defining that polygon selection as a 'Group'. The export filter will scan this list of selections and create the appropriate group records within the .obj file. The tag itself will be saved/loaded with your .c4d file.

    [top]

    Region Tag

    This new tag functions identically to the Group Tag outlined above. To add one, right-click on the mesh name in the Objects Tab, then select "New Tag->Plugin Tags->UVM Region Tag" (or just "New Tag->UVM Region Tag" in v8.x) from the menu.

    By moving a selection to the 'Selected' list, you are basically defining that polygon selection as a 'UVMapper Region'. The export filter will scan this list of selections and create the appropriate region records within the .obj file.

    [top]

    Tag implementation/background

    The polygon selection tags in C4D are a pretty good match for material/group/region selections in a .obj file, but there are some differences you should be aware of. The primary difference is that while individual polygons may exist in more than one C4D selection (overlap), they may only exist in ONE .obj file material/group/region selection. The same polygon can be in one material AND one group AND one region, but it can't be in more than one of each type. This is accounted for in the code by assigning each polygon to the first selection it exists in (for each selection type - material/group/region).

    For example, let's say that you have a humanoid model, with a 'Body' C4D selection tag, that encompasses every polygon of the mesh. You also have a 'hip' C4D selection tag that only contains polygons that make up the hip area. Suppose you want to create 'Group' records for each of these selections... obviously, there is overlap between the selections, so if the 'Body' selection is listed before (to the left of) the 'hip' selection, ALL of the polygons will go into the 'Body' group and the 'hip' group will be lost. To get around this problem, you could either move the 'hip' C4D selection tag ahead (to the left) of the 'Body' tag, or remove the hip polygons from the Body selection.

    I hope that makes sense... you only need to worry about overlap within the same type of group (a UVMapper Region could encompass/span several 'groups', for example, which is why they are useful to begin with ;).

    Other considerations:

    • selections must be NAMED to show up as 'Available' in the assignment dialogs.
    • selections that are deleted or renamed after being added to the group/region lists are not removed/updated in those lists, which won't hurt anything, but you'll have to update them manually to get the expected results.

    [top]

    .obj Export Plugin

    Once the plugin is installed, a new option shows up in the Plugins menu, named "Riptide". One of it's sub-menus is named ".Obj Exporter". After selecting a filename, an export options dialog will appear. Below is a description of each option...

    • Scale Factor:
      This is used for scaling the output mesh and should be set to the same value as the C4D .obj import/export value.
    • Export Normals (only available in the v8.5 plugin)
      IF your model has C4D Normal Tags, enabling this option will save those Normals to the output .obj file. If no Normal Tags are found, no Normals are saved.
    • Export Faces
      You can choose to export the polygon faces or not (morph files don't need faces, just vertices, for example). Also enables the additional Face Sorting options...
      • C4D Ordering
        Writes out the facet (polygon) records in the order encountered in the C4D in-memory image.
      • Sort By Material
        Sorts facets (within each mesh) based on the material groups.
      • Sort By Group
        Sorts facets (within each mesh) based on the Group Tag selections.
      • Sort By Region
        Sorts facets (within each mesh) based on the Region Tag selections.

    ...just as background, it doesn't adversely affect anything to change the 'order' facets are listed in the .obj file (unlike vertex ordering, which can redefine things to the extent that may break things like morph files). There are a couple of reasons that you might want to sort them differently, and most of them have to do with aesthetics (.obj files are
    human-readable ASCII text files) or file-size, but may also be relevant for application implementers who prefer a particular ordering.

    When you start adding group and material information to a .obj file, anytime a facet (polygon) belongs to a different group, material or region, you have to write out a new record before the facet record. So you can imagine that if you have a humanoid model with 50+ groups and a dozen or so materials, if you just start writing out facets based on the order they may have been created in C4D, you might constantly be writing out a new group or material record every few lines as the list meanders around through the mesh. Generally, you can produce a smaller (and more human-readable) file by sorting them by Group (if there's more groups than materials) or by Material (if there's more materials than groups). Just as an aside, you can still sort by Group, Material or Region, even if you're not exporting that particular record type (though it may or may not ultimately be non-meaningful to do so ;).

    • Reverse Faces
      This reverses the winding order of the polygons (in effect, changing the direction that the 'Normals' point), which changes the direction that the polygons face. Since C4D itself uses the opposite face direction for determining backface culling, you should pretty much always leave this option selected.
    • Export UV Coords
      UV (sometimes called UVW) Coordinates are basically the texture coordinates... you can choose to export these or not.
    • Flip UV Horizontally/Vertically
      If your textures show up upside-down or flipped left->right in whatever external application you use, you can use these options to flip them around.
    • Export Materials
      Enable/Disable saving material groups. Note that these groups are saved based on the materials/selections you have set up in C4D. To get the expected results, you really should use the 'Restrict to Selection' feature of the material dialog and re-read the text above about overlapping selections if you run into problems. As implemented, a "default" material record will be written to hold any polygons that don't belong to any other material group.
    • Export Groups
      This option determines whether any group records are written to the exported file and also enables the additional group options on the dialog...
      • Mesh Names
        Determines whether the mesh names are written to the file (default C4D behavior is to write out the mesh names as groups).
        • As groups
          Mimic C4D .obj export functionality
        • As UVMapper Regions
          Write the mesh names out as UVMapper Regions instead of Groups (without using any Region tags, you can still create 'region wrappers' around the separate meshes being saved).
      • Group Tag Names
        Determines whether the list of selections in the Group Tag(s) are saved as group records. As implemented, a "default" group record will be written to hold any polygons that don't belong to any other group.
      • Preserve Hierarchy
        Using the example given earlier, would produce "Hyper_NURBS:Symmetry:Eye_Base:Left_Eye" when enabled or just "Left_Eye" as a group name if disabled.
    • Export Regions
      Determines whether the list of selections in the Region Tag(s) are saved in the output file. As implemented, a "default" region record will be written to hold any polygons that don't belong to any other region.

    [top]

    .obj Import Plugin

    The other sub-menu of the new "Plugins->Riptide" menu is ".Obj Importer". This feature will allow you to import either a Wavefront format ".obj" mesh file or a Wavefront format ".mtl" material file (importing a .obj file can also import the specified .mtl file... see below for details).

    If a .mtl file is selected, that file is read any existing materials in the active document that are named the same are updated with the new information. New materials are created for any uniquely named materials found in the file. If a .obj file is selected, an Import Options dialog will open, with the following options...

    • Scale Factor:
      This is used for scaling the input mesh and should normally be set to the same value as the C4D .obj import/export value.
    • Import Normals (only available in the v8.5 plugin)
      If Normals exist in the .obj file, C4D Normal Tags will be created using that information. If no Normals exist in the file, no Normal Tags are created.
    • Import Groups
      - Selection tags are created for any Groups within the mesh and a 'Group Tag' is created and set up to track them.
      - If disabled, no Group Selections or Group Tags will be created (note that even if this option is disabled, you can still "Split by Group" and get separate meshes, who's names are the group names).
    • Import Regions
      - Selection tags are created for any UVMapper regions found and a 'Region Tag' is created and set up to track them.
      - If disabled, no UVMapper Region Selections or Region Tags will be created (note that even if this option is disabled, you can still "Split by Region" and get separate meshes, who's names are the region names).
    • Import Materials
      - If the .obj file lists a mtllib and it can be found and read, Materials are created (or updated) using that information, otherwise they are created using some default settings (see information below about some re-mapping that takes place).
      - Selection tags are created for any Material groupings and the selections use the material names (no more "Selection 1", "Selection 2" ... "Selection 34", etc. (yay!)).
      - Texture Tags are created for every material grouping.
      - If disabled, no Material Selections, Texture Tags or Materials will be created (note that even if this option is disabled, you can still "Split by Material" and get separate meshes, who's names are the material names).
    • Import UV Coords
      - If the mesh has UV (texture) coordinates, a UVW Coordinates tag(s) is created and added.
      - If disabled, no UV Coordinate Tags will be created.
    • Flip UV Horizontally/Vertically
      These can be used to flip textures left->right or top->bottom.
    • Reverse Faces
      This option can be used to reverse the facets of the imported mesh.
    • Don't Split
      The mesh is set up as one big Polygon Object (editable mesh).
    • Split by Group
      The mesh being loaded is split up into one Polygon Object per group record found in the file (ala C4D's importer).
    • Split by Region
      The mesh being loaded is split up into one Polygon Object per UVMapper Region record found in the file.
    • Split by Material
      The mesh being loaded is split up into one Polygon Object per Material selection found in the file.
    • Create New Document
      When selected, the mesh being loaded is loaded into a fresh/new document.
    • Merge Into Current Document
      When selected, the mesh being loaded is merged into the current/active document.

    [top]

    Wavefront .mtl file notes

    Note that besides being largely undocumented (I spent a week scouring the net to get what information I have on it), a Wavefront .mtl file supports (at best) a small subset of the settings you have available within C4D and as such, there is no 1-to-1 mapping of material properties (bump maps are supported, but there's no way to specify bumpmap strength, for example).

    With that in mind, I had to make some decisions about how to best map C4D's idea of material properties into something that makes sense in a .mtl file. As another example, the .mtl file supports a 'Diffuse' color and texture map, but these are a closer match to C4D's 'Color' channel than the 'Diffuse' channel, so I translate them between the two.

    Other design-decisions/implementation details:

    • 'Ambient' settings are mapped to the 'Luminance' property/channel
    • Specular Color (and any related texture) are set up, but Specular Scale is not.
    • Texture sampling is set to "Alias1" (instead of MIP)
    • Blend Mode is set to "Multiply" (instead of Normal)
    • C4D has a 'brightness' value for various channel colors, but there's not a separate parameter for that in the .mtl file, so the RGB values are scaled by it. In other words, if you had a channel set to White (RGB all = 100%) with a Brightness of 50%, you'd get a mid-Grey color. If you export that mesh, then re-import it and go check that material/channel, you'll find that now the RGB values are all set to 50% and the Brightness is set to 100% - which is opposite - but the resulting mid-Grey color is the same ;).

    ...On a related note, some applications (Poser, for example) don't always save out all of the values you are expecting (like transparency/alpha maps), so you will likely need to still manually load or adjust some settings for best results. In the end, it's still a step up from C4D's built-in .obj import, which ignores the .mtl file all together.

    Also note that for the textures to be loaded correctly, you'll need to set up your "Texture Paths" within C4D for it to find them ("Edit->General Settings" menu in C4D v7.303).

    [top]

    Limitations

    I guess the biggest issue of note here is speed... a lot of the pre-processing done internally to allow all of this amount of flexibility is very brute-force/intensive/repetitive - much of it requiring recursive walks through every polygon in the list multiple times. I've tried to optimize the code wherever possible to account for this, but it may still take a few seconds longer than C4D's built-in .obj import/export feature does to input/output the same file.

    One additional word of caution... various features of the various plugins make attempts to enforce unique group/region/material naming, but not all do. So to get the best (expected) results, you should try to make sure each of your selections (for example) have unique names before exporting. It's also best to make sure that everything is accounted for... polygons that
    don't belong to any particular group/region/material will get consolidated into some 'default' group/region/material... this might create unexpected results. So... "If in doubt, spell it out".

    And on that happy note...

    [top]

    Acknowledgements

    I'd like to give a special thanks to the following people who helped make this happen:

    • Testing and Feedback
      'ramhernan'
      'Viomar'
      'Specs2'
      'Beanzvision'
      'Chris'
      'umblefugly'
      'Irish'
      'jelisa'
      'Damsel'
    • French string (and documentation) translations
      'Viomar'
    • German string translations
      'Specs2'
    • Sample imagery used in Riptide Logo
      'Beanzvision'
    • Developer Support
      Maxon Computers

    [top]

    Final Comments

    Thanks again for your patronage. I am always interested in comments and product feedback. You can send any comments or questions to: spanki@cablenet-va.com I am always happy to try to help with questions whenever possible, but please do me the courtesy of reading through the documentation above first.

    If you like this product, please visit my store for your future shopping needs.

    If you'd like to keep up to date on the latest products, freebies and updates, please stop by Spanki's Prop Shop and sign up for the newsletter.

    Enjoy,

    Keith Young a.k.a. Spanki
    http://www.skinprops.com

    [top]

     

      All images, meshes, props, programs and textual content on this site are Copyright © 2003 by Keith Young. All rights reserved.