// @(#)root/eve:$Id: view3ds.C 26876 2008-12-12 14:45:40Z matevz $ // Author: Bertrand Bellenot // Loading and display of basic 3DS models. #include "TCanvas.h" #include "TStyle.h" #include "TFile.h" #include "TStopwatch.h" #include "TError.h" #include <math.h> #include <stdlib.h> #include <stdio.h> #include <string.h> class TEveTriangleSet; TEveTriangleSet *ts[2048]; // Believe3D Model file defines #define MAGICNUMBER 0xB3D0 // types of 3DS Chunks #define CHUNKMAIN 0x4D4D #define CHUNKMAINVERSION 0x0002 #define CHUNK3D 0x3D3D #define CHUNK3DVERSION 0x3D3E #define CHUNK3DOBJECT 0x4000 #define CHUNK3DOBJECTMESH 0x4100 #define CHUNK3DOBJECTMESHVERTICES 0x4110 #define CHUNK3DOBJECTMESHFACES 0x4120 #define CHUNK3DOBJECTMESHMATGROUP 0x4130 #define CHUNK3DOBJECTMESHMAPPING 0x4140 #define CHUNK3DMATERIAL 0xAFFF // Sub defines of MATERIAL #define MATNAME 0xA000 #define MATDIFFUSE 0xA020 #define MATSPECULAR 0xA030 #define MATTRANSPARENCY 0xA050 #define COLOR_F 0x0010 #define COLOR_24 0x0011 #define LIN_COLOR_24 0x0012 #define LIN_COLOR_F 0x0013 #define INT_PERCENTAGE 0x0030 #define FLOAT_PERCENTAGE 0x0031 ////////////////////////////////////// //The tMaterialInfo Struct ////////////////////////////////////// class Material { public: char name[256]; UChar_t color[3]; UShort_t transparency; Material() { sprintf(name, ""); color[0] = color[1] = color[2] = 0; transparency = 0; } ~Material() { } }; // Chunk structure typedef struct _Chunk { UShort_t idnum; UInt_t offset, len, endoffset; } Chunk; // vertex structure typedef struct _Vertex { Float_t x, y, z; Float_t u, v; } Vertex; // face structure typedef struct _Face { UInt_t v1, v2, v3; } Face; // model structure class Model { public: char name[256]; char matname[256]; Vertex *vlist; Face *flist; UInt_t numverts, numfaces; Model() { sprintf(name,""); sprintf(matname,""); vlist = 0; flist = 0; numverts = numfaces = 0; } ~Model() { if (vlist != 0) delete [] vlist; if (flist != 0) delete [] flist; } }; // chunk reading routines Int_t ReadChunk(FILE*, Chunk*); // data reading routines Int_t ReadMainChunk(FILE*); Int_t Read3DChunk(FILE*, UInt_t); Int_t ReadObjectChunk(FILE*, UInt_t); Int_t ReadMeshChunk(FILE*, UInt_t, char*); Int_t ReadVerticesChunk(FILE*); Int_t ReadFacesChunk(FILE*); Int_t ReadMappingChunk(FILE*); Int_t ReadASCIIZ(FILE*, char*); Int_t ReadMaterialChunk(FILE *, UInt_t); Int_t ReadColor(FILE *, UInt_t); Int_t ReadTransparency(FILE *, UInt_t); Int_t ReadObjectMaterial(FILE *); Int_t ConvertModel(); // global variables Int_t nummodels = 0; Model model = {"","",0,0,0,0}; Int_t nummaterials = 0; Material *material[1024]; //______________________________________________________________________________ Int_t Read3DSFile(const char *fname) { // main function FILE *infile; infile = fopen(fname, "rb"); if (infile == 0) { printf("Error : Input File Could Not Be Opened!\n"); return -1; } UShort_t magic = MAGICNUMBER; if (ReadMainChunk(infile) != 0) { printf("Error : Input File Could Not Be Read!\n"); } fclose(infile); return 0; } //______________________________________________________________________________ Int_t ReadChunk(FILE *f, Chunk *c) { // reads a chunk from an opened file if (feof(f)) return(-1); c->idnum = 0; c->offset = c->len = 0; c->offset = (UInt_t) ftell(f); fread(&c->idnum, sizeof(UShort_t), 1, f); fread(&c->len, sizeof(UInt_t), 1, f); c->endoffset = c->offset + c->len; return(0); } //______________________________________________________________________________ Int_t ReadMainChunk(FILE *f) { // handles the main body of the 3DS file Chunk chunk; ReadChunk(f, &chunk); if (chunk.idnum != CHUNKMAIN) return(-1); while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { if (chunk.idnum == CHUNK3D) { Read3DChunk(f, chunk.endoffset); } else { //printf("Debug : Unknown Chunk [Main Chunk] [0x%x]\n", chunk.idnum); fseek(f, chunk.offset + chunk.len, SEEK_SET); } } return 0; } //______________________________________________________________________________ Int_t Read3DChunk(FILE *f, UInt_t len) { // reads the 3D Edit Chunk Chunk chunk; while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { if (chunk.idnum == CHUNK3DOBJECT) { ReadObjectChunk(f, chunk.endoffset); fseek(f, chunk.endoffset, SEEK_SET); } else if (chunk.idnum == CHUNK3DMATERIAL) { ReadMaterialChunk(f, chunk.endoffset); fseek(f, chunk.endoffset, SEEK_SET); } else { if (chunk.endoffset < len) { //printf("Debug : Unknown Chunk [3D Chunk] [0x%x]\n", chunk.idnum); fseek(f, chunk.endoffset, SEEK_SET); } else { break; } } } return 0; } //______________________________________________________________________________ Int_t ReadMaterialChunk(FILE *f, UInt_t len) { // reads the Material sub-chunk of the 3D Edit Chunk Chunk chunk; char name[256]; material[nummaterials] = new Material(); while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { if (chunk.idnum == MATNAME) { ReadASCIIZ(f, name); strcpy(material[nummaterials]->name, name); fseek(f, chunk.endoffset, SEEK_SET); } else if (chunk.idnum == MATDIFFUSE) { ReadColor(f, chunk.endoffset); fseek(f, chunk.endoffset, SEEK_SET); } else if (chunk.idnum == MATTRANSPARENCY) { ReadTransparency(f, chunk.endoffset); fseek(f, chunk.endoffset, SEEK_SET); } else { if (chunk.endoffset < len) { //printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum); fseek(f, chunk.endoffset, SEEK_SET); } else { break; } } } nummaterials++; return 0; } //______________________________________________________________________________ Int_t ReadColor(FILE *f, UInt_t len) { // reads the Color property of the Material Chunk Chunk chunk; float fr, fg, fb; while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { if (chunk.idnum == LIN_COLOR_24) { fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f); fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f); fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f); fseek(f, chunk.endoffset, SEEK_SET); } else if (chunk.idnum == COLOR_24) { fread(&material[nummaterials]->color[0], sizeof(UChar_t), 1, f); fread(&material[nummaterials]->color[1], sizeof(UChar_t), 1, f); fread(&material[nummaterials]->color[2], sizeof(UChar_t), 1, f); fseek(f, chunk.endoffset, SEEK_SET); } else if (chunk.idnum == LIN_COLOR_F) { fread(&fr, sizeof(Float_t), 1, f); fread(&fg, sizeof(Float_t), 1, f); fread(&fb, sizeof(Float_t), 1, f); fseek(f, chunk.endoffset, SEEK_SET); } else if (chunk.idnum == COLOR_F) { fread(&fr, sizeof(Float_t), 1, f); fread(&fg, sizeof(Float_t), 1, f); fread(&fb, sizeof(Float_t), 1, f); fseek(f, chunk.endoffset, SEEK_SET); } else { if (chunk.endoffset < len) { //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum); fseek(f, chunk.endoffset, SEEK_SET); } else { break; } } } return 0; } //______________________________________________________________________________ Int_t ReadTransparency(FILE *f, UInt_t len) { // reads the Transparency property of the Material Chunk Chunk chunk; float ftransp; UShort_t stransp; while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { if (chunk.idnum == INT_PERCENTAGE) { fread(&stransp, sizeof(UShort_t), 1, f); material[nummaterials]->transparency = stransp; fseek(f, chunk.endoffset, SEEK_SET); } else if (chunk.idnum == FLOAT_PERCENTAGE) { fread(&ftransp, sizeof(float), 1, f); fseek(f, chunk.endoffset, SEEK_SET); } else { if (chunk.endoffset < len) { //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum); fseek(f, chunk.endoffset, SEEK_SET); } else { break; } } } return 0; } //______________________________________________________________________________ Int_t ReadObjectMaterial(FILE *f) { // reads the name of material associated to the current Chunk ReadASCIIZ(f, model.matname); return 0; } //______________________________________________________________________________ Int_t ReadObjectChunk(FILE *f, UInt_t len) { // reads the Object sub-chunk of the 3D Edit Chunk Chunk chunk; char name[256]; ReadASCIIZ(f, name); while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { if (chunk.idnum == CHUNK3DOBJECTMESH) { ReadMeshChunk(f, chunk.endoffset, name); } else { if (chunk.endoffset < len) { //printf("Debug : Unknown Chunk [Object Chunk] [0x%x]\n", chunk.idnum); fseek(f, chunk.endoffset, SEEK_SET); } else { break; } } } return 0; } //______________________________________________________________________________ Int_t ReadMeshChunk(FILE *f, UInt_t len, char *objname) { // reads the TriMesh sub-chunk of the Object Chunk Chunk chunk; model.vlist = 0; model.flist = 0; model.numverts = model.numfaces = 0; sprintf(model.name, "%s", objname); printf("Reading Mesh : %s\n", objname); while ((ReadChunk(f, &chunk) == 0) && (!feof(f))) { if (chunk.idnum == CHUNK3DOBJECTMESHVERTICES) { ReadVerticesChunk(f); } else if (chunk.idnum == CHUNK3DOBJECTMESHFACES) { ReadFacesChunk(f); } else if (chunk.idnum == CHUNK3DOBJECTMESHMAPPING) { ReadMappingChunk(f); } else if (chunk.idnum == CHUNK3DOBJECTMESHMATGROUP) { ReadObjectMaterial(f); } else { if (chunk.endoffset < len) { //printf("Debug : Unknown Chunk [Mesh Chunk] [0x%x]\n", chunk.idnum); fseek(f, chunk.endoffset, SEEK_SET); } else { break; } } } ConvertModel(); if (model.vlist != 0) delete [] model.vlist; if (model.flist != 0) delete [] model.flist; model.vlist = 0; model.flist = 0; model.numverts = model.numfaces = 0; sprintf(model.name,""); nummodels++; return 0; } //______________________________________________________________________________ Int_t ReadVerticesChunk(FILE *f) { // reads Vertex data of the TriMesh Chunk Int_t i; UShort_t numv = 0; Float_t x, y, z; fread(&numv, sizeof(UShort_t), 1, f); printf("Reading %i Vertices...", numv); model.vlist = new Vertex[numv]; if (model.vlist == 0) { for (i = 0; i < numv; i++) { fread(&x, sizeof(Float_t), 1, f); fread(&y, sizeof(Float_t), 1, f); fread(&z, sizeof(Float_t), 1, f); } printf("\nWarning : Insufficient Memory to Load Vertices!\n"); return -1; } for (i = 0; i < numv; i++) { fread(&model.vlist[i].x, sizeof(Float_t), 1, f); fread(&model.vlist[i].y, sizeof(Float_t), 1, f); fread(&model.vlist[i].z, sizeof(Float_t), 1, f); } model.numverts = (UInt_t) numv; printf("Done!\n"); return 0; } //______________________________________________________________________________ Int_t ReadFacesChunk(FILE *f) { // reads Face data of the TriMesh Chunk Int_t i; UShort_t numf = 0, v1, v2, v3, attr; fread(&numf, sizeof(UShort_t), 1, f); printf("Reading %i Faces...", numf); model.flist = new Face[numf]; if (model.flist == 0) { for (i = 0; i < numf; i++) { fread(&v1, sizeof(UShort_t), 1, f); fread(&v2, sizeof(UShort_t), 1, f); fread(&v3, sizeof(UShort_t), 1, f); fread(&attr, sizeof(UShort_t), 1, f); } printf("\nWarning : Insufficient Memory to Load Faces!\n"); return -1; } for (i = 0; i < numf; i++) { fread(&v1, sizeof(UShort_t), 1, f); fread(&v2, sizeof(UShort_t), 1, f); fread(&v3, sizeof(UShort_t), 1, f); fread(&attr, sizeof(UShort_t), 1, f); model.flist[i].v1 = (UInt_t)(v1); model.flist[i].v2 = (UInt_t)(v2); model.flist[i].v3 = (UInt_t)(v3); } model.numfaces = (UInt_t)(numf); printf("Done!\n"); return 0; } //______________________________________________________________________________ Int_t ReadMappingChunk(FILE *f) { // reads Texture Mapping data of the TriMesh Chunk UShort_t numuv = 0, i; Float_t u, v; fread(&numuv, sizeof(UShort_t), 1, f); printf("Reading %i Texture Coordinates...", numuv); if (numuv != model.numverts) { for (i = 0; i < numuv; i++) { fread(&u, sizeof(Float_t), 1, f); fread(&v, sizeof(Float_t), 1, f); } printf("\nWarning : Number of Vertices and Mapping Data do not match!\n"); return -1; } for (i = 0; i < numuv; i++) { fread(&model.vlist[i].u, sizeof(Float_t), 1, f); fread(&model.vlist[i].v, sizeof(Float_t), 1, f); } printf("Done!\n"); return 0; } //______________________________________________________________________________ Int_t ReadASCIIZ(FILE *f, char *name) { // reads a null-terminated string from the given file char c = -1; Int_t index = 0; do { fread(&c, sizeof(char), 1, f); name[index] = c; index++; if (index == 255) { name[index] = 0; c = 0; } } while ((c != 0) && (!feof(f))); return 0; } //______________________________________________________________________________ Int_t ConvertModel() { // Convert from Model structure to TEveTriangleSet Int_t i; ts[nummodels] = new TEveTriangleSet(model.numverts, model.numfaces); if (ts[nummodels] == 0) return -1; for (i=0; i<model.numverts; ++i) { ts[nummodels]->SetVertex(i, model.vlist[i].x, model.vlist[i].y, model.vlist[i].z); } for (i=0; i<model.numfaces; ++i) { ts[nummodels]->SetTriangle(i, model.flist[i].v1, model.flist[i].v2, model.flist[i].v3); } ts[nummodels]->SetName(model.name); ts[nummodels]->SetMainTransparency(0); ts[nummodels]->SetMainColor(0); for (i = 0; i < nummaterials; i++) { if (strcmp(model.matname, material[i]->name) == 0) { ts[nummodels]->SetMainTransparency(material[i]->transparency); ts[nummodels]->SetMainColorRGB(material[i]->color[0], material[i]->color[1], material[i]->color[2]); break; } } return 0; } //______________________________________________________________________________ void view3ds(const char *fname = "nasashuttle.3ds") { // Main. TEveManager::Create(); Int_t i; for (i=0;i<2048;i++) ts[i] = 0; for (i=0;i<1024;i++) material[i] = 0; model.vlist = 0; model.flist = 0; nummodels = 0; if (Read3DSFile(fname) == 0) { TEveTriangleSet* parent = new TEveTriangleSet(0, 0); parent->SetName(fname); gEve->AddElement(parent); for (i=0;i<nummodels;i++) { if (ts[i]) { ts[i]->GenerateTriangleNormals(); ts[i]->RefMainTrans().RotateLF(1, 2, TMath::Pi()); gEve->AddElement(ts[i], parent); } } gEve->Redraw3D(kTRUE); } for (i = 0; i < nummaterials; i++) if (material[i] != 0) delete material[i]; } view3ds.C:1 view3ds.C:2 view3ds.C:3 view3ds.C:4 view3ds.C:5 view3ds.C:6 view3ds.C:7 view3ds.C:8 view3ds.C:9 view3ds.C:10 view3ds.C:11 view3ds.C:12 view3ds.C:13 view3ds.C:14 view3ds.C:15 view3ds.C:16 view3ds.C:17 view3ds.C:18 view3ds.C:19 view3ds.C:20 view3ds.C:21 view3ds.C:22 view3ds.C:23 view3ds.C:24 view3ds.C:25 view3ds.C:26 view3ds.C:27 view3ds.C:28 view3ds.C:29 view3ds.C:30 view3ds.C:31 view3ds.C:32 view3ds.C:33 view3ds.C:34 view3ds.C:35 view3ds.C:36 view3ds.C:37 view3ds.C:38 view3ds.C:39 view3ds.C:40 view3ds.C:41 view3ds.C:42 view3ds.C:43 view3ds.C:44 view3ds.C:45 view3ds.C:46 view3ds.C:47 view3ds.C:48 view3ds.C:49 view3ds.C:50 view3ds.C:51 view3ds.C:52 view3ds.C:53 view3ds.C:54 view3ds.C:55 view3ds.C:56 view3ds.C:57 view3ds.C:58 view3ds.C:59 view3ds.C:60 view3ds.C:61 view3ds.C:62 view3ds.C:63 view3ds.C:64 view3ds.C:65 view3ds.C:66 view3ds.C:67 view3ds.C:68 view3ds.C:69 view3ds.C:70 view3ds.C:71 view3ds.C:72 view3ds.C:73 view3ds.C:74 view3ds.C:75 view3ds.C:76 view3ds.C:77 view3ds.C:78 view3ds.C:79 view3ds.C:80 view3ds.C:81 view3ds.C:82 view3ds.C:83 view3ds.C:84 view3ds.C:85 view3ds.C:86 view3ds.C:87 view3ds.C:88 view3ds.C:89 view3ds.C:90 view3ds.C:91 view3ds.C:92 view3ds.C:93 view3ds.C:94 view3ds.C:95 view3ds.C:96 view3ds.C:97 view3ds.C:98 view3ds.C:99 view3ds.C:100 view3ds.C:101 view3ds.C:102 view3ds.C:103 view3ds.C:104 view3ds.C:105 view3ds.C:106 view3ds.C:107 view3ds.C:108 view3ds.C:109 view3ds.C:110 view3ds.C:111 view3ds.C:112 view3ds.C:113 view3ds.C:114 view3ds.C:115 view3ds.C:116 view3ds.C:117 view3ds.C:118 view3ds.C:119 view3ds.C:120 view3ds.C:121 view3ds.C:122 view3ds.C:123 view3ds.C:124 view3ds.C:125 view3ds.C:126 view3ds.C:127 view3ds.C:128 view3ds.C:129 view3ds.C:130 view3ds.C:131 view3ds.C:132 view3ds.C:133 view3ds.C:134 view3ds.C:135 view3ds.C:136 view3ds.C:137 view3ds.C:138 view3ds.C:139 view3ds.C:140 view3ds.C:141 view3ds.C:142 view3ds.C:143 view3ds.C:144 view3ds.C:145 view3ds.C:146 view3ds.C:147 view3ds.C:148 view3ds.C:149 view3ds.C:150 view3ds.C:151 view3ds.C:152 view3ds.C:153 view3ds.C:154 view3ds.C:155 view3ds.C:156 view3ds.C:157 view3ds.C:158 view3ds.C:159 view3ds.C:160 view3ds.C:161 view3ds.C:162 view3ds.C:163 view3ds.C:164 view3ds.C:165 view3ds.C:166 view3ds.C:167 view3ds.C:168 view3ds.C:169 view3ds.C:170 view3ds.C:171 view3ds.C:172 view3ds.C:173 view3ds.C:174 view3ds.C:175 view3ds.C:176 view3ds.C:177 view3ds.C:178 view3ds.C:179 view3ds.C:180 view3ds.C:181 view3ds.C:182 view3ds.C:183 view3ds.C:184 view3ds.C:185 view3ds.C:186 view3ds.C:187 view3ds.C:188 view3ds.C:189 view3ds.C:190 view3ds.C:191 view3ds.C:192 view3ds.C:193 view3ds.C:194 view3ds.C:195 view3ds.C:196 view3ds.C:197 view3ds.C:198 view3ds.C:199 view3ds.C:200 view3ds.C:201 view3ds.C:202 view3ds.C:203 view3ds.C:204 view3ds.C:205 view3ds.C:206 view3ds.C:207 view3ds.C:208 view3ds.C:209 view3ds.C:210 view3ds.C:211 view3ds.C:212 view3ds.C:213 view3ds.C:214 view3ds.C:215 view3ds.C:216 view3ds.C:217 view3ds.C:218 view3ds.C:219 view3ds.C:220 view3ds.C:221 view3ds.C:222 view3ds.C:223 view3ds.C:224 view3ds.C:225 view3ds.C:226 view3ds.C:227 view3ds.C:228 view3ds.C:229 view3ds.C:230 view3ds.C:231 view3ds.C:232 view3ds.C:233 view3ds.C:234 view3ds.C:235 view3ds.C:236 view3ds.C:237 view3ds.C:238 view3ds.C:239 view3ds.C:240 view3ds.C:241 view3ds.C:242 view3ds.C:243 view3ds.C:244 view3ds.C:245 view3ds.C:246 view3ds.C:247 view3ds.C:248 view3ds.C:249 view3ds.C:250 view3ds.C:251 view3ds.C:252 view3ds.C:253 view3ds.C:254 view3ds.C:255 view3ds.C:256 view3ds.C:257 view3ds.C:258 view3ds.C:259 view3ds.C:260 view3ds.C:261 view3ds.C:262 view3ds.C:263 view3ds.C:264 view3ds.C:265 view3ds.C:266 view3ds.C:267 view3ds.C:268 view3ds.C:269 view3ds.C:270 view3ds.C:271 view3ds.C:272 view3ds.C:273 view3ds.C:274 view3ds.C:275 view3ds.C:276 view3ds.C:277 view3ds.C:278 view3ds.C:279 view3ds.C:280 view3ds.C:281 view3ds.C:282 view3ds.C:283 view3ds.C:284 view3ds.C:285 view3ds.C:286 view3ds.C:287 view3ds.C:288 view3ds.C:289 view3ds.C:290 view3ds.C:291 view3ds.C:292 view3ds.C:293 view3ds.C:294 view3ds.C:295 view3ds.C:296 view3ds.C:297 view3ds.C:298 view3ds.C:299 view3ds.C:300 view3ds.C:301 view3ds.C:302 view3ds.C:303 view3ds.C:304 view3ds.C:305 view3ds.C:306 view3ds.C:307 view3ds.C:308 view3ds.C:309 view3ds.C:310 view3ds.C:311 view3ds.C:312 view3ds.C:313 view3ds.C:314 view3ds.C:315 view3ds.C:316 view3ds.C:317 view3ds.C:318 view3ds.C:319 view3ds.C:320 view3ds.C:321 view3ds.C:322 view3ds.C:323 view3ds.C:324 view3ds.C:325 view3ds.C:326 view3ds.C:327 view3ds.C:328 view3ds.C:329 view3ds.C:330 view3ds.C:331 view3ds.C:332 view3ds.C:333 view3ds.C:334 view3ds.C:335 view3ds.C:336 view3ds.C:337 view3ds.C:338 view3ds.C:339 view3ds.C:340 view3ds.C:341 view3ds.C:342 view3ds.C:343 view3ds.C:344 view3ds.C:345 view3ds.C:346 view3ds.C:347 view3ds.C:348 view3ds.C:349 view3ds.C:350 view3ds.C:351 view3ds.C:352 view3ds.C:353 view3ds.C:354 view3ds.C:355 view3ds.C:356 view3ds.C:357 view3ds.C:358 view3ds.C:359 view3ds.C:360 view3ds.C:361 view3ds.C:362 view3ds.C:363 view3ds.C:364 view3ds.C:365 view3ds.C:366 view3ds.C:367 view3ds.C:368 view3ds.C:369 view3ds.C:370 view3ds.C:371 view3ds.C:372 view3ds.C:373 view3ds.C:374 view3ds.C:375 view3ds.C:376 view3ds.C:377 view3ds.C:378 view3ds.C:379 view3ds.C:380 view3ds.C:381 view3ds.C:382 view3ds.C:383 view3ds.C:384 view3ds.C:385 view3ds.C:386 view3ds.C:387 view3ds.C:388 view3ds.C:389 view3ds.C:390 view3ds.C:391 view3ds.C:392 view3ds.C:393 view3ds.C:394 view3ds.C:395 view3ds.C:396 view3ds.C:397 view3ds.C:398 view3ds.C:399 view3ds.C:400 view3ds.C:401 view3ds.C:402 view3ds.C:403 view3ds.C:404 view3ds.C:405 view3ds.C:406 view3ds.C:407 view3ds.C:408 view3ds.C:409 view3ds.C:410 view3ds.C:411 view3ds.C:412 view3ds.C:413 view3ds.C:414 view3ds.C:415 view3ds.C:416 view3ds.C:417 view3ds.C:418 view3ds.C:419 view3ds.C:420 view3ds.C:421 view3ds.C:422 view3ds.C:423 view3ds.C:424 view3ds.C:425 view3ds.C:426 view3ds.C:427 view3ds.C:428 view3ds.C:429 view3ds.C:430 view3ds.C:431 view3ds.C:432 view3ds.C:433 view3ds.C:434 view3ds.C:435 view3ds.C:436 view3ds.C:437 view3ds.C:438 view3ds.C:439 view3ds.C:440 view3ds.C:441 view3ds.C:442 view3ds.C:443 view3ds.C:444 view3ds.C:445 view3ds.C:446 view3ds.C:447 view3ds.C:448 view3ds.C:449 view3ds.C:450 view3ds.C:451 view3ds.C:452 view3ds.C:453 view3ds.C:454 view3ds.C:455 view3ds.C:456 view3ds.C:457 view3ds.C:458 view3ds.C:459 view3ds.C:460 view3ds.C:461 view3ds.C:462 view3ds.C:463 view3ds.C:464 view3ds.C:465 view3ds.C:466 view3ds.C:467 view3ds.C:468 view3ds.C:469 view3ds.C:470 view3ds.C:471 view3ds.C:472 view3ds.C:473 view3ds.C:474 view3ds.C:475 view3ds.C:476 view3ds.C:477 view3ds.C:478 view3ds.C:479 view3ds.C:480 view3ds.C:481 view3ds.C:482 view3ds.C:483 view3ds.C:484 view3ds.C:485 view3ds.C:486 view3ds.C:487 view3ds.C:488 view3ds.C:489 view3ds.C:490 view3ds.C:491 view3ds.C:492 view3ds.C:493 view3ds.C:494 view3ds.C:495 view3ds.C:496 view3ds.C:497 view3ds.C:498 view3ds.C:499 view3ds.C:500 view3ds.C:501 view3ds.C:502 view3ds.C:503 view3ds.C:504 view3ds.C:505 view3ds.C:506 view3ds.C:507 view3ds.C:508 view3ds.C:509 view3ds.C:510 view3ds.C:511 view3ds.C:512 view3ds.C:513 view3ds.C:514 view3ds.C:515 view3ds.C:516 view3ds.C:517 view3ds.C:518 view3ds.C:519 view3ds.C:520 view3ds.C:521 view3ds.C:522 view3ds.C:523 view3ds.C:524 view3ds.C:525 view3ds.C:526 view3ds.C:527 view3ds.C:528 view3ds.C:529 view3ds.C:530 view3ds.C:531 view3ds.C:532 view3ds.C:533 view3ds.C:534 view3ds.C:535 view3ds.C:536 view3ds.C:537 view3ds.C:538 view3ds.C:539 view3ds.C:540 view3ds.C:541 view3ds.C:542 view3ds.C:543 view3ds.C:544 view3ds.C:545 view3ds.C:546 view3ds.C:547 view3ds.C:548 view3ds.C:549 view3ds.C:550 view3ds.C:551 view3ds.C:552 view3ds.C:553 view3ds.C:554 view3ds.C:555 view3ds.C:556 view3ds.C:557 view3ds.C:558 view3ds.C:559 view3ds.C:560 view3ds.C:561 view3ds.C:562 view3ds.C:563 view3ds.C:564 view3ds.C:565 view3ds.C:566 view3ds.C:567 view3ds.C:568 view3ds.C:569 view3ds.C:570 view3ds.C:571 view3ds.C:572 view3ds.C:573 view3ds.C:574 view3ds.C:575 view3ds.C:576 view3ds.C:577 view3ds.C:578 view3ds.C:579 view3ds.C:580 view3ds.C:581 view3ds.C:582 |
|