00001 #include "PLYIO.hpp"
00002
00003 #include <cstring>
00004 #include <sstream>
00005 #include <cassert>
00006
00007 using std::stringstream;
00008
00009 #include <boost/algorithm/string.hpp>
00010 #include <boost/progress.hpp>
00011
00012
00013 using boost::algorithm::to_lower;
00014 using boost::algorithm::is_equal;
00015
00016 namespace lssr
00017 {
00018
00019 PLYIO::PLYIO()
00020 {
00021 m_vertices = 0;
00022 m_normals = 0;
00023 m_colors = 0;
00024 m_indices = 0;
00025 m_binary = false;;
00026
00027 m_numberOfVertices = 0;
00028 m_numberOfNormals = 0;
00029 m_numberOfFaces = 0;
00030 }
00031
00032
00033 PLYIO::~PLYIO()
00034 {
00035
00036 }
00037
00038
00039 float* PLYIO::getVertexArray(size_t &n)
00040 {
00041 if(m_vertices)
00042 {
00043 n = m_numberOfVertices;
00044 }
00045 else
00046 {
00047 n = 0;
00048 }
00049 return m_vertices;
00050 }
00051
00052 float* PLYIO::getNormalArray(size_t &n)
00053 {
00054 if(m_normals)
00055 {
00056 n = m_numberOfVertices;
00057 }
00058 else
00059 {
00060 n = 0;
00061 }
00062 return m_normals;
00063 }
00064
00065 float* PLYIO::getColorArray(size_t &n)
00066 {
00067 if(m_colors)
00068 {
00069 n = m_numberOfVertices;
00070 }
00071 else
00072 {
00073 n = 0;
00074 }
00075 return m_colors;
00076 }
00077
00078 unsigned int* PLYIO::getIndexArray(size_t &n)
00079 {
00080 if(m_indices)
00081 {
00082 n = m_numberOfFaces;
00083 }
00084 else
00085 {
00086 n = 0;
00087 }
00088 return m_indices;
00089 }
00090
00091 void PLYIO::setVertexArray(float* array, size_t n)
00092 {
00093 m_vertices = array;
00094 m_numberOfVertices = n;
00095 }
00096
00097 void PLYIO::setNormalArray(float* array, size_t n)
00098 {
00099 m_normals = array;
00100 m_numberOfNormals = n;
00101 }
00102
00103 void PLYIO::setIndexArray(unsigned int* array, size_t n)
00104 {
00105 m_indices = array;
00106 m_numberOfFaces = n;
00107 }
00108
00109 void PLYIO::setColorArray(float* array, size_t n)
00110 {
00111 m_colors = array;
00112 assert(n == m_numberOfVertices);
00113 }
00114
00115 void PLYIO::save(string filename, bool binary)
00116 {
00117
00118 m_binary = binary;
00119
00120
00121 ofstream out(filename.c_str());
00122
00123 if(out.good())
00124 {
00125 writeHeader(out);
00126 writeElements(out);
00127 }
00128 else
00129 {
00130 cout << "PLYIO::save(): Unable to open file '"
00131 << filename << "'." << endl;
00132 }
00133
00134
00135 out.close();
00136 }
00137
00138 void PLYIO::read(string filename)
00139 {
00140 ifstream in(filename.c_str());
00141
00142 if(in.good())
00143 {
00144 deleteBuffers();
00145 readHeader(in);
00146 loadElements(in);
00147 }
00148 else
00149 {
00150 cout << "PLYIO::read(): Unable to open file '"
00151 << filename << "'." << endl;
00152 }
00153
00154 }
00155
00156 void PLYIO::readHeader(ifstream& in)
00157 {
00158
00159 char line[1024];
00160
00161
00162 in.getline(line, 1024);
00163 string ply_tag(line);
00164
00165
00166 if(ply_tag.compare("ply") != 0)
00167 {
00168 cout << "PLYIO::readHeader(): No PLY tag in first line." << endl;
00169 return;
00170 }
00171
00172
00173 do
00174 {
00175 in.getline(line, 1024);
00176 }
00177 while(parseHeaderLine(line));
00178 }
00179
00180 bool PLYIO::parseHeaderLine(const char* line)
00181 {
00182
00183 string line_str(line);
00184
00185
00186 to_lower(line_str);
00187
00188
00189 if(line_str.compare("end_header") == 0)
00190 {
00191 return false;
00192 }
00193 else
00194 {
00195
00196 stringstream ss(line_str);
00197
00198
00199 string element_dscr;
00200 ss >> element_dscr;
00201
00202
00203 if(element_dscr.compare("comment") == 0)
00204 {
00205
00206 return true;
00207 }
00208 else if(element_dscr.compare("format") == 0)
00209 {
00210
00211 string format;
00212 ss >> format;
00213 if(format.compare("ascii") == 0)
00214 {
00215 m_binary = false;
00216 return true;
00217 }
00218 else if(format.compare("binary_little_endian") == 0)
00219 {
00220 m_binary = true;
00221 return true;
00222 }
00223 else if(format.compare("binary_big_endian") == 0)
00224 {
00225 m_binary = true;
00226 cout << "PLYIO::parseHeaderLine(): Error: Big endianess is not yet supported." << endl;
00227
00228 return false;
00229 }
00230 else
00231 {
00232 cout << "PLYIO::parseHeaderLine(): Error: Unknown format'"
00233 << format << "'." << endl;
00234 return false;
00235 }
00236
00237 }
00238 else if(element_dscr.compare("element") == 0)
00239 {
00240
00241 size_t element_count;
00242 string element_name;
00243 ss >> element_name >> element_count;
00244
00245
00246 m_elements.push_back(new PLYElement(element_name, element_count));
00247
00248
00249 return true;
00250 }
00251 else if(element_dscr.compare("property") == 0)
00252 {
00253 assert(m_elements.size() > 0);
00254
00255 string type;
00256 ss >> type;
00257 if(type.compare("list") == 0)
00258 {
00259 string count_type, value_type, property_name;
00260 ss >> count_type >> value_type >> property_name;
00261
00262 (m_elements.back())->addProperty(property_name, value_type, count_type);
00263 }
00264 else
00265 {
00266 string property_name;
00267 ss >> property_name;
00268 (m_elements.back())->addProperty(property_name, type);
00269 }
00270
00271 return true;
00272 }
00273 else
00274 {
00275
00276 cout << "PLYIO::parseHeaderLine(): Error: Invalid header line: '"
00277 << line_str << endl;
00278 return false;
00279 }
00280 }
00281
00282 }
00283
00284 void PLYIO::loadElements(ifstream &in)
00285 {
00286
00287 vector<PLYElement*>::iterator it;
00288 PLYElement* current_element;
00289
00290 for(it = m_elements.begin(); it != m_elements.end(); it++)
00291 {
00292 current_element = *it;
00293 string element_name = current_element->getName();
00294 if(isSupported(element_name))
00295 {
00296
00297
00298
00299 if(element_name == "vertex")
00300 {
00301
00302
00303 if(m_binary)
00304 {
00305 readVerticesBinary(in, current_element);
00306 }
00307 else
00308 {
00309 readVerticesASCII(in, current_element);
00310 }
00311 }
00312 else if (element_name == "face")
00313 {
00314 if(m_binary)
00315 {
00316 readFacesBinary(in, current_element);
00317 }
00318 else
00319 {
00320 readFacesASCII(in, current_element);
00321 }
00322 }
00323 else if (element_name == "normal")
00324 {
00325 if(m_binary)
00326 {
00327 readNormalsBinary(in, current_element);
00328 }
00329 else
00330 {
00331 readNormalsASCII(in, current_element);
00332 }
00333 }
00334 else
00335 {
00336 cout << "PLYIO::loadElements(): Warning: Unknown element '"
00337 << element_name << "'." << endl;
00338 }
00339 }
00340 else
00341 {
00342
00343 if(m_binary)
00344 {
00345 cout << "ERROR: SKIPPING OF UNSUPPORTED ELEMENTS NOT YET IMPLEMENTED. DO IT NOW!!!" << endl;
00346 }
00347 else
00348 {
00349
00350
00351 char buffer[1024];
00352 for(size_t i = 0; i < current_element->getCount(); i++)
00353 {
00354 in.getline(buffer, 1024);
00355 }
00356 }
00357 }
00358 }
00359 }
00360
00361 void PLYIO::printElementsInHeader()
00362 {
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 }
00382
00383 void PLYIO::writeHeader(ofstream& out)
00384 {
00385
00386 out << "ply" << endl;
00387
00388
00389 if(m_binary)
00390 {
00391 out << "format binary_little_endian 1.0" << endl;
00392 }
00393 else
00394 {
00395 out << "format ascii 1.0" << endl;
00396 }
00397
00398
00399 for(size_t i = 0; i < m_elements.size(); i++)
00400 {
00401 PLYElement* element = m_elements[i];
00402 out << "element "
00403 << element->getName() << " "
00404 << element->getCount() << endl;
00405 element->printProperties(out);
00406 }
00407
00408
00409 out << "end_header" << endl;
00410 }
00411
00412 void PLYIO::writeElements(ofstream &out)
00413 {
00414
00415
00416 for(size_t i = 0; i < m_elements.size(); i++)
00417 {
00418 if(m_elements[i]->getName() == "vertex")
00419 {
00420 m_binary ? writeVerticesBinary(out, m_elements[i])
00421 : writeVerticesASCII(out, m_elements[i]);
00422 }
00423
00424 if(m_elements[i]->getName() == "face")
00425 {
00426
00427 m_binary ? writeFacesBinary(out, m_elements[i]) : writeFacesASCII(out, m_elements[i]);
00428 }
00429
00430 if(m_elements[i]->getName() == "normal")
00431 {
00432 m_binary ? writeNormalsBinary(out, m_elements[i]) : writeNormalsASCII(out, m_elements[i]);
00433 }
00434 }
00435 }
00436
00437 void PLYIO::writeVerticesASCII(ofstream &out, PLYElement *e)
00438 {
00439 assert(m_vertices);
00440
00441 vector<Property*>::iterator current, last;
00442 string property_name;
00443
00444 for(size_t i = 0; i < m_numberOfVertices; i++)
00445 {
00446 size_t vertex_pointer = i * 3;
00447
00448
00449
00450
00451
00452
00453 current = e->getFirstProperty();
00454 last = e->getLastProperty();
00455
00456 while(current != last)
00457 {
00458 property_name = (*current)->getName();
00459 if(property_name == "x")
00460 {
00461 out << m_vertices[vertex_pointer] << " ";
00462 }
00463 else if (property_name == "y")
00464 {
00465 out << m_vertices[vertex_pointer + 1] << " ";
00466 }
00467 else if (property_name == "z")
00468 {
00469 out << m_vertices[vertex_pointer + 2] << " ";
00470 }
00471 else if (property_name == "r")
00472 {
00473 assert(m_colors);
00474 out << m_colors[vertex_pointer] << " ";
00475 }
00476 else if (property_name == "g")
00477 {
00478 assert(m_colors);
00479 out << m_colors[vertex_pointer + 1] << " ";
00480 }
00481 else if (property_name == "b")
00482 {
00483 assert(m_colors);
00484 out << m_colors[vertex_pointer + 2] << " ";
00485 }
00486 current++;
00487 }
00488
00489 out << endl;
00490 }
00491 }
00492
00493 void PLYIO::writeFacesASCII(ofstream &out, PLYElement *e)
00494 {
00495 assert(m_indices);
00496
00497 for(size_t i = 0; i < m_numberOfFaces; i++)
00498 {
00499 int index_pointer = i * 3;
00500
00501 out << "3 ";
00502 out << m_indices[index_pointer] << " "
00503 << m_indices[index_pointer + 1] << " "
00504 << m_indices[index_pointer + 2] << endl;
00505 }
00506 }
00507
00508 void PLYIO::writeVerticesBinary(ofstream &out, PLYElement* e)
00509 {
00510 assert(m_vertices);
00511
00512
00513 vector<Property*>::iterator current, first, last;
00514 first = e->getFirstProperty();
00515 last = e->getLastProperty();
00516
00517
00518
00519
00520 size_t buffer_size = 0;
00521 for(current = first; current != last; current++)
00522 {
00523 buffer_size += (*current)->getValueSize();
00524 }
00525
00526
00527 char buffer[buffer_size];
00528 char *pos;
00529
00530
00531
00532
00533 for(size_t i = 0; i < m_numberOfVertices; i++)
00534 {
00535 size_t vertex_pointer = i * 3;
00536
00537
00538 memset(buffer, 0, buffer_size);
00539 pos = buffer;
00540
00541
00542 for(current = first; current != last; current++)
00543 {
00544 Property* p = (*current);
00545 string property_name = p->getName();
00546 string property_type = p->getElementTypeStr();
00547 if(property_name == "x")
00548 {
00549 pos = putElementInBuffer(pos, property_type, m_vertices[vertex_pointer]);
00550 }
00551 else if (property_name == "y")
00552 {
00553 pos = putElementInBuffer(pos, property_type, m_vertices[vertex_pointer + 1]);
00554 }
00555 else if (property_name == "z")
00556 {
00557 pos = putElementInBuffer(pos, property_type, m_vertices[vertex_pointer + 2]);
00558 }
00559 else if(property_name == "r")
00560 {
00561 pos = putElementInBuffer(pos, property_type, m_colors[vertex_pointer]);
00562 }
00563 else if (property_name == "g")
00564 {
00565 pos = putElementInBuffer(pos, property_type, m_colors[vertex_pointer + 1]);
00566 }
00567 else if (property_name == "b")
00568 {
00569 pos = putElementInBuffer(pos, property_type, m_colors[vertex_pointer + 2]);
00570 }
00571 else
00572 {
00573 pos = putElementInBuffer(pos, property_type, 0);
00574 }
00575 }
00576
00577
00578 out.write(buffer, buffer_size);
00579 }
00580 }
00581
00582 void PLYIO::writeNormalsASCII(ofstream &out, PLYElement* e)
00583 {
00584
00585 assert(m_normals);
00586
00587 vector<Property*>::iterator current, last;
00588 string property_name;
00589
00590 for(size_t i = 0; i < m_numberOfNormals; i++)
00591 {
00592 size_t vertex_pointer = i * 3;
00593
00594
00595
00596
00597
00598
00599 current = e->getFirstProperty();
00600 last = e->getLastProperty();
00601
00602 while(current != last)
00603 {
00604 property_name = (*current)->getName();
00605 if( (property_name == "x") || (property_name == "nx") )
00606 {
00607 out << m_normals[vertex_pointer] << " ";
00608 }
00609 else if ( (property_name == "ny") || (property_name == "ny") )
00610 {
00611 out << m_normals[vertex_pointer + 1] << " ";
00612 }
00613 else if ( (property_name == "nz") || (property_name == "nz") )
00614 {
00615 out << m_normals[vertex_pointer + 2] << " ";
00616 }
00617 current++;
00618 }
00619
00620 out << endl;
00621 }
00622 }
00623
00624
00625
00626 void PLYIO::writeNormalsBinary(ofstream &out, PLYElement* e)
00627 {
00628 assert(m_vertices);
00629
00630
00631 vector<Property*>::iterator current, first, last;
00632 first = e->getFirstProperty();
00633 last = e->getLastProperty();
00634
00635
00636
00637
00638 size_t buffer_size = 0;
00639 for(current = first; current != last; current++)
00640 {
00641 buffer_size += (*current)->getValueSize();
00642 }
00643
00644
00645 char buffer[buffer_size];
00646 char *pos;
00647
00648
00649
00650
00651 for(size_t i = 0; i < m_numberOfNormals; i++)
00652 {
00653 size_t vertex_pointer = i * 3;
00654
00655
00656 memset(buffer, 0, buffer_size);
00657 pos = buffer;
00658
00659
00660 for(current = first; current != last; current++)
00661 {
00662 Property* p = (*current);
00663 string property_name = p->getName();
00664 string property_type = p->getElementTypeStr();
00665 if( (property_name == "x") || (property_name == "nx") )
00666 {
00667 pos = putElementInBuffer(pos, property_type, m_normals[vertex_pointer]);
00668 }
00669 else if ( (property_name == "y") || (property_name == "ny") )
00670 {
00671 pos = putElementInBuffer(pos, property_type, m_normals[vertex_pointer + 1]);
00672 }
00673 else if ( (property_name == "z") || (property_name == "nz"))
00674 {
00675 pos = putElementInBuffer(pos, property_type, m_normals[vertex_pointer + 2]);
00676 }
00677 else
00678 {
00679 pos = putElementInBuffer(pos, property_type, 0);
00680 }
00681 }
00682
00683
00684 out.write(buffer, buffer_size);
00685 }
00686
00687 }
00688
00689 char* PLYIO::putElementInBuffer(char* buffer, string value_type, float value)
00690 {
00691
00692 if(value_type == "char")
00693 {
00694 char c = (char)value;
00695 memcpy(buffer, &c, sizeof(char));
00696 buffer ++;
00697 }
00698 else if (value_type == "uchar")
00699 {
00700 unsigned char c = (unsigned char)value;
00701 memcpy(buffer, &c, sizeof(unsigned char));
00702 buffer ++;
00703 }
00704 else if (value_type == "short")
00705 {
00706 short s = (short)value;
00707 memcpy(buffer, &s, sizeof(short));
00708 buffer += 2;
00709 }
00710 else if (value_type == "ushort")
00711 {
00712 unsigned short s = (unsigned short)value;
00713 memcpy(buffer, &s, sizeof(unsigned short));
00714 buffer += 2;
00715 }
00716 else if (value_type == "int")
00717 {
00718 int i = (int)value;
00719 memcpy(buffer, &i, sizeof(int));
00720 buffer += 4;
00721 }
00722 else if (value_type == "uint")
00723 {
00724 unsigned int i = (unsigned int)value;
00725 memcpy(buffer, &i, sizeof(unsigned int));
00726 buffer += 4;
00727 }
00728 else if (value_type == "float")
00729 {
00730 memcpy(buffer, &value, sizeof(float));
00731 buffer += 4;
00732 }
00733 else if (value_type == "double")
00734 {
00735 double d = (double)value;
00736 memcpy(buffer, &d, sizeof(double));
00737 buffer += 8;
00738 }
00739
00740 return buffer;
00741 }
00742
00743 void PLYIO::allocVertexBuffers(PLYElement* descr)
00744 {
00745
00746
00747 m_vertices = new float[3 * m_numberOfVertices];
00748 memset(m_vertices, 0, 3 * m_numberOfVertices * sizeof(float));
00749
00750
00751
00752
00753 vector<Property*>::iterator it;
00754 for(it = descr->getFirstProperty(); it != descr->getLastProperty(); it++)
00755 {
00756 string property_name = (*it)->getName();
00757 if(property_name == "r" || property_name == "g" || property_name == "b")
00758 {
00759
00760 m_colors = new float[3 * m_numberOfVertices];
00761 memset(m_colors, 0, 3 * sizeof(float));
00762 break;
00763 }
00764 }
00765 }
00766
00767 void PLYIO::deleteBuffers()
00768 {
00769
00770 if(m_vertices)
00771 {
00772 delete[] m_vertices;
00773 m_vertices = 0;
00774 }
00775
00776 if(m_colors)
00777 {
00778 delete[] m_colors;
00779 m_colors = 0;
00780 }
00781
00782 if(m_indices)
00783 {
00784 delete[] m_indices;
00785 m_indices = 0;
00786 }
00787
00788 if(m_normals)
00789 {
00790 delete[] m_normals;
00791 m_normals = 0;
00792 }
00793 }
00794
00795 void PLYIO::readVerticesASCII(ifstream &in, PLYElement* descr)
00796 {
00797
00798
00799 m_numberOfVertices = descr->getCount();
00800
00801
00802 allocVertexBuffers(descr);
00803
00804
00805 vector<Property*>::iterator it;
00806 for(size_t i = 0; i < m_numberOfVertices; i++)
00807 {
00808
00809
00810 it = descr->getFirstProperty();
00811 while(it != descr->getLastProperty())
00812 {
00813 Property* p = *it;
00814 string property_name = p->getName();
00815 if(property_name == "x")
00816 {
00817 in >> m_vertices[i * 3];
00818 }
00819 else if(property_name == "y")
00820 {
00821 in >> m_vertices[i * 3 + 1];
00822 }
00823 else if(property_name == "z")
00824 {
00825 in >> m_vertices[i * 3 + 2];
00826 }
00827 else if(property_name == "r")
00828 {
00829 in >> m_colors[i * 3];
00830 }
00831 else if(property_name == "g")
00832 {
00833 in >> m_colors[i * 3 + 1];
00834 }
00835 else if(property_name == "b")
00836 {
00837 in >> m_colors[i * 3 + 2];
00838 }
00839 it++;
00840 }
00841
00842
00843
00844 }
00845 }
00846
00847
00848 void PLYIO::readVerticesBinary(ifstream &in, PLYElement* descr)
00849 {
00850
00851
00852 m_numberOfVertices = descr->getCount();
00853
00854
00855 allocVertexBuffers(descr);
00856
00857
00858 vector<Property*>::iterator it;
00859 for(size_t i = 0; i < m_numberOfVertices; i++)
00860 {
00861 if(i % 100000 == 0) cout << "Reading points: " << i << endl;
00862 for(it = descr->getFirstProperty(); it != descr->getLastProperty(); it++)
00863 {
00864
00865 Property* p = *it;
00866 if(p->getName() == "x")
00867 {
00868 copyElementToVertexBuffer(in, p, m_vertices, i * 3);
00869 }
00870 else if(p->getName() == "y")
00871 {
00872 copyElementToVertexBuffer(in, p, m_vertices, i * 3 + 1);
00873 }
00874 else if(p->getName() == "z")
00875 {
00876 copyElementToVertexBuffer(in, p, m_vertices, i * 3 + 2);
00877 }
00878 else if(p->getName() == "r")
00879 {
00880 copyElementToVertexBuffer(in, p, m_colors, i * 3);
00881 }
00882 else if(p->getName() == "g")
00883 {
00884 copyElementToVertexBuffer(in, p, m_colors, i * 3 + 1);
00885 }
00886 else if(p->getName() == "b")
00887 {
00888 copyElementToVertexBuffer(in, p, m_colors, i * 3 + 2);
00889 }
00890 }
00891
00892
00893
00894 }
00895
00896 }
00897
00898 float** PLYIO::getIndexedVertexArray(size_t& n)
00899 {
00900 assert(m_vertices);
00901 n = m_numberOfVertices;
00902 return interlacedBufferToIndexedBuffer(m_vertices, m_numberOfVertices);
00903 }
00904
00905 float** PLYIO::getIndexedNormalArray(size_t& n)
00906 {
00907 assert(m_normals);
00908 n = m_numberOfNormals;
00909 return interlacedBufferToIndexedBuffer(m_normals, m_numberOfNormals);
00910 }
00911
00912 void PLYIO::readNormalsBinary(ifstream &in, PLYElement* descr)
00913 {
00914
00915 m_numberOfNormals= descr->getCount();
00916
00917
00918 if(m_normals) delete[] m_normals;
00919 m_normals = new float[3 * m_numberOfNormals];
00920
00921
00922 vector<Property*>::iterator it;
00923 for(size_t i = 0; i < m_numberOfNormals; i++)
00924 {
00925 for(it = descr->getFirstProperty(); it != descr->getLastProperty(); it++)
00926 {
00927
00928 Property* p = *it;
00929 if( (p->getName() == "x") || (p->getName() == "nx") )
00930 {
00931 copyElementToVertexBuffer(in, p, m_normals, i * 3);
00932 }
00933 else if( (p->getName() == "y") || (p->getName() == "ny"))
00934 {
00935 copyElementToVertexBuffer(in, p, m_normals, i * 3 + 1);
00936 }
00937 else if( (p->getName() == "z") || (p->getName() == "nz"))
00938 {
00939 copyElementToVertexBuffer(in, p, m_normals, i * 3 + 2);
00940 }
00941 }
00942 }
00943 }
00944
00945 void PLYIO::readNormalsASCII(ifstream &in, PLYElement* descr)
00946 {
00947
00948 if(m_normals) delete[] m_normals;
00949 m_numberOfNormals = descr->getCount();
00950
00951 m_normals = new float[3 * m_numberOfNormals];
00952 memset(m_normals, 0, 3 * m_numberOfNormals * sizeof(float));
00953
00954
00955 vector<Property*>::iterator it;
00956 for(size_t i = 0; i < m_numberOfNormals; i++)
00957 {
00958 for(it = descr->getFirstProperty(); it != descr->getLastProperty(); it++)
00959 {
00960 Property* p = *it;
00961 if( (p->getName() == "x") || (p->getName() == "nx") )
00962 {
00963 in >> m_normals[i * 3];
00964 }
00965 else if( (p->getName() == "y") || (p->getName() == "ny"))
00966 {
00967 in >> m_normals[i * 3 + 1];
00968 }
00969 else if( (p->getName() == "z") || (p->getName() == "nz"))
00970 {
00971 in >> m_normals[i * 3 + 2];
00972 }
00973 }
00974 }
00975 }
00976
00977
00978 void PLYIO::copyElementToVertexBuffer(ifstream &in, Property* p, float* buffer, size_t position)
00979 {
00980 if(p->getElementTypeStr() == "char")
00981 {
00982 char tmp = 0;
00983 in.read(&tmp, sizeof(char));
00984 buffer[position] = (float)tmp;
00985 }
00986 else if(p->getElementTypeStr() == "uchar")
00987 {
00988 unsigned char tmp = 0;
00989 in.read((char*)&tmp, sizeof(unsigned char));
00990 buffer[position] = (float)tmp;
00991 }
00992 else if(p->getElementTypeStr() == "short")
00993 {
00994 short tmp = 0;
00995 in.read((char*)&tmp, sizeof(short));
00996 buffer[position] = (float)tmp;
00997 }
00998 else if(p->getElementTypeStr() == "ushort")
00999 {
01000 unsigned short tmp = 0;
01001 in.read((char*)&tmp, sizeof(unsigned short));
01002 buffer[position] = (float)tmp;
01003 }
01004 else if(p->getElementTypeStr() == "int")
01005 {
01006 int tmp = 0;
01007 in.read((char*)&tmp, sizeof(int));
01008 buffer[position] = (float)tmp;
01009 }
01010 else if(p->getElementTypeStr() == "uint")
01011 {
01012 unsigned int tmp = 0;
01013 in.read((char*)&tmp, sizeof(unsigned int));
01014 buffer[position] = (float)tmp;
01015 }
01016 else if(p->getElementTypeStr() == "float")
01017 {
01018 float tmp;
01019 in.read((char*)&tmp, sizeof(float));
01020 buffer[position] = tmp;
01021 }
01022 else if(p->getElementTypeStr() == "double")
01023 {
01024 double tmp = 0;
01025 in.read((char*)&tmp, sizeof(double));
01026 buffer[position] = (float)tmp;
01027 }
01028 }
01029
01030 void PLYIO::readFacesASCII(ifstream &in, PLYElement* descr)
01031 {
01032
01033
01034 m_numberOfFaces = descr->getCount();
01035
01036
01037 m_indices = new unsigned int[3 * m_numberOfFaces];
01038
01039
01040 int count, a, b, c, position;
01041 for(size_t i = 0; i < m_numberOfFaces; i++)
01042 {
01043 position = i * 3;
01044 in >> count >> a >> b >> c;
01045
01046 if(count != 3) cout << "PLYIO::readFacesASCII(): Warning: Indexed face is not a triangle." << endl;
01047 m_indices[position ] = a;
01048 m_indices[position + 1] = b;
01049 m_indices[position + 2] = c;
01050 }
01051
01052 }
01053
01054 void PLYIO::readFacesBinary(ifstream &in, PLYElement* descr)
01055 {
01056
01057 m_numberOfFaces = descr->getCount();
01058
01059
01060 m_indices = new unsigned int[3 * m_numberOfFaces];
01061
01062
01063
01064 size_t count_size, value_size;
01065
01066 Property* list_property = 0;
01067 vector<Property*>::iterator it;
01068 for(it = descr->getFirstProperty(); it != descr->getLastProperty(); it++)
01069 {
01070 Property* p = *it;
01071 if(p->getName() == "vertex_indices" || p->getName() == "vertex_index")
01072 {
01073 count_size = p->getCountSize();
01074 value_size = p->getValueSize();
01075 list_property = p;
01076 break;
01077 }
01078 }
01079
01080
01081 if(list_property == 0)
01082 {
01083 cout << "PLYIO::readFacesBinary() : Warning 'vertex_indices' property not found." << endl;
01084
01085 return;
01086 }
01087
01088
01089 string count_name = list_property->getCountTypeStr();
01090 string value_name = list_property->getElementTypeStr();
01091
01092
01093
01094 char* chunk_position;
01095
01096
01097 char* chunk_buffer = new char[count_size + 3 * value_size];
01098
01099 for(size_t i = 0; i < m_numberOfFaces; i++)
01100 {
01101 chunk_position = chunk_buffer;
01102
01103
01104 in.read(chunk_buffer, count_size + 3 * value_size);
01105
01106
01107 unsigned int vertex_count;
01108 if(count_name == "char")
01109 {
01110 char tmp;
01111 memcpy(&tmp, chunk_buffer, sizeof(char));
01112 chunk_position += sizeof(char);
01113 vertex_count = (unsigned int)tmp;
01114 }
01115 else if(count_name == "uchar")
01116 {
01117 unsigned char tmp;
01118 memcpy( (char*)&tmp, chunk_buffer, sizeof(unsigned char));
01119 chunk_position += sizeof(unsigned char);
01120 vertex_count = (unsigned int)tmp;
01121 }
01122 else if(count_name == "short")
01123 {
01124 short tmp;
01125 memcpy( (char*)&tmp, chunk_buffer, sizeof(short));
01126 chunk_position += sizeof(short);
01127 vertex_count = (unsigned int)tmp;
01128 }
01129 else if(count_name == "ushort")
01130 {
01131 unsigned short tmp;
01132 memcpy( (char*)&tmp, chunk_buffer, sizeof(unsigned short));
01133 chunk_position += sizeof(unsigned short);
01134 vertex_count = (unsigned int)tmp;
01135 }
01136 else if(count_name == "int")
01137 {
01138 int tmp;
01139 memcpy( (char*)&tmp, chunk_buffer, sizeof(int));
01140 chunk_position += sizeof(int);
01141 vertex_count = (unsigned int)tmp;
01142 }
01143 else if(count_name == "uint")
01144 {
01145 unsigned int tmp;
01146 memcpy( (char*)&tmp, chunk_buffer, sizeof(unsigned int));
01147 chunk_position += sizeof(unsigned int);
01148 vertex_count = (unsigned int)tmp;
01149 }
01150 else if(count_name == "float")
01151 {
01152 float tmp;
01153 memcpy( (char*)&tmp, chunk_buffer, sizeof(float));
01154 chunk_position += sizeof(float);
01155 vertex_count = tmp;
01156 }
01157 else if(count_name == "double")
01158 {
01159 double tmp;
01160 memcpy( (char*)&tmp, chunk_buffer, sizeof(double));
01161 chunk_position += sizeof(double);
01162 vertex_count = tmp;
01163 }
01164
01165
01166 if(vertex_count != 3)
01167 {
01168 cout << "PLYIO::readFacesBinary(): Warning: Face defintion is not a triangle." << endl;
01169
01170 return;
01171 }
01172
01173
01174 if(value_name == "char")
01175 {
01176 char indices[3];
01177 for(int j = 0; j < 3; j++)
01178 {
01179 memcpy( &indices[j], chunk_position + j * sizeof(char), sizeof(char));
01180 m_indices[i * 3 + j] = (unsigned int) indices[j];
01181 }
01182 }
01183 if(value_name == "uchar")
01184 {
01185 unsigned char indices[3];
01186 for(int j = 0; j < 3; j++)
01187 {
01188 memcpy( (char*) &indices[j], chunk_position + j * sizeof(unsigned char), sizeof(unsigned char));
01189 m_indices[i * 3 + j] = (unsigned int) indices[j];
01190 }
01191 }
01192 if(value_name == "short")
01193 {
01194 short indices[3];
01195 for(int j = 0; j < 3; j++)
01196 {
01197 memcpy( (char*) &indices[j], chunk_position + j * sizeof(short), sizeof(short));
01198 m_indices[i * 3 + j] = (unsigned int) indices[j];
01199 }
01200 }
01201 if(value_name == "ushort")
01202 {
01203 unsigned short indices[3];
01204 for(int j = 0; j < 3; j++)
01205 {
01206 memcpy( (char*) &indices[j], chunk_position + j * sizeof(unsigned short), sizeof(unsigned short));
01207 m_indices[i * 3 + j] = (unsigned int) indices[j];
01208 }
01209 }
01210 if(value_name == "int")
01211 {
01212 int indices[3];
01213 for(int j = 0; j < 3; j++)
01214 {
01215 memcpy( (char*) &indices[j], chunk_position + j * sizeof(int), sizeof(int));
01216 m_indices[i * 3 + j] = (unsigned int) indices[j];
01217 }
01218 }
01219 if(value_name == "uint")
01220 {
01221 unsigned int indices[3];
01222 for(int j = 0; j < 3; j++)
01223 {
01224 memcpy( (char*) &indices[j], chunk_position + j * sizeof(unsigned int), sizeof(unsigned int));
01225 m_indices[i * 3 + j] = indices[j];
01226 }
01227 }
01228 if(value_name == "float")
01229 {
01230 float indices[3];
01231 for(int j = 0; j < 3; j++)
01232 {
01233 memcpy( (char*) &indices[j], chunk_position + j * sizeof(float), sizeof(float));
01234 m_indices[i * 3 + j] = indices[j];
01235 }
01236 }
01237 if(value_name == "double")
01238 {
01239 double indices[3];
01240 for(int j = 0; j < 3; j++)
01241 {
01242 memcpy( (char*) &indices[j], chunk_position + j * sizeof(double), sizeof(double));
01243 m_indices[i * 3 + j] = (unsigned int)indices[j];
01244 }
01245 }
01246 }
01247
01248 }
01249
01250 bool PLYIO::isSupported(string element_name)
01251 {
01252 return element_name == "vertex" || element_name == "face" || element_name == "normal";
01253 }
01254
01255 void PLYIO::writeFacesBinary(ofstream &out, PLYElement* e)
01256 {
01257
01258
01259 int N_VERTICES_PER_FACE = 3;
01260
01261 vector<Property*>::iterator it, end, start;
01262 start = e->getFirstProperty();
01263 end = e->getLastProperty();
01264
01265
01266 size_t buffer_size = 0;
01267 for(it = start; it != end; it++)
01268 {
01269
01270 size_t count_size = (*it)->getCountSize();
01271 buffer_size += count_size;
01272
01273
01274 if(count_size != 0)
01275 {
01276 buffer_size += N_VERTICES_PER_FACE * (*it)->getValueSize();
01277 }
01278 else
01279 {
01280 buffer_size += (*it)->getValueSize();
01281 }
01282 }
01283
01284
01285 char buffer[buffer_size];
01286
01287 char* pos;
01288
01289
01290 for(size_t i = 0; i < m_numberOfFaces; i++)
01291 {
01292
01293 memset(buffer, 0, buffer_size);
01294 pos = buffer;
01295
01296 size_t index_pointer = i * 3;
01297 for(it = start; it != end; it++)
01298 {
01299 Property* p = (*it);
01300 string property_name = p->getName();
01301 string property_type = p->getElementTypeStr();
01302
01303 if(property_name == "vertex_index" || property_name == "vertex_indices")
01304 {
01305 string count_type = p->getCountTypeStr();
01306 pos = putElementInBuffer(pos, count_type, N_VERTICES_PER_FACE);
01307 pos = putElementInBuffer(pos, property_type, m_indices[index_pointer]);
01308 pos = putElementInBuffer(pos, property_type, m_indices[index_pointer + 1]);
01309 pos = putElementInBuffer(pos, property_type, m_indices[index_pointer + 2]);
01310 }
01311
01312 }
01313
01314
01315 out.write(buffer, buffer_size);
01316 }
01317
01318 }
01319
01320 float** PLYIO::interlacedBufferToIndexedBuffer(float* src, size_t n)
01321 {
01322 cout << "Creating indexed array..." << endl;
01323 const size_t buffer_size = 1000;
01324
01325
01326
01327 float** ivertices = new float*[n];
01328
01329
01330 float* begin = src;
01331
01332
01333 size_t c = 0;
01334
01335 while(c < n)
01336 {
01337 for(size_t i = 0; i < buffer_size && c < n; i++, c++)
01338 {
01339 int vertexPos = (n - 1 - c) * 3;
01340 ivertices[c] = new float[3];
01341 ivertices[c][0] = begin[vertexPos];
01342 ivertices[c][1] = begin[vertexPos + 1];
01343 ivertices[c][2] = begin[vertexPos + 2];
01344
01345 }
01346 begin = (float*)realloc(begin, (n * 3 - c) * sizeof(float));
01347 }
01348 free(src);
01349
01350 n = n;
01351 cout << "Done. " << c << " " << n << endl;
01352 return ivertices;
01353 }
01354
01355 float* PLYIO::indexedBufferToInterlacedBuffer(float** src, size_t n)
01356 {
01357
01358 size_t buffer_size = 100000;
01359 size_t initial_buffer_size = std::min((size_t)buffer_size, n);
01360 size_t buffer_size_bytes = 3 * initial_buffer_size * sizeof(float);
01361
01362
01363 float* interlaced_array = (float*)malloc(buffer_size_bytes);
01364
01365
01366 for(size_t c = 0; c < n;)
01367 {
01368
01369 for(size_t i = 0; i < buffer_size && c < n; i++, c++)
01370 {
01371 int index = 3 * c;
01372 interlaced_array[index ] = src[c][0];
01373 interlaced_array[index + 1] = src[c][1];
01374 interlaced_array[index + 2] = src[c][2];
01375 delete[] src[c];
01376 }
01377
01378
01379
01380 size_t remaining_points = n - c;
01381 size_t points_to_copy = std::min(remaining_points, buffer_size);
01382 size_t memory_needed = 3 * points_to_copy * sizeof(float);
01383 buffer_size_bytes += memory_needed;
01384
01385
01386 interlaced_array = (float*)realloc(interlaced_array, buffer_size_bytes);
01387 }
01388 delete[] src;
01389 return interlaced_array;
01390 }
01391
01392 void PLYIO::setIndexedVertexArray(float** arr, size_t vertex_count)
01393 {
01394
01395 m_vertices = indexedBufferToInterlacedBuffer(arr, vertex_count);
01396 m_numberOfVertices = vertex_count;
01397 }
01398
01399 void PLYIO::setIndexedNormalArray(float** arr, size_t count)
01400 {
01401 if(m_normals) delete[] m_normals;
01402 m_normals = indexedBufferToInterlacedBuffer(arr, count);
01403 m_numberOfNormals = count;
01404 }
01405
01406 void PLYIO::addElement(PLYElement* e)
01407 {
01408 m_elements.push_back(e);
01409 }
01410
01411 bool PLYIO::containsElement(string name)
01412 {
01413 vector<PLYElement*>::iterator it;
01414 PLYElement* element;
01415 for(it = m_elements.begin(); it != m_elements.end(); it++)
01416 {
01417 element = *it;
01418 if(element->getName() == name) return true;
01419 }
01420 return false;
01421 }
01422
01423
01424
01425 }