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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 #ifndef __VCGLIB_IMPORT_OFF
00094 #define __VCGLIB_IMPORT_OFF
00095
00096 #include <fstream>
00097 #include <string>
00098 #include <vector>
00099 #include <assert.h>
00100 #include <vcg/space/color4.h>
00101 #include<vcg/complex/trimesh/allocate.h>
00102 #include <wrap/callback.h>
00103 #include <wrap/io_trimesh/io_mask.h>
00104
00105 namespace vcg
00106 {
00107 namespace tri
00108 {
00109 namespace io
00110 {
00111
00112
00117 template<class MESH_TYPE>
00118 class ImporterOFF
00119 {
00120 public:
00121
00122 typedef typename MESH_TYPE::VertexType VertexType;
00123 typedef typename MESH_TYPE::VertexIterator VertexIterator;
00124 typedef typename MESH_TYPE::VertexPointer VertexPointer;
00125 typedef typename MESH_TYPE::FaceType FaceType;
00126 typedef typename MESH_TYPE::FaceIterator FaceIterator;
00127 typedef typename MESH_TYPE::FacePointer FacePointer;
00128 typedef typename MESH_TYPE::CoordType CoordType;
00129 typedef typename MESH_TYPE::ScalarType ScalarType;
00130
00131
00132 enum OFFCodes {NoError=0, CantOpen, InvalidFile,
00133 InvalidFile_MissingOFF,
00134 UnsupportedFormat, ErrorNotTriangularFace,ErrorHighDimension,ErrorDegenerateFace};
00135
00141 static const char* ErrorMsg(int message_code)
00142 {
00143 static const char* error_msg[] =
00144 {
00145 "No errors", "Can't open file", "Invalid file",
00146 "Invalid file: OFF file should have in the first line the OFF keyword as a first token",
00147 "Unsupported format", "Face with more than 3 vertices","File with high dimensional vertexes are not supported", "Error Degenerate Face with less than 3 vertices" };
00148
00149 if(message_code>6 || message_code<0)
00150 return "Unknown error";
00151 else
00152 return error_msg[message_code];
00153 };
00154
00162 static bool LoadMask(const char *filename, int &loadmask)
00163 {
00164
00165
00166 loadmask=0;
00167 MESH_TYPE dummyMesh;
00168 return (Open(dummyMesh, filename, loadmask,0,true)==NoError);
00169 }
00170
00171 static int Open(MESH_TYPE &mesh, const char *filename,CallBackPos *cb=0)
00172 {
00173 int loadmask;
00174 return Open(mesh,filename,loadmask,cb);
00175 }
00176
00184 static int Open(MESH_TYPE &mesh, const char *filename, int &loadmask,
00185 CallBackPos *cb=0, bool onlyMaskFlag=false )
00186 {
00187 std::ifstream stream(filename);
00188 if (stream.fail())
00189 return CantOpen;
00190
00191 std::vector< std::string > tokens;
00192 TokenizeNextLine(stream, tokens);
00193
00194 bool isNormalDefined = false;
00195 bool isColorDefined = false;
00196 bool isTexCoordDefined = false;
00197 int dimension = 3;
00198 bool homogeneousComponents = false;
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 std::string header = tokens[0];
00226 if (header.rfind("OFF") != std::basic_string<char>::npos)
00227 {
00228 for (int u = static_cast<int>(header.rfind("OFF")-1); u>=0; u--)
00229 {
00230 if (header[u] == 'C') isColorDefined = true;
00231 else if (header[u] == 'N') isNormalDefined = true;
00232 else if (u>0 && header[u-1] == 'S' && header[u] == 'T') isTexCoordDefined = true;
00233 else if (header[u] == '4') homogeneousComponents = true;
00234 else if (header[u] == 'n') return ErrorHighDimension;
00235 }
00236 }
00237 else return InvalidFile_MissingOFF;
00238
00239
00240
00241 if(tokens.size()==1) TokenizeNextLine(stream, tokens);
00242 else tokens.erase(tokens.begin(),tokens.begin()+1);
00243
00244
00246
00247 loadmask = Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX;
00248
00249 if (isNormalDefined) loadmask |= Mask::IOM_VERTNORMAL;
00250 if (isTexCoordDefined) loadmask |= Mask::IOM_VERTTEXCOORD;
00251 if (isColorDefined) { loadmask |= Mask::IOM_VERTCOLOR;loadmask |= Mask::IOM_FACECOLOR;}
00252
00253
00254 if(onlyMaskFlag) return NoError;
00255
00256
00257 mesh.Clear();
00258
00259
00260 if(tokens.size() < 3)
00261 return InvalidFile;
00262
00263 unsigned int nVertices, nFaces, nEdges;
00264 nVertices = atoi(tokens[0].c_str());
00265 nFaces = atoi(tokens[1].c_str());
00266 nEdges = atoi(tokens[2].c_str());
00267
00268
00269 if (dimension != 3)
00270 return UnsupportedFormat;
00271
00272 if (homogeneousComponents)
00273 return UnsupportedFormat;
00274
00275
00277
00278 VertexIterator v_iter = Allocator<MESH_TYPE>::AddVertices(mesh, nVertices);
00279 TokenizeNextLine(stream, tokens);
00280 size_t k = 0;
00281
00282 for (unsigned int i=0; i<nVertices; i++, v_iter++)
00283 {
00284 if (cb && (i%1000)==0)
00285 cb(i*50/nVertices, "Vertex Loading");
00286
00287
00288 for (unsigned int j=0; j<3; j++)
00289 {
00290
00291 if (k == tokens.size())
00292 {
00293 TokenizeNextLine(stream, tokens);
00294 if (tokens.size() == 0)
00295 return InvalidFile;
00296 k = 0;
00297 }
00298
00299
00300 (*v_iter).P()[j] = (ScalarType) atof(tokens[k].c_str());
00301 k++;
00302 }
00303
00304 if (isNormalDefined)
00305 {
00306
00307 for (unsigned int j=0; j<3; j++)
00308 {
00309
00310 if (k == tokens.size())
00311 {
00312 TokenizeNextLine(stream, tokens);
00313 if (tokens.size() == 0)
00314 return InvalidFile;
00315 k = 0;
00316 }
00317
00318
00319 (*v_iter).N()[j] = (ScalarType) atof(tokens[k].c_str());
00320 k++;
00321 }
00322 }
00323
00324
00325
00326
00327 if (isColorDefined)
00328 {
00329
00330
00331 int nb_color_components = static_cast<int>(tokens.size())
00332 - static_cast<int>(k)
00333 - 2 * (isTexCoordDefined ? 1 : 0);
00334
00335 if (nb_color_components < 0 || nb_color_components > 4)
00336 return InvalidFile;
00337
00338
00339 if (nb_color_components > 0)
00340 loadmask |= Mask::IOM_VERTCOLOR;
00341
00342
00343 if (tri::HasPerVertexColor(mesh))
00344 {
00345
00346
00347 if (nb_color_components == 1)
00348 {
00349
00350 (*v_iter).C().Import(ColorMap(atoi(tokens[k].c_str())));
00351 }
00352 else if (nb_color_components == 3)
00353 {
00354
00355 if (tokens[k].find(".") == size_t(-1))
00356 {
00357
00358 unsigned char r =
00359 static_cast<unsigned char>(atoi(tokens[k].c_str()));
00360 unsigned char g =
00361 static_cast<unsigned char>(atoi(tokens[k+1].c_str()));
00362 unsigned char b =
00363 static_cast<unsigned char>(atoi(tokens[k+2].c_str()));
00364
00365 vcg::Color4b color(r, g, b, 255);
00366 (*v_iter).C().Import(color);
00367 }
00368 else
00369 {
00370
00371 float r = static_cast<float>(atof(tokens[k].c_str()));
00372 float g = static_cast<float>(atof(tokens[k+1].c_str()));
00373 float b = static_cast<float>(atof(tokens[k+2].c_str()));
00374
00375 vcg::Color4f color(r, g, b, 1.0);
00376 (*v_iter).C().Import(color);
00377 }
00378 }
00379 else if (nb_color_components == 4)
00380 {
00381
00382 if (tokens[k].find(".") == size_t(-1))
00383 {
00384
00385 unsigned char r =
00386 static_cast<unsigned char>(atoi(tokens[k].c_str()));
00387 unsigned char g =
00388 static_cast<unsigned char>(atoi(tokens[k+1].c_str()));
00389 unsigned char b =
00390 static_cast<unsigned char>(atoi(tokens[k+2].c_str()));
00391 unsigned char a =
00392 static_cast<unsigned char>(atoi(tokens[k+3].c_str()));
00393
00394 Color4b color(r, g, b, a);
00395 (*v_iter).C().Import(color);
00396 }
00397 else
00398 {
00399
00400 float r = static_cast<float>(atof(tokens[k].c_str()));
00401 float g = static_cast<float>(atof(tokens[k+1].c_str()));
00402 float b = static_cast<float>(atof(tokens[k+2].c_str()));
00403 float a = static_cast<float>(atof(tokens[k+3].c_str()));
00404
00405 vcg::Color4f color(r, g, b, a);
00406 (*v_iter).C().Import(color);
00407 }
00408 }
00409 }
00410
00411 k += nb_color_components;
00412 }
00413
00414 if (isTexCoordDefined)
00415 {
00416 for (unsigned int j=0; j<2; j++)
00417 {
00418
00419 if (k == tokens.size())
00420 {
00421 TokenizeNextLine(stream, tokens);
00422 if (tokens.size() == 0)
00423 return InvalidFile;
00424 k = 0;
00425 }
00426
00427 std::string str = tokens[k];
00428 k++;
00429
00430
00431 if (tri::HasPerWedgeTexCoord(mesh))
00432 {
00433
00434 }
00435 }
00436 }
00437 }
00438
00439
00441
00442 Allocator<MESH_TYPE>::AddFaces(mesh, nFaces);
00443 unsigned int f0=0;
00444 for (unsigned int f=0; f < nFaces; f++)
00445 {
00446 f0 = f;
00447 if (stream.fail())
00448 return InvalidFile;
00449
00450 if(cb && (f%1000)==0)
00451 cb(50+f*50/nFaces,"Face Loading");
00452
00453 TokenizeNextLine(stream, tokens);
00454 int vert_per_face = atoi(tokens[0].c_str());
00455 if(vert_per_face < 3)
00456 return ErrorDegenerateFace;
00457 k = 1;
00458 if (vert_per_face == 3)
00459 {
00460 for (int j = 0; j < 3; j++)
00461 {
00462 if (k == tokens.size())
00463 {
00464 TokenizeNextLine(stream, tokens);
00465 if (tokens.size() == 0) return InvalidFile;
00466 k = 0;
00467 }
00468
00469 mesh.face[f].V(j) = &(mesh.vert[ atoi(tokens[k].c_str()) ]);
00470 k++;
00471 }
00472 }
00473 else
00474 {
00475
00476 unsigned int trigs = vert_per_face-3;
00477 nFaces += trigs;
00478 Allocator<MESH_TYPE>::AddFaces(mesh, trigs);
00479 std::vector<int> vertIndices(vert_per_face);
00480 for (int j=0; j < vert_per_face; j++)
00481 {
00482 if (k == tokens.size())
00483 {
00484 TokenizeNextLine(stream, tokens);
00485 if (tokens.size() == 0) return InvalidFile;
00486 k = 0;
00487 }
00488 vertIndices[j] = atoi(tokens[k].c_str());
00489 k++;
00490 }
00491 if(vert_per_face==4)
00492 {
00493
00494
00495
00496 const CoordType &P0=mesh.vert[vertIndices[0]].cP();
00497 const CoordType &P1=mesh.vert[vertIndices[1]].cP();
00498 const CoordType &P2=mesh.vert[vertIndices[2]].cP();
00499 const CoordType &P3=mesh.vert[vertIndices[3]].cP();
00500
00501 CoordType N00 = Normal(P0,P1,P2);
00502 CoordType N01 = Normal(P0,P2,P3);
00503 CoordType N10 = Normal(P1,P2,P3);
00504 CoordType N11 = Normal(P1,P3,P0);
00505
00506 ScalarType Angle0Rad=Angle(N00,N01);
00507 ScalarType Angle1Rad=Angle(N10,N11);
00508
00509
00510
00511 bool qualityImprove = std::min(QualityRadii(P0,P1,P2),QualityRadii(P0,P2,P3)) < std::min(QualityRadii(P1,P2,P3),QualityRadii(P1,P3,P0));
00512 bool swapCauseFlip = (Angle1Rad > M_PI/2.0) && (Angle0Rad <M_PI/2.0);
00513 if(qualityImprove && ! swapCauseFlip)
00514 std::rotate(vertIndices.begin(), vertIndices.begin()+1, vertIndices.end());
00515
00516 }
00517
00518 for (int j=0; j<=vert_per_face-3; j++)
00519 {
00520 mesh.face[f+j].V(0) = &(mesh.vert[ vertIndices[0 ] ]);
00521 mesh.face[f+j].V(1) = &(mesh.vert[ vertIndices[1+j] ]);
00522 mesh.face[f+j].V(2) = &(mesh.vert[ vertIndices[2+j] ]);
00523 if (tri::HasPerFaceFlags(mesh)) {
00524
00525 if (j>0) mesh.face[f+j].SetF(0);
00526 if (j<vert_per_face-3) mesh.face[f+j].SetF(2);
00527 loadmask |= Mask::IOM_BITPOLYGONAL;
00528 }
00529 }
00530 f+=trigs;
00531 }
00532
00533
00534
00535
00536 if (isColorDefined && tri::HasPerFaceColor(mesh))
00537 {
00538 size_t color_elements = tokens.size() - vert_per_face-1;
00539
00540
00541 if (color_elements > 0)
00542 loadmask |= Mask::IOM_FACECOLOR;
00543
00544 switch (color_elements)
00545 {
00546 case 0:
00547 {
00548 for ( ; f0<=f; f0++)
00549 mesh.face[f0].C().Import(vcg::Color4f(.666f, .666f, .666f, .666f));
00550 break;
00551 }
00552 case 1:
00553 {
00554 for ( ; f0<=f; f0++)
00555 mesh.face[f0].C().Import( ColorMap( atoi(tokens[vert_per_face+1].c_str()) ) );
00556 break;
00557 }
00558 case 3:
00559 {
00560 if (tokens[vert_per_face+1].find('.')==size_t(-1))
00561 {
00562 int rgb[3];
00563 rgb[0] = atoi( tokens[vert_per_face+1].c_str() );
00564 rgb[1] = atoi( tokens[vert_per_face+2].c_str() );
00565 rgb[2] = atoi( tokens[vert_per_face+3].c_str() );
00566 for ( ; f0<=f; f0++)
00567 mesh.face[f0].C().SetRGB(rgb[0], rgb[1], rgb[2]);
00568 }
00569 else
00570 {
00571 float color[3];
00572 color[0] = (float) atof( tokens[vert_per_face+1].c_str() );
00573 color[1] = (float) atof( tokens[vert_per_face+2].c_str() );
00574 color[2] = (float) atof( tokens[vert_per_face+3].c_str() );
00575 for ( ; f0<=f; f0++)
00576 mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], 1.0f));
00577 }
00578 break;
00579 }
00580 case 4:
00581 {
00582 if (tokens[vert_per_face+1].find('.')==0)
00583 {
00584 unsigned char color[4];
00585 color[0] = (unsigned char) atoi(tokens[vert_per_face+1].c_str());
00586 color[1] = (unsigned char) atoi(tokens[vert_per_face+2].c_str());
00587 color[2] = (unsigned char) atoi(tokens[vert_per_face+3].c_str());
00588 color[3] = (unsigned char) atoi(tokens[vert_per_face+4].c_str());
00589 for ( ; f0<=f; f0++)
00590 mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], color[3]));
00591 }
00592 else
00593 {
00594 float color[4];
00595 color[0] = float( atof(tokens[vert_per_face+1].c_str()) );
00596 color[1] = float( atof(tokens[vert_per_face+2].c_str()) );
00597 color[2] = float( atof(tokens[vert_per_face+3].c_str()) );
00598 color[3] = float( atof(tokens[vert_per_face+4].c_str()) );
00599 for ( ; f0<=f; f0++)
00600 mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], color[3]));
00601 }
00602 break;
00603 }
00604 }
00605 }
00606 }
00607
00608 return NoError;
00609
00610 }
00611
00612 protected:
00613
00619 inline static const void TokenizeNextLine(std::ifstream &stream, std::vector< std::string > &tokens)
00620 {
00621 std::string line;
00622 do
00623 std::getline(stream, line, '\n');
00624 while (line[0] == '#' || line.length()==0);
00625
00626 size_t from = 0;
00627 size_t to = 0;
00628 size_t length = line.size();
00629 tokens.clear();
00630 do
00631 {
00632 while ( (line[from]==' ' || line[from] == '\t' || line[from] == '\r') && from!=length)
00633 from++;
00634 if(from!=length)
00635 {
00636 to = from+1;
00637 while ( (line[to]!=' ' && line[to] != '\t' || line[to] == '\r') && to!=length)
00638 to++;
00639 tokens.push_back(line.substr(from, to-from).c_str());
00640 from = to;
00641 }
00642 }
00643 while (from<length);
00644 }
00645
00651 static const vcg::Color4f ColorMap(int i)
00652 {
00653 static const float colorMap[148][4] =
00654 {
00655 { 1.0f, 1.0f, 1.0f, 1.0f },
00656 { 1.0f, 1.0f, 1.0f, 1.0f },
00657 { 1.0f, 1.0f, 1.0f, 1.0f },
00658 { 1.0f, 1.0f, 1.0f, 1.0f },
00659 { 1.0f, 1.0f, 1.0f, 1.0f },
00660 { 1.0f, 1.0f, 1.0f, 1.0f },
00661 { 0.7f, 0.7f, 0.7f, 0.7f },
00662 { 0.2f, 0.2f, 0.2f, 0.2f },
00663 { 0.9f, 0.9f, 0.9f, 0.9f },
00664 { 0.1f, 0.1f, 0.1f, 0.1f },
00665 { 0.1f, 0.1f, 0.1f, 0.1f },
00666 { 0.8f, 0.8f, 0.8f, 0.8f },
00667 { 0.7f, 0.7f, 0.7f, 0.7f },
00668 { 0.7f, 0.7f, 0.7f, 0.7f },
00669 { 0.0f, 0.0f, 0.0f, 0.0f },
00670 { 0.9f, 0.9f, 0.9f, 0.9f },
00671 { 0.2f, 0.2f, 0.2f, 0.2f },
00672 { 0.0f, 0.0f, 0.0f, 0.0f },
00673 { 0.75f, 0.75f, 0.75f, 0.75f },
00674 { 0.8f, 0.8f, 0.8f, 0.8f },
00675 { 0.8f, 0.8f, 0.8f, 0.8f },
00676 { 0.0f, 0.0f, 0.0f, 0.0f },
00677 { 0.0f, 0.0f, 0.0f, 0.0f },
00678 { 0.0f, 0.0f, 0.0f, 0.0f },
00679 { 0.0f, 0.0f, 0.0f, 0.0f },
00680 { 0.4f, 0.4f, 0.4f, 0.4f },
00681 { 0.4f, 0.4f, 0.4f, 0.4f },
00682 { 0.8f, 0.8f, 0.8f, 0.8f },
00683 { 0.8f, 0.8f, 0.8f, 0.8f },
00684 { 0.7f, 0.7f, 0.7f, 0.7f },
00685 { 0.7f, 0.7f, 0.7f, 0.7f },
00686 { 0.7f, 0.7f, 0.7f, 0.7f },
00687 { 0.7f, 0.7f, 0.7f, 0.7f },
00688 { 0.0f, 0.0f, 0.0f, 0.0f },
00689 { 0.9f, 0.9f, 0.9f, 0.9f },
00690 { 0.0f, 0.0f, 0.0f, 0.0f },
00691 { 0.0f, 0.0f, 0.0f, 0.0f },
00692 { 0.75f, 0.75f, 0.75f, 0.75f },
00693 { 0.8f, 0.8f, 0.8f, 0.8f },
00694 { 0.4f, 0.4f, 0.4f, 0.4f },
00695 { 0.0f, 0.0f, 0.0f, 0.0f },
00696 { 0.0f, 0.0f, 0.0f, 0.0f },
00697 { 0.4f, 0.4f, 0.4f, 0.4f },
00698 { 0.8f, 0.8f, 0.8f, 0.8f },
00699 { 0.7f, 0.7f, 0.7f, 0.7f },
00700 { 0.7f, 0.7f, 0.7f, 0.7f },
00701 { 0.0f, 0.0f, 0.0f, 0.0f },
00702 { 0.9f, 0.9f, 0.9f, 0.9f },
00703 { 0.0f, 0.0f, 0.0f, 0.0f },
00704 { 0.0f, 0.0f, 0.0f, 0.0f },
00705 { 0.75f, 0.75f, 0.75f, 0.75f },
00706 { 0.8f, 0.8f, 0.8f, 0.8f },
00707 { 0.4f, 0.4f, 0.4f, 0.4f },
00708 { 0.0f, 0.0f, 0.0f, 0.0f },
00709 { 0.0f, 0.0f, 0.0f, 0.0f },
00710 { 0.4f, 0.4f, 0.4f, 0.4f },
00711 { 0.8f, 0.8f, 0.8f, 0.8f },
00712 { 0.7f, 0.7f, 0.7f, 0.7f },
00713 { 0.7f, 0.7f, 0.7f, 0.7f },
00714 { 0.0f, 0.0f, 0.0f, 0.0f },
00715 { 0.9f, 0.9f, 0.9f, 0.9f },
00716 { 0.0f, 0.0f, 0.0f, 0.0f },
00717 { 0.0f, 0.0f, 0.0f, 0.0f },
00718 { 0.75f, 0.75f, 0.75f, 0.75f },
00719 { 0.8f, 0.8f, 0.8f, 0.8f },
00720 { 0.4f, 0.4f, 0.4f, 0.4f },
00721 { 0.0f, 0.0f, 0.0f, 0.0f },
00722 { 0.0f, 0.0f, 0.0f, 0.0f },
00723 { 0.4f, 0.4f, 0.4f, 0.4f },
00724 { 0.8f, 0.8f, 0.8f, 0.8f },
00725 { 1.0f, 1.0f, 1.0f, 1.0f },
00726 { 1.0f, 1.0f, 1.0f, 1.0f },
00727 { 1.0f, 1.0f, 1.0f, 1.0f },
00728 { 1.0f, 1.0f, 1.0f, 1.0f },
00729 { 1.0f, 1.0f, 1.0f, 1.0f },
00730 { 1.0f, 1.0f, 1.0f, 1.0f },
00731 { 0.05f, 0.05f, 0.05f, 0.05f },
00732 { 0.7f, 0.7f, 0.7f, 0.7f },
00733 { 0.2f, 0.2f, 0.2f, 0.2f },
00734 { 0.9f, 0.9f, 0.9f, 0.9f },
00735 { 0.0f, 0.0f, 0.0f, 0.0f },
00736 { 0.1f, 0.1f, 0.1f, 0.1f },
00737 { 0.8f, 0.8f, 0.8f, 0.8f },
00738 { 0.7f, 0.7f, 0.7f, 0.7f },
00739 { 0.7f, 0.7f, 0.7f, 0.7f },
00740 { 0.7f, 0.7f, 0.7f, 0.7f },
00741 { 0.7f, 0.7f, 0.7f, 0.7f },
00742 { 0.0f, 0.0f, 0.0f, 0.0f },
00743 { 0.0f, 0.0f, 0.0f, 0.0f },
00744 { 0.9f, 0.9f, 0.9f, 0.9f },
00745 { 0.9f, 0.9f, 0.9f, 0.9f },
00746 { 0.0f, 0.0f, 0.0f, 0.0f },
00747 { 0.0f, 0.0f, 0.0f, 0.0f },
00748 { 0.0f, 0.0f, 0.0f, 0.0f },
00749 { 0.0f, 0.0f, 0.0f, 0.0f },
00750 { 0.75f, 0.75f, 0.75f, 0.75f },
00751 { 0.75f, 0.75f, 0.75f, 0.75f },
00752 { 0.8f, 0.8f, 0.8f, 0.8f },
00753 { 0.8f, 0.8f, 0.8f, 0.8f },
00754 { 0.0f, 0.0f, 0.0f, 0.0f },
00755 { 0.0f, 0.0f, 0.0f, 0.0f },
00756 { 0.0f, 0.0f, 0.0f, 0.0f },
00757 { 0.0f, 0.0f, 0.0f, 0.0f },
00758 { 0.4f, 0.4f, 0.4f, 0.4f },
00759 { 0.4f, 0.4f, 0.4f, 0.4f },
00760 { 0.8f, 0.8f, 0.8f, 0.8f },
00761 { 0.8f, 0.8f, 0.8f, 0.8f },
00762 { 0.7f, 0.7f, 0.7f, 0.7f },
00763 { 0.7f, 0.7f, 0.7f, 0.7f },
00764 { 0.7f, 0.7f, 0.7f, 0.7f },
00765 { 0.7f, 0.7f, 0.7f, 0.7f },
00766 { 0.0f, 0.0f, 0.0f, 0.0f },
00767 { 0.9f, 0.9f, 0.9f, 0.9f },
00768 { 0.0f, 0.0f, 0.0f, 0.0f },
00769 { 0.0f, 0.0f, 0.0f, 0.0f },
00770 { 0.75f, 0.75f, 0.75f, 0.75f },
00771 { 0.8f, 0.8f, 0.8f, 0.8f },
00772 { 0.4f, 0.4f, 0.4f, 0.4f },
00773 { 0.0f, 0.0f, 0.0f, 0.0f },
00774 { 0.0f, 0.0f, 0.0f, 0.0f },
00775 { 0.4f, 0.4f, 0.4f, 0.4f },
00776 { 0.8f, 0.8f, 0.8f, 0.8f },
00777 { 0.7f, 0.7f, 0.7f, 0.7f },
00778 { 0.7f, 0.7f, 0.7f, 0.7f },
00779 { 0.0f, 0.0f, 0.0f, 0.0f },
00780 { 0.9f, 0.9f, 0.9f, 0.9f },
00781 { 0.0f, 0.0f, 0.0f, 0.0f },
00782 { 0.0f, 0.0f, 0.0f, 0.0f },
00783 { 0.75f, 0.75f, 0.75f, 0.75f },
00784 { 0.8f, 0.8f, 0.8f, 0.8f },
00785 { 0.4f, 0.4f, 0.4f, 0.4f },
00786 { 0.0f, 0.0f, 0.0f, 0.0f },
00787 { 0.0f, 0.0f, 0.0f, 0.0f },
00788 { 0.4f, 0.4f, 0.4f, 0.4f },
00789 { 0.8f, 0.8f, 0.8f, 0.8f },
00790 { 0.7f, 0.7f, 0.7f, 0.7f },
00791 { 0.7f, 0.7f, 0.7f, 0.7f },
00792 { 0.0f, 0.0f, 0.0f, 0.0f },
00793 { 0.9f, 0.9f, 0.9f, 0.9f },
00794 { 0.0f, 0.0f, 0.0f, 0.0f },
00795 { 0.0f, 0.0f, 0.0f, 0.0f },
00796 { 0.75f, 0.75f, 0.75f, 0.75f },
00797 { 0.8f, 0.8f, 0.8f, 0.8f },
00798 { 0.4f, 0.4f, 0.4f, 0.4f },
00799 { 0.0f, 0.0f, 0.0f, 0.0f },
00800 { 0.0f, 0.0f, 0.0f, 0.0f },
00801 { 0.4f, 0.4f, 0.4f, 0.4f },
00802 { 0.8f, 0.8f, 0.8f, 0.8f }
00803 };
00804 return Color4f(colorMap[i][0], colorMap[i][1], colorMap[i][2], colorMap[i][3]);
00805 }
00806 };
00807
00808 }
00809 }
00810 }
00811
00812 #endif //__VCGLIB_IMPORT_OFF