Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

vtk3DSOurImporter.cxx

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

Generated on Thu Jul 3 16:54:23 2003 for Sq3Subdivision by doxygen1.2.18