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
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
00062 vtkObject* ret = vtkObjectFactory::CreateInstance("VTK3DSOurImporter");
00063 if(ret)
00064 {
00065 return (VTK3DSOurImporter*)ret;
00066 }
00067
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
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,
00085 0.0,
00086 0.0,
00087 0,
00088 "",
00089 0.0,
00090 "",
00091 0.0,
00092 NULL};
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
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
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
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
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
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
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
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
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
00405 static void list_insert (vtk3DSList **root, vtk3DSList *new_node)
00406 {
00407 new_node->next = *root;
00408 *root = new_node;
00409 }
00410
00411
00412
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
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
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
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
00821 (void)read_word(importer);
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
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
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
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
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
01191 i = 0;
01192 while ((name[i] == ' ' || name[i] == '"') && name[i] != '\0')
01193 {
01194 i++;
01195 }
01196 strcpy (tmp, &name[i]);
01197
01198
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
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
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
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
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
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
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
01315
01316 VTK_LIST_KILL (this->MeshList);
01317 VTK_LIST_KILL (this->MaterialList);
01318
01319
01320 vtk3DSMatProp *m;
01321
01322 for (m = this->MatPropList; m != (vtk3DSMatProp *) NULL; m = (vtk3DSMatProp *) m->next)
01323 {
01324 m->aProperty->Delete();
01325 }
01326
01327
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