Main Page | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

vtk3DSOurImporter.cpp

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    $RCSfile: vtk3DSImporter.cxx,v $
00005   Language:  C++
00006   Date:      $Date: 2001/04/26 14:46:40 $
00007   Version:   $Revision: 1.24 $
00008 
00009 
00010 Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen 
00011 All rights reserved.
00012 
00013 Redistribution and use in source and binary forms, with or without
00014 modification, are permitted provided that the following conditions are met:
00015 
00016  * Redistributions of source code must retain the above copyright notice,
00017    this list of conditions and the following disclaimer.
00018 
00019  * Redistributions in binary form must reproduce the above copyright notice,
00020    this list of conditions and the following disclaimer in the documentation
00021    and/or other materials provided with the distribution.
00022 
00023  * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
00024    of any contributors may be used to endorse or promote products derived
00025    from this software without specific prior written permission.
00026 
00027  * Modified source versions must be plainly marked as such, and must not be
00028    misrepresented as being the original software.
00029 
00030 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00031 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00032 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00033 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
00034 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00035 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00036 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00037 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00038 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00039 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00040 
00041 =========================================================================*/
00042 #include <vtkActor.h>
00043 #include <vtkByteSwap.h>
00044 #include <vtkCamera.h>
00045 #include <vtkCellArray.h>
00046 #include <vtkLight.h>
00047 #include <vtkPolyDataMapper.h>
00048 #include <vtkPolyDataNormals.h>
00049 #include <vtkProperty.h>
00050 #include <vtkRenderer.h>
00051 #include <vtkStripper.h>
00052 #include <vtkObjectFactory.h>
00053 
00054 #include "vtk3DSOurImporter.h"
00055 
00056 //-------------------------------------------------------------------------
00057 vtk3DSOurImporter* vtk3DSOurImporter::New()
00058 {
00059   // First try to create the object from the vtkObjectFactory
00060   vtkObject* ret = vtkObjectFactory::CreateInstance("vtk3DSOurImporter");
00061   if(ret)
00062     {
00063     return (vtk3DSOurImporter*)ret;
00064     }
00065   // If the factory was unable to create the object, then create it here.
00066   return new vtk3DSOurImporter;
00067 }
00068 
00069 static vtk3DSColour Black = {0.0, 0.0, 0.0};
00070 static char   obj_name[80] = "";
00071 static vtk3DSColour fog_colour = {0.0, 0.0, 0.0};
00072 static vtk3DSColour col        = {0.0, 0.0, 0.0};
00073 static vtk3DSColour global_amb = {0.1, 0.1, 0.1};
00074 static vtk3DSVector pos        = {0.0, 0.0, 0.0};
00075 static vtk3DSVector target     = {0.0, 0.0, 0.0};
00076 static float  hotspot = -1;
00077 static float  falloff = -1;
00078 /* Default material property */
00079 static vtk3DSMatProp DefaultMaterial =
00080   { "Default", NULL,
00081     {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0},
00082     70.0, // shininess
00083     0.0,  // transparency
00084     0.0,  // reflection
00085     0,// self illumination
00086     "",   // tex_map
00087     0.0,  // tex_strength
00088     "",   // bump_map
00089     0.0,  // bump_strength
00090     NULL};// vtkProperty
00091 
00092 static void cleanup_name (char *);
00093 static void list_insert (vtk3DSList **root, vtk3DSList *new_node);
00094 static void *list_find (vtk3DSList **root, const char *name);
00095 static void list_kill (vtk3DSList **root);
00096 static vtk3DSMatProp *create_mprop (void);
00097 static vtk3DSMesh *create_mesh (char *name, int vertices, int faces);
00098 static int parse_3ds_file (vtk3DSOurImporter *importer);
00099 static void parse_3ds (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00100 static void parse_mdata (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00101 static void parse_fog (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00102 static void parse_fog_bgnd (vtk3DSOurImporter *importer);
00103 static void parse_mat_entry (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00104 static char *parse_mapname (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00105 static void parse_named_object (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00106 static void parse_n_tri_object (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00107 static void parse_point_array (vtk3DSOurImporter *importer, vtk3DSMesh *mesh);
00108 static void parse_face_array (vtk3DSOurImporter *importer, vtk3DSMesh *mesh, vtk3DSChunk *mainchunk);
00109 static void parse_msh_mat_group (vtk3DSOurImporter *importer, vtk3DSMesh *mesh);
00110 static void parse_smooth_group (vtk3DSOurImporter *importer);
00111 static void parse_mesh_matrix (vtk3DSOurImporter *importer, vtk3DSMesh *mesh);
00112 static void parse_n_direct_light (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk);
00113 static void parse_dl_spotlight (vtk3DSOurImporter *importer);
00114 static void parse_n_camera (vtk3DSOurImporter *importer);
00115 static void parse_colour (vtk3DSOurImporter *importer, vtk3DSColour *colour);
00116 static void parse_colour_f (vtk3DSOurImporter *importer, vtk3DSColour *colour);
00117 static void parse_colour_24 (vtk3DSOurImporter *importer, vtk3DSColour_24 *colour);
00118 static float parse_percentage (vtk3DSOurImporter *importer);
00119 static short parse_int_percentage (vtk3DSOurImporter *importer);
00120 static float parse_float_percentage (vtk3DSOurImporter *importer);
00121 static vtk3DSMaterial *update_materials (vtk3DSOurImporter *importer, const char *new_material, int ext);
00122 static void start_chunk (vtk3DSOurImporter *importer, vtk3DSChunk *chunk);
00123 static void end_chunk (vtk3DSOurImporter *importer, vtk3DSChunk *chunk);
00124 static byte read_byte (vtk3DSOurImporter *importer);
00125 static word read_word (vtk3DSOurImporter *importer);
00126 static dword read_dword (vtk3DSOurImporter *importer);
00127 static float read_float (vtk3DSOurImporter *importer);
00128 static void read_point (vtk3DSOurImporter *importer, vtk3DSVector v);
00129 static char *read_string (vtk3DSOurImporter *importer);
00130 
00131 vtk3DSOurImporter::vtk3DSOurImporter ()
00132 {
00133   this->OmniList = NULL;
00134   this->SpotLightList = NULL;
00135   this->CameraList = NULL;
00136   this->MeshList = NULL;
00137   this->MaterialList = NULL;
00138   this->MatPropList = NULL;
00139   this->FileName = NULL;
00140   this->FileFD = NULL;
00141   this->ComputeNormals = 0;
00142   this->flag3 = 0;
00143 }
00144 
00145 int vtk3DSOurImporter::ImportBegin ()
00146 {
00147   vtkDebugMacro(<< "Opening import file as binary");
00148   this->FileFD = fopen (this->FileName, "rb");
00149   if (this->FileFD == NULL)
00150     {
00151     vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
00152     return 0;
00153     }
00154   return this->Read3DS ();
00155 }
00156 
00157 void vtk3DSOurImporter::ImportEnd ()
00158 {
00159   vtkDebugMacro(<<"Closing import file");
00160   if ( this->FileFD != NULL )
00161     {
00162     fclose (this->FileFD);
00163     }
00164   this->FileFD = NULL;
00165 }
00166 
00167 int vtk3DSOurImporter::Read3DS ()
00168 {
00169   vtk3DSMatProp *aMaterial;
00170 
00171   if (parse_3ds_file (this) == 0)
00172     {
00173     vtkErrorMacro (<<  "Error readings .3ds file: " << this->FileName << "\n");
00174     return 0;
00175     }
00176 
00177 
00178   // create a MatProp and fill if in with default
00179   aMaterial = (vtk3DSMatProp *) malloc (sizeof (vtk3DSMatProp));
00180   *aMaterial = DefaultMaterial;
00181   aMaterial->aProperty = vtkProperty::New ();
00182   VTK_LIST_INSERT (this->MatPropList, aMaterial);
00183   return 1;
00184 }
00185 
00186 void vtk3DSOurImporter::ImportActors (vtkRenderer *renderer)
00187 {
00188   vtk3DSMatProp *material;
00189   vtk3DSMesh *mesh;
00190   vtkStripper *polyStripper;
00191   vtkPolyDataNormals *polyNormals;
00192   vtkPolyDataMapper *polyMapper;
00193   vtkPolyData *polyData;
00194   vtkActor *actor;
00195 
00196   // walk the list of meshes, creating actors
00197   for (mesh = this->MeshList; mesh != (vtk3DSMesh *) NULL; 
00198        mesh = (vtk3DSMesh *) mesh->next)
00199     {
00200     if (mesh->faces == 0)
00201       {
00202       vtkWarningMacro (<< "part " << mesh->name << " has zero faces... skipping\n");
00203       continue;
00204       }
00205 
00206     polyData = this->GeneratePolyData (mesh);
00207     mesh->aMapper = polyMapper = vtkPolyDataMapper::New ();
00208     mesh->aStripper = polyStripper = vtkStripper::New ();
00209 
00210     // if ComputeNormals is on, insert a vtkPolyDataNormals filter
00211     if (this->ComputeNormals)
00212       {
00213       mesh->aNormals = polyNormals = vtkPolyDataNormals::New ();
00214       polyNormals->SetInput (polyData);
00215       polyStripper->SetInput (polyNormals->GetOutput ());
00216       }
00217     else
00218       {
00219         polyStripper->SetInput (polyData);
00220       }
00221     
00222     //polyMapper->SetInput (polyStripper->GetOutput ());
00223     polyMapper->SetInput(polyData);
00224     vtkDebugMacro (<< "Importing Actor: " << mesh->name);
00225     mesh->anActor = actor = vtkActor::New ();
00226     actor->SetMapper (polyMapper);
00227     material = (vtk3DSMatProp *)VTK_LIST_FIND(this->MatPropList, mesh->mtl[0]->name);
00228     actor->SetProperty (material->aProperty);
00229     renderer->AddActor (actor);
00230   }
00231 }
00232 
00233 void vtk3DSOurImporter::SetPolys (char* f)
00234   {
00235   if (strcmp(f,"triangle")==0) flag3=0;
00236   else flag3=1;
00237   }
00238 
00239 vtkPolyData *vtk3DSOurImporter::GeneratePolyData (vtk3DSMesh *mesh)
00240 {
00241   int i;
00242   vtk3DSFace  *face;
00243   vtkCellArray *triangles;
00244   vtkPoints *vertices;
00245   vtkPolyData *polyData;
00246 
00247   face = mesh->face;
00248   mesh->aCellArray = triangles = vtkCellArray::New ();
00249   triangles->Allocate(mesh->faces * 4);
00250  
00251   if (flag3!=0) 
00252   for (i = 0; i < mesh->faces; i++, face++)
00253     {
00254     triangles->InsertNextCell (4);
00255     triangles->InsertCellPoint (face->a);
00256     triangles->InsertCellPoint (face->b);
00257     triangles->InsertCellPoint (face->c);
00258     i++; face++;
00259     triangles->InsertCellPoint (face->b);
00260     }
00261   else
00262   for (i = 0; i < mesh->faces; i++, face++)
00263     {
00264     triangles->InsertNextCell (3);
00265     triangles->InsertCellPoint (face->a);
00266     triangles->InsertCellPoint (face->b);
00267     triangles->InsertCellPoint (face->c);
00268     }
00269 
00270   mesh->aPoints = vertices = vtkPoints::New ();
00271   vertices->Allocate(mesh->vertices);
00272   for (i = 0; i < mesh->vertices; i++)
00273     {
00274     vertices->InsertPoint (i, (float *) mesh->vertex[i]);
00275     }
00276   mesh->aPolyData = polyData = vtkPolyData::New ();
00277   polyData->SetPolys (triangles);
00278   polyData->SetPoints (vertices);
00279 
00280   return polyData;
00281 }
00282 
00283 void vtk3DSOurImporter::ImportCameras (vtkRenderer *renderer)
00284 {
00285   vtkCamera *aCamera;
00286   vtk3DSCamera *camera;
00287 
00288   // walk the list of cameras and create vtk cameras
00289   for (camera = this->CameraList; camera != (vtk3DSCamera *) NULL; camera = (vtk3DSCamera *) camera->next)
00290     {
00291     camera->aCamera = aCamera = vtkCamera::New ();      
00292     aCamera->SetPosition (camera->pos[0], camera->pos[1], camera->pos[2]);
00293     aCamera->SetFocalPoint (camera->target[0], camera->target[1], camera->target[2]);
00294     aCamera->SetViewUp (0, 0, 1);
00295     aCamera->SetClippingRange (.1,10000);
00296     aCamera->Roll (camera->bank);
00297     renderer->SetActiveCamera (aCamera);
00298     vtkDebugMacro (<< "Importing Camera: " << camera->name);
00299   }
00300 }
00301 
00302 void vtk3DSOurImporter::ImportLights (vtkRenderer *renderer)
00303 {
00304   vtk3DSOmniLight *omniLight;
00305   vtk3DSSpotLight *spotLight;
00306   vtkLight *aLight;
00307 
00308   // just walk the list of omni lights, creating vtk lights
00309   for (omniLight = this->OmniList; omniLight != (vtk3DSOmniLight *) NULL; 
00310        omniLight = (vtk3DSOmniLight *) omniLight->next)
00311   {
00312   omniLight->aLight = aLight = vtkLight::New ();
00313   aLight->SetPosition (omniLight->pos[0],
00314                        omniLight->pos[1],
00315                        omniLight->pos[2]);
00316   aLight->SetFocalPoint (0, 0, 0);
00317   aLight->SetColor (omniLight->col.red,
00318                     omniLight->col.green,
00319                     omniLight->col.blue);
00320   renderer->AddLight (aLight);
00321   vtkDebugMacro (<< "Importing Omni Light: " << omniLight->name);
00322   }                       
00323 
00324   // now walk the list of spot lights, creating vtk lights
00325   for (spotLight = this->SpotLightList; spotLight != (vtk3DSSpotLight *) NULL; 
00326        spotLight = (vtk3DSSpotLight *) spotLight->next)
00327   {
00328   spotLight->aLight = aLight = vtkLight::New ();
00329   aLight->PositionalOn ();
00330   aLight->SetPosition (spotLight->pos[0],
00331                        spotLight->pos[1],
00332                        spotLight->pos[2]);
00333   aLight->SetFocalPoint (spotLight->target[0],
00334                          spotLight->target[1],
00335                          spotLight->target[2]);
00336   aLight->SetColor (spotLight->col.red,
00337                     spotLight->col.green,
00338                     spotLight->col.blue);
00339   aLight->SetConeAngle (spotLight->falloff);
00340   renderer->AddLight (aLight);
00341   vtkDebugMacro (<< "Importing Spot Light: " << spotLight->name);
00342   }                       
00343 }
00344 
00345 void vtk3DSOurImporter::ImportProperties (vtkRenderer *vtkNotUsed(renderer))
00346 {
00347   float amb = 0.1, dif = 0.9;
00348   float dist_white, dist_diff, phong, phong_size;
00349   vtkProperty *property;
00350   vtk3DSMatProp *m;
00351 
00352   // just walk the list of material properties, creating vtk properties
00353   for (m = this->MatPropList; m != (vtk3DSMatProp *) NULL; m = (vtk3DSMatProp *) m->next)
00354     {
00355     if (m->self_illum)
00356       {
00357       amb = 0.9;
00358       dif = 0.1;
00359       }
00360 
00361     dist_white = fabs(1.0 - m->specular.red) +
00362          fabs(1.0 - m->specular.green) +
00363          fabs(1.0 - m->specular.blue);
00364 
00365     dist_diff  = fabs(m->diffuse.red   - m->specular.red) +
00366          fabs(m->diffuse.green - m->specular.green) +
00367          fabs(m->diffuse.blue  - m->specular.blue);
00368 
00369     if (dist_diff < dist_white)
00370       {
00371       dif = .1; amb = .8;
00372       }
00373 
00374     phong_size = 0.7*m->shininess;
00375     if (phong_size < 1.0)
00376       {
00377       phong_size = 1.0;
00378       }
00379     if (phong_size > 30.0)
00380       {
00381       phong = 1.0;
00382       }
00383     else
00384       {
00385       phong = phong_size/30.0;
00386       }
00387   property = m->aProperty;
00388   property->SetAmbientColor(m->ambient.red, m->ambient.green, m->ambient.blue);
00389   property->SetAmbient (amb);
00390   property->SetDiffuseColor(m->diffuse.red, m->diffuse.green, m->diffuse.blue);
00391   property->SetDiffuse (dif);
00392   property->SetSpecularColor(m->specular.red, m->specular.green, m->specular.blue);
00393   property->SetSpecular (phong);
00394   property->SetSpecularPower(phong_size);
00395   property->SetOpacity(1.0 - m->transparency);
00396   vtkDebugMacro(<< "Importing Property: " << m->name);
00397   
00398   m->aProperty = property;
00399   }
00400 }
00401 
00402 /* Insert a new node into the list */
00403 static void list_insert (vtk3DSList **root, vtk3DSList *new_node)
00404 {
00405   new_node->next = *root;
00406   *root = new_node;
00407 }
00408 
00409 
00410 /* Find the node with the specified name */
00411 static void *list_find (vtk3DSList **root, const char *name)
00412 {
00413   vtk3DSList *p;
00414   for (p = *root; p != (vtk3DSList *) NULL; p = (vtk3DSList *) p->next)
00415     {
00416     if (strcmp (p->name, name) == 0)
00417       {
00418       break;
00419       }
00420     }
00421   return (void *)p;
00422 }
00423 
00424 /* Delete the entire list */
00425 static void list_kill (vtk3DSList **root)
00426 {
00427   vtk3DSList *temp;
00428 
00429   while (*root != (vtk3DSList *) NULL) 
00430     {
00431     temp = *root;
00432     *root = (vtk3DSList *) (*root)->next;
00433     free (temp);
00434     }
00435 }
00436 
00437 /* Add a new material to the material list */
00438 static vtk3DSMaterial *update_materials (vtk3DSOurImporter *importer, const char *new_material, int ext)
00439 {
00440   vtk3DSMaterial *p;
00441 
00442   p = (vtk3DSMaterial *) VTK_LIST_FIND (importer->MaterialList, new_material);
00443 
00444   if (p == NULL)
00445     {
00446     p = (vtk3DSMaterial *) malloc (sizeof (*p));
00447     strcpy (p->name, new_material);
00448     p->external = ext;
00449     VTK_LIST_INSERT (importer->MaterialList, p);
00450     }
00451   return p;
00452 }
00453 
00454 
00455 static vtk3DSMatProp *create_mprop()
00456 {
00457   vtk3DSMatProp *new_mprop;
00458 
00459   new_mprop = (vtk3DSMatProp *) malloc (sizeof(*new_mprop));
00460   strcpy (new_mprop->name, "");
00461   new_mprop->ambient = Black;
00462   new_mprop->diffuse = Black;
00463   new_mprop->specular = Black;
00464   new_mprop->shininess = 0.0;
00465   new_mprop->transparency = 0.0;
00466   new_mprop->reflection = 0.0;
00467   new_mprop->self_illum = 0;
00468 
00469   strcpy (new_mprop->tex_map, "");
00470   new_mprop->tex_strength = 0.0;
00471 
00472   strcpy (new_mprop->bump_map, "");
00473   new_mprop->bump_strength = 0.0;
00474 
00475   new_mprop->aProperty = vtkProperty::New ();
00476   return new_mprop;
00477 }
00478 
00479 
00480 /* Create a new mesh */
00481 static vtk3DSMesh *create_mesh (char *name, int vertices, int faces)
00482 {
00483   vtk3DSMesh *new_mesh;
00484 
00485   new_mesh = (vtk3DSMesh *) malloc (sizeof(*new_mesh));
00486   strcpy (new_mesh->name, name);
00487 
00488   new_mesh->vertices = vertices;
00489 
00490   if (vertices <= 0)
00491     {
00492     new_mesh->vertex = NULL;
00493     }
00494   else
00495     {
00496     new_mesh->vertex = (vtk3DSVector *) malloc(vertices * sizeof(*new_mesh->vertex));
00497     }
00498 
00499   new_mesh->faces = faces;
00500 
00501   if (faces <= 0)
00502     {
00503     new_mesh->face = NULL;
00504     new_mesh->mtl = NULL;
00505     }
00506   else
00507     {
00508     new_mesh->face = (vtk3DSFace *) malloc (faces * sizeof(*new_mesh->face));
00509     new_mesh->mtl = (vtk3DSMaterial **) malloc (faces * sizeof(*new_mesh->mtl));
00510     }
00511 
00512   new_mesh->hidden = 0;
00513   new_mesh->shadow = 1;
00514 
00515   new_mesh->anActor = NULL;
00516   new_mesh->aMapper = NULL;
00517   new_mesh->aNormals = NULL;
00518   new_mesh->aStripper = NULL;
00519   new_mesh->aPoints = NULL;
00520   new_mesh->aCellArray = NULL;
00521   new_mesh->aPolyData = NULL;
00522   return new_mesh;
00523 }
00524 
00525 
00526 static int parse_3ds_file(vtk3DSOurImporter *importer)
00527 {
00528   vtk3DSChunk chunk;
00529 
00530   start_chunk(importer, &chunk);
00531 
00532   if (chunk.tag == 0x4D4D)
00533     {
00534     parse_3ds (importer, &chunk);
00535     }
00536   else
00537     {
00538     vtkGenericWarningMacro(<< "Error: Input file is not .3DS format\n");
00539     return 0;
00540     }
00541 
00542   end_chunk (importer, &chunk);
00543   return 1;
00544 }
00545 
00546 static void parse_3ds (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00547 {
00548   vtk3DSChunk chunk;
00549 
00550   do  
00551     {
00552     start_chunk (importer, &chunk);
00553 
00554     if (chunk.end <= mainchunk->end)
00555       {
00556       switch (chunk.tag)
00557         {
00558         case 0x3D3D: parse_mdata (importer, &chunk);
00559           break;
00560         }
00561       }
00562     end_chunk (importer, &chunk);
00563     } while (chunk.end <= mainchunk->end);
00564 }
00565 
00566 
00567 static void parse_mdata (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00568 {
00569   vtk3DSChunk chunk;
00570   vtk3DSColour bgnd_colour;
00571 
00572   do  
00573     {
00574     start_chunk (importer, &chunk);
00575     
00576     if (chunk.end <= mainchunk->end) 
00577       {
00578       switch (chunk.tag) 
00579         {
00580         case 0x2100: parse_colour (importer, &global_amb);
00581           break;
00582         case 0x1200: parse_colour (importer, &bgnd_colour);
00583           break;
00584         case 0x2200: parse_fog (importer, &chunk);
00585           break;
00586         case 0x2210: parse_fog_bgnd(importer);
00587           break;
00588         case 0xAFFF: parse_mat_entry (importer, &chunk);
00589           break;
00590         case 0x4000: parse_named_object (importer, &chunk);
00591           break;
00592         }
00593       }
00594 
00595     end_chunk (importer, &chunk);
00596     } while (chunk.end <= mainchunk->end);
00597 }
00598 
00599 
00600 static void parse_fog (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00601 {
00602   vtk3DSChunk chunk;
00603 
00604   (void)read_float(importer);
00605   (void)read_float(importer);
00606   (void) read_float(importer);
00607   (void)read_float(importer);
00608 
00609   parse_colour (importer, &fog_colour);
00610 
00611   do  
00612     {
00613     start_chunk (importer, &chunk);
00614 
00615     if (chunk.end <= mainchunk->end) 
00616       {
00617       switch (chunk.tag) 
00618         {
00619         case 0x2210: parse_fog_bgnd(importer);
00620           break;
00621         }
00622       }
00623 
00624     end_chunk (importer, &chunk);
00625     } while (chunk.end <= mainchunk->end);
00626 }
00627 
00628 
00629 static void parse_fog_bgnd(vtk3DSOurImporter *vtkNotUsed(importer))
00630 {
00631 }
00632 
00633 
00634 static void parse_mat_entry (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00635 {
00636   vtk3DSChunk chunk;
00637   vtk3DSMatProp *mprop;
00638 
00639   mprop = create_mprop();
00640 
00641   do  
00642     {
00643     start_chunk (importer, &chunk);
00644     if (chunk.end <= mainchunk->end) 
00645       {
00646       switch (chunk.tag) 
00647         {
00648         case 0xA000: strcpy (mprop->name, read_string(importer));
00649           cleanup_name (mprop->name);
00650           break;
00651 
00652         case 0xA010: parse_colour (importer, &mprop->ambient);
00653           break;
00654 
00655         case 0xA020: parse_colour (importer, &mprop->diffuse);
00656           break;
00657 
00658         case 0xA030: parse_colour (importer, &mprop->specular);
00659           break;
00660 
00661         case 0xA040: mprop->shininess = 100.0*parse_percentage(importer);
00662           break;
00663 
00664         case 0xA050: mprop->transparency = parse_percentage(importer);
00665           break;
00666 
00667         case 0xA080: mprop->self_illum = 1;
00668           break;
00669 
00670         case 0xA220: mprop->reflection = parse_percentage(importer);
00671           (void)parse_mapname (importer, &chunk);
00672           break;
00673 
00674         case 0xA310: if (mprop->reflection == 0.0)
00675           {
00676           mprop->reflection = 1.0;
00677           }
00678         break;
00679 
00680         case 0xA200: mprop->tex_strength = parse_percentage(importer);
00681           strcpy (mprop->tex_map, parse_mapname (importer, &chunk));
00682           break;
00683 
00684         case 0xA230: mprop->bump_strength = parse_percentage(importer);
00685           strcpy (mprop->bump_map, parse_mapname (importer, &chunk));
00686           break;
00687         }
00688       }
00689 
00690     end_chunk (importer, &chunk);
00691     } while (chunk.end <= mainchunk->end);
00692 
00693     VTK_LIST_INSERT (importer->MatPropList, mprop);
00694 }
00695 
00696 
00697 static char *parse_mapname (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00698 {
00699   static char name[80] = "";
00700   vtk3DSChunk chunk;
00701 
00702   do  
00703     {
00704     start_chunk (importer, &chunk);
00705 
00706     if (chunk.end <= mainchunk->end) 
00707       {
00708       switch (chunk.tag) 
00709         {
00710         case 0xA300: strcpy (name, read_string(importer));
00711           break;
00712         }
00713       }
00714 
00715     end_chunk (importer, &chunk);
00716     } while (chunk.end <= mainchunk->end);
00717 
00718     return name;
00719 }
00720 
00721 
00722 static void parse_named_object (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00723 {
00724   vtk3DSMesh *mesh;
00725   vtk3DSChunk chunk;
00726 
00727   strcpy (obj_name, read_string(importer));
00728   cleanup_name (obj_name);
00729 
00730   mesh = NULL;
00731 
00732   do  
00733     {
00734     start_chunk (importer, &chunk);
00735     if (chunk.end <= mainchunk->end) 
00736       {
00737       switch (chunk.tag) 
00738         {
00739         case 0x4100: parse_n_tri_object (importer, &chunk);
00740           break;
00741         case 0x4600: parse_n_direct_light (importer, &chunk);
00742           break;
00743         case 0x4700: parse_n_camera(importer);
00744           break;
00745         case 0x4010: if (mesh != NULL)
00746           {
00747           mesh->hidden = 1;
00748           }
00749         break;
00750         case 0x4012: if (mesh != NULL)
00751           {
00752           mesh->shadow = 0;
00753           }
00754         break;
00755         }
00756       }
00757 
00758     end_chunk (importer, &chunk);
00759     } while (chunk.end <= mainchunk->end);
00760 
00761 }
00762 
00763 static void parse_n_tri_object (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00764 {
00765   vtk3DSMesh *mesh;
00766   vtk3DSChunk chunk;
00767 
00768   mesh = create_mesh (obj_name, 0, 0);
00769 
00770   do  
00771     {
00772     start_chunk (importer, &chunk);
00773 
00774     if (chunk.end <= mainchunk->end) 
00775       {
00776       switch (chunk.tag) 
00777         {
00778         case 0x4110: parse_point_array(importer, mesh);
00779           break;
00780         case 0x4120: parse_face_array (importer, mesh, &chunk);
00781           break;
00782         case 0x4160: parse_mesh_matrix(importer, mesh);
00783           break;
00784         }
00785       }
00786 
00787     end_chunk (importer, &chunk);
00788     } while (chunk.end <= mainchunk->end);
00789 
00790   VTK_LIST_INSERT (importer->MeshList, mesh);
00791 }
00792 
00793 
00794 static void parse_point_array(vtk3DSOurImporter *importer, vtk3DSMesh *mesh)
00795 {
00796   int i;
00797   mesh->vertices = read_word(importer);
00798   mesh->vertex = (vtk3DSVector *) malloc (mesh->vertices * sizeof(*(mesh->vertex)));
00799   for (i = 0; i < mesh->vertices; i++)
00800     {
00801     read_point (importer, mesh->vertex[i]);
00802     }
00803 }
00804 
00805 static void parse_face_array (vtk3DSOurImporter *importer, vtk3DSMesh *mesh, vtk3DSChunk *mainchunk)
00806 {
00807   vtk3DSChunk chunk;
00808   int i;
00809   mesh->faces = read_word(importer);
00810   mesh->face = (vtk3DSFace *) malloc (mesh->faces * sizeof(*(mesh->face)));
00811   mesh->mtl = (vtk3DSMaterial **) malloc (mesh->faces * sizeof(*(mesh->mtl)));
00812 
00813   for (i = 0; i < mesh->faces; i++) 
00814     {
00815     mesh->face[i].a = read_word(importer);
00816     mesh->face[i].b = read_word(importer);
00817     mesh->face[i].c = read_word(importer);
00818     //fprintf (stdout, "face %d: %d,%d,%d, %d \n", i, mesh->face[i].a, mesh->face[i].b, mesh->face[i].c, read_word(importer));
00819     (void)read_word(importer); //flags not implemented: bit 0 - CA visible, bit 1 - BC visible, bit 2 - AB visible
00820     mesh->mtl[i] = NULL;
00821     }
00822 
00823   do  
00824     {
00825     start_chunk (importer, &chunk);
00826     if (chunk.end <= mainchunk->end) 
00827       {
00828       switch (chunk.tag) 
00829         {
00830         case 0x4130: parse_msh_mat_group(importer, mesh);
00831           break;
00832         case 0x4150: parse_smooth_group(importer);
00833           break;
00834         }
00835       }
00836 
00837     end_chunk (importer, &chunk);
00838     } while (chunk.end <= mainchunk->end);
00839 
00840   for (i = 0; i < mesh->faces; i++)
00841     {
00842     if (mesh->mtl[i] == (vtk3DSMaterial *) NULL)
00843       {
00844       mesh->mtl[i] = update_materials (importer, "Default", 0);
00845       }
00846     }
00847 }
00848 
00849 
00850 static void parse_msh_mat_group(vtk3DSOurImporter *importer, vtk3DSMesh *mesh)
00851 {
00852   vtk3DSMaterial *new_mtl;
00853   char mtlname[80];
00854   int  mtlcnt;
00855   int  i, face;
00856 
00857   strcpy (mtlname, read_string(importer));
00858   cleanup_name (mtlname);
00859 
00860   new_mtl = update_materials (importer, mtlname, 0);
00861 
00862   mtlcnt = read_word(importer);
00863 
00864   for (i = 0; i < mtlcnt; i++) 
00865     {
00866     face = read_word(importer);
00867     mesh->mtl[face] = new_mtl;
00868     }
00869 }
00870 
00871 static void parse_smooth_group(vtk3DSOurImporter *vtkNotUsed(importer))
00872 {
00873 }
00874 
00875 static void parse_mesh_matrix(vtk3DSOurImporter *vtkNotUsed(importer), vtk3DSMesh *vtkNotUsed(mesh))
00876 {
00877   //  vtkGenericWarningMacro(<< "mesh matrix detected but not used\n");
00878 }
00879 
00880 
00881 static void parse_n_direct_light (vtk3DSOurImporter *importer, vtk3DSChunk *mainchunk)
00882 {
00883   vtk3DSChunk chunk;
00884   vtk3DSSpotLight *s;
00885   vtk3DSOmniLight *o;
00886   int spot_flag = 0;
00887 
00888   read_point (importer, pos);
00889   parse_colour (importer, &col);
00890 
00891   do  
00892     {
00893     start_chunk (importer, &chunk);
00894 
00895     if (chunk.end <= mainchunk->end) 
00896       {
00897       switch (chunk.tag) 
00898         {
00899         case 0x4620: break;
00900         case 0x4610: parse_dl_spotlight(importer);
00901           spot_flag = 1;
00902           break;
00903         }
00904       }
00905 
00906     end_chunk (importer, &chunk);
00907     } while (chunk.end <= mainchunk->end);
00908 
00909   if (!spot_flag)
00910     {
00911     o = (vtk3DSOmniLight *) VTK_LIST_FIND (importer->OmniList, obj_name);
00912 
00913     if (o != NULL)
00914       {
00915       pos[0] = o->pos[0];
00916       pos[1] = o->pos[1];
00917       pos[2] = o->pos[2];
00918       col    = o->col;
00919       }
00920     else
00921       {
00922       o = (vtk3DSOmniLight *) malloc (sizeof (*o));
00923       o->pos[0] = pos[0];
00924       o->pos[1] = pos[1];
00925       o->pos[2] = pos[2];
00926       o->col = col   ;
00927       strcpy (o->name, obj_name);
00928       VTK_LIST_INSERT (importer->OmniList, o);
00929       }
00930     }
00931   else
00932     {
00933     s = (vtk3DSSpotLight *) VTK_LIST_FIND (importer->SpotLightList, obj_name);
00934 
00935     if (s != NULL)
00936       {
00937       pos[0]    = s->pos[0];
00938       pos[1]    = s->pos[1];
00939       pos[2]    = s->pos[2];
00940       target[0] = s->target[0];
00941       target[1] = s->target[1];
00942       target[2] = s->target[2];
00943       col       = s->col;
00944       hotspot   = s->hotspot;
00945       falloff   = s->falloff;
00946       }
00947     else
00948       {
00949       if (falloff <= 0.0)
00950         {
00951         falloff = 180.0;
00952         }
00953       if (hotspot <= 0.0)
00954         {
00955         hotspot = 0.7*falloff;
00956         }
00957       s = (vtk3DSSpotLight *) malloc (sizeof (*s));
00958       s->pos[0] = pos[0];
00959       s->pos[1] = pos[1];
00960       s->pos[2] = pos[2];
00961       s->target[0] = target[0];
00962       s->target[1] = target[1];
00963       s->target[2] = target[2];
00964       s->col = col   ;
00965       s->hotspot = hotspot;
00966       s->falloff = falloff;
00967       strcpy (s->name, obj_name);
00968       VTK_LIST_INSERT (importer->SpotLightList, s);
00969       }
00970     }
00971 }
00972 
00973 
00974 static void parse_dl_spotlight(vtk3DSOurImporter *importer)
00975 {
00976   read_point (importer, target);
00977 
00978   hotspot = read_float(importer);
00979   falloff = read_float(importer);
00980 }
00981 
00982 
00983 static void parse_n_camera(vtk3DSOurImporter *importer)
00984 {
00985   float  bank;
00986   float  lens;
00987   vtk3DSCamera *c = (vtk3DSCamera *) malloc (sizeof (vtk3DSCamera));
00988 
00989   read_point (importer, pos);
00990   read_point (importer, target);
00991   bank = read_float(importer);
00992   lens = read_float(importer);
00993 
00994   strcpy (c->name, obj_name);
00995   c->pos[0] = pos[0];
00996   c->pos[1] = pos[1];
00997   c->pos[2] = pos[2];
00998   c->target[0] = target[0];
00999   c->target[1] = target[1];
01000   c->target[2] = target[2];
01001   c->lens = lens;
01002   c->bank = bank;
01003 
01004   VTK_LIST_INSERT (importer->CameraList, c);
01005 }
01006 
01007 static void parse_colour (vtk3DSOurImporter *importer, vtk3DSColour *colour)
01008 {
01009   vtk3DSChunk chunk;
01010   vtk3DSColour_24 colour_24;
01011 
01012   start_chunk (importer, &chunk);
01013 
01014   switch (chunk.tag) 
01015     {
01016     case 0x0010: parse_colour_f (importer, colour);
01017       break;
01018 
01019     case 0x0011: parse_colour_24 (importer, &colour_24);
01020       colour->red   = colour_24.red/255.0;
01021       colour->green = colour_24.green/255.0;
01022       colour->blue  = colour_24.blue/255.0;
01023       break;
01024 
01025     default: vtkGenericWarningMacro(<< "Error parsing colour");
01026     }
01027 
01028   end_chunk (importer, &chunk);
01029 }
01030 
01031 
01032 static void parse_colour_f (vtk3DSOurImporter *importer, vtk3DSColour *colour)
01033 {
01034   colour->red   = read_float(importer);
01035   colour->green = read_float(importer);
01036   colour->blue  = read_float(importer);
01037 }
01038 
01039 
01040 static void parse_colour_24 (vtk3DSOurImporter *importer, vtk3DSColour_24 *colour)
01041 {
01042   colour->red   = read_byte(importer);
01043   colour->green = read_byte(importer);
01044   colour->blue  = read_byte(importer);
01045 }
01046 
01047 
01048 static float parse_percentage(vtk3DSOurImporter *importer)
01049 {
01050   vtk3DSChunk chunk;
01051   float percent = 0.0;
01052 
01053   start_chunk (importer, &chunk);
01054 
01055   switch (chunk.tag) 
01056     {
01057     case 0x0030: percent = parse_int_percentage(importer)/100.0;
01058       break;
01059 
01060     case 0x0031: percent = parse_float_percentage(importer);
01061       break;
01062 
01063     default:     vtkGenericWarningMacro( << "Error parsing percentage\n");
01064     }
01065 
01066   end_chunk (importer, &chunk);
01067 
01068   return percent;
01069 }
01070 
01071 
01072 static short parse_int_percentage(vtk3DSOurImporter *importer)
01073 {
01074   word percent = read_word(importer);
01075 
01076   return percent;
01077 }
01078 
01079 
01080 static float parse_float_percentage(vtk3DSOurImporter *importer)
01081 {
01082   float percent = read_float(importer);
01083 
01084   return percent;
01085 }
01086 
01087 
01088 static void start_chunk (vtk3DSOurImporter *importer, vtk3DSChunk *chunk)
01089 {
01090   chunk->start  = ftell(importer->GetFileFD());
01091   chunk->tag    = read_word(importer);
01092   chunk->length = read_dword(importer);
01093   if (chunk->length == 0)
01094     {
01095     chunk->length = 1;
01096     }
01097   chunk->end    = chunk->start + chunk->length;
01098 }
01099 
01100 
01101 static void end_chunk (vtk3DSOurImporter *importer, vtk3DSChunk *chunk)
01102 {
01103   fseek (importer->GetFileFD(), chunk->end, 0);
01104 }
01105 
01106 
01107 static byte read_byte(vtk3DSOurImporter *importer)
01108 {
01109   byte data;
01110 
01111   data = fgetc (importer->GetFileFD());
01112 
01113   return data;
01114 }
01115 
01116 
01117 static word read_word(vtk3DSOurImporter *importer)
01118 {
01119   word data;
01120 
01121   fread (&data, 2, 1, importer->GetFileFD());
01122   vtkByteSwap::Swap2LE ((short *) &data);
01123 /*    swab ((char *) &data, (char *) &sdata, 2);*/
01124 
01125   return data;
01126 }
01127 
01128 static dword read_dword(vtk3DSOurImporter *importer)
01129 {
01130   dword data;
01131 
01132   if (fread (&data, 4, 1, importer->GetFileFD()) != 1)
01133     {
01134 //    vtkGenericWarningMacro(<<"Pre-mature end of file in read_dword\n");
01135     data = 0;
01136     }
01137 
01138   vtkByteSwap::Swap4LE ((char *) &data);
01139   return data;
01140 }
01141 
01142 
01143 static float read_float(vtk3DSOurImporter *importer)
01144 {
01145   float data;
01146 
01147   fread (&data, 4, 1, importer->GetFileFD());
01148   vtkByteSwap::Swap4LE ((char *) &data);
01149 /*    TIFFSwabLong (&data);*/
01150 
01151     return data;
01152 }
01153 
01154 
01155 static void read_point (vtk3DSOurImporter *importer, vtk3DSVector v)
01156 {
01157   v[0] = read_float(importer);
01158   v[1] = read_float(importer);
01159   v[2] = read_float(importer);
01160 }
01161 
01162 
01163 static char *read_string(vtk3DSOurImporter *importer)
01164 {
01165   static char string[80];
01166   int i;
01167 
01168   for (i = 0; i < 80; i++)
01169     {
01170     string[i] = read_byte(importer);
01171 
01172     if (string[i] == '\0')
01173       {
01174       break;
01175       }
01176     }
01177 
01178     return string;
01179 }
01180 
01181 
01182 
01183 static void cleanup_name (char *name)
01184 {
01185   char *tmp = (char *) malloc (strlen(name)+2);
01186   int  i;
01187 
01188     /* Remove any leading blanks or quotes */
01189   i = 0;
01190   while ((name[i] == ' ' || name[i] == '"') && name[i] != '\0')
01191     {
01192     i++;
01193     }
01194   strcpy (tmp, &name[i]);
01195 
01196     /* Remove any trailing blanks or quotes */
01197   for (i = strlen(tmp)-1; i >= 0; i--)
01198     {
01199     if (isprint(tmp[i]) && !isspace(tmp[i]) && tmp[i] != '"')
01200       {
01201       break;
01202       }
01203     else
01204       {
01205       tmp[i] = '\0';
01206       }
01207     }
01208 
01209     strcpy (name, tmp);
01210 
01211     /* Prefix the letter 'N' to materials that begin with a digit */
01212     if (!isdigit (name[0]))
01213       {
01214       strcpy (tmp, name);
01215       }
01216     else 
01217       {
01218       tmp[0] = 'N';
01219       strcpy (&tmp[1], name);
01220       }
01221 
01222     /* Replace all illegal charaters in name with underscores */
01223     for (i = 0; tmp[i] != '\0'; i++)
01224       {
01225       if (!isalnum(tmp[i]))
01226         {
01227         tmp[i] = '_';
01228         }
01229       }
01230 
01231     strcpy (name, tmp);
01232 
01233     free (tmp);
01234 }
01235 
01236 vtk3DSOurImporter::~vtk3DSOurImporter()
01237 {
01238   vtk3DSOmniLight *omniLight;
01239   vtk3DSSpotLight *spotLight;
01240 
01241   // walk the light list and delete vtk objects
01242   for (omniLight = this->OmniList; omniLight != (vtk3DSOmniLight *) NULL; omniLight = (vtk3DSOmniLight *) omniLight->next)
01243     {
01244     omniLight->aLight->Delete();
01245     }
01246   VTK_LIST_KILL (this->OmniList);
01247 
01248   // walk the spot light list and delete vtk objects
01249   for (spotLight = this->SpotLightList; spotLight != (vtk3DSSpotLight *) NULL; 
01250        spotLight = (vtk3DSSpotLight *) spotLight->next)
01251     {
01252     spotLight->aLight->Delete();
01253     }
01254   VTK_LIST_KILL (this->SpotLightList);
01255 
01256   vtk3DSCamera *camera;
01257   // walk the camera list and delete vtk objects
01258   for (camera = this->CameraList; camera != (vtk3DSCamera *) NULL; 
01259        camera = (vtk3DSCamera *) camera->next)
01260     {
01261     camera->aCamera->Delete ();
01262     }
01263   VTK_LIST_KILL (this->CameraList);
01264 
01265   // walk the mesh list and delete malloced datra and vtk objects
01266   vtk3DSMesh *mesh;
01267   for (mesh = this->MeshList; mesh != (vtk3DSMesh *) NULL; 
01268        mesh = (vtk3DSMesh *) mesh->next)
01269     {
01270     if (mesh->anActor != NULL)
01271       {
01272       mesh->anActor->Delete ();
01273       }
01274     if (mesh->aMapper != NULL)
01275       {
01276       mesh->aMapper->Delete ();
01277       }
01278     if (mesh->aNormals != NULL)
01279       {
01280       mesh->aNormals->Delete ();
01281       }
01282     if (mesh->aStripper != NULL)
01283       {
01284       mesh->aStripper->Delete ();
01285       }
01286     if (mesh->aPoints != NULL)
01287       {
01288       mesh->aPoints->Delete ();
01289       }
01290     if (mesh->aCellArray != NULL)
01291       {
01292       mesh->aCellArray->Delete ();
01293       }
01294     if (mesh->aPolyData != NULL)
01295       {
01296       mesh->aPolyData->Delete ();
01297       }
01298     if (mesh->vertex)
01299       {
01300       free (mesh->vertex);
01301       }
01302     if (mesh->face)
01303       {
01304       free (mesh->face);
01305       }
01306     if (mesh->mtl)
01307       {
01308       free (mesh->mtl);  
01309       }
01310     }
01311 
01312   // then delete the list structure
01313 
01314   VTK_LIST_KILL (this->MeshList);
01315   VTK_LIST_KILL (this->MaterialList);
01316 
01317   // objects allocated in Material Property List
01318   vtk3DSMatProp *m;
01319   // just walk the list of material properties, deleting vtk properties
01320   for (m = this->MatPropList; m != (vtk3DSMatProp *) NULL; m = (vtk3DSMatProp *) m->next)
01321     {
01322     m->aProperty->Delete();
01323     }
01324 
01325   // then delete the list structure
01326   VTK_LIST_KILL (this->MatPropList);
01327 
01328   if (this->FileName)
01329     {
01330     delete [] this->FileName;
01331     }
01332 }
01333 
01334 void vtk3DSOurImporter::PrintSelf(ostream& os, vtkIndent indent)
01335 {
01336   vtkImporter::PrintSelf(os,indent);
01337   os << indent << "File Name: " 
01338      << (this->FileName ? this->FileName : "(none)") << "\n";
01339 
01340   os << indent << "Compute Normals: " 
01341      << (this->ComputeNormals ? "On\n" : "Off\n");
01342 }
01343 
01344 
01345 
01346 
01347 
01348 

Generated on Sun Jun 22 12:13:09 2003 for Catmull Clark by doxygen 1.3.2