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