00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
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
00060 vtkObject* ret = vtkObjectFactory::CreateInstance("vtk3DSOurImporter");
00061 if(ret)
00062 {
00063 return (vtk3DSOurImporter*)ret;
00064 }
00065
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
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,
00083 0.0,
00084 0.0,
00085 0,
00086 "",
00087 0.0,
00088 "",
00089 0.0,
00090 NULL};
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
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
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
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
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
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
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
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
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
00403 static void list_insert (vtk3DSList **root, vtk3DSList *new_node)
00404 {
00405 new_node->next = *root;
00406 *root = new_node;
00407 }
00408
00409
00410
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
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
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
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
00819 (void)read_word(importer);
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
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
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
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
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
01189 i = 0;
01190 while ((name[i] == ' ' || name[i] == '"') && name[i] != '\0')
01191 {
01192 i++;
01193 }
01194 strcpy (tmp, &name[i]);
01195
01196
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
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
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
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
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
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
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
01313
01314 VTK_LIST_KILL (this->MeshList);
01315 VTK_LIST_KILL (this->MaterialList);
01316
01317
01318 vtk3DSMatProp *m;
01319
01320 for (m = this->MatPropList; m != (vtk3DSMatProp *) NULL; m = (vtk3DSMatProp *) m->next)
01321 {
01322 m->aProperty->Delete();
01323 }
01324
01325
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