35 #include <boost/filesystem.hpp> 62 std::cout <<
timestamp <<
"Could not open '" << filename <<
"." << endl;
68 std::cout <<
timestamp <<
"Could not read header." << endl;
74 const char * name = buf;
77 bool found_vertices =
false;
78 bool found_points =
false;
79 bool found_faces =
false;
84 if(!strcmp( name,
"vertex" ))
86 found_vertices =
true;
88 else if(!strcmp( name,
"point" ))
92 else if(!strcmp( name,
"face" ))
103 if(found_faces && found_vertices && !found_points)
105 cout <<
timestamp <<
"Warning: While parsing '" << filename <<
"': Found mesh data without points." << endl;
115 std::cout <<
timestamp <<
"Could not open '" << filename <<
"." << endl;
121 std::cout <<
timestamp <<
"Could not read header." << endl;
131 if(found_vertices && !found_points)
133 if (!strcmp( name,
"vertex" ) )
142 if ( !strcmp( name,
"red" ) || !strcmp( name,
"r" ))
147 else if(!strcmp( name,
"nx"))
155 else if(found_points)
157 if (!strcmp( name,
"point" ) )
166 if ( !strcmp( name,
"red" ) || !strcmp( name,
"r" ))
171 else if(!strcmp( name,
"nx"))
184 void writePLYHeader(ofstream& outfile,
size_t numPoints,
bool writeColors,
bool writeNormals)
186 outfile <<
"ply" << endl;
187 outfile <<
"format binary_little_endian 1.0" << endl;
188 outfile <<
"element vertex " << numPoints << endl;
189 outfile <<
"property float x" << endl;
190 outfile <<
"property float y" << endl;
191 outfile <<
"property float z" << endl;
194 outfile <<
"property uchar red" << endl;
195 outfile <<
"property uchar green" << endl;
196 outfile <<
"property uchar blue" << endl;
201 outfile <<
"property float nx" << endl;
202 outfile <<
"property float ny" << endl;
203 outfile <<
"property float nz" << endl;
205 outfile <<
"end_header" << endl;
215 np = pointBuffer->numPoints();
218 floatArr points = pointBuffer->getPointArray();
220 floatArr normals = pointBuffer->getNormalArray();
223 size_t buffer_size = 3 *
sizeof(float);
227 buffer_size += w_color *
sizeof(
unsigned char);
232 buffer_size += 3 *
sizeof(float);
235 char* buffer =
new char[buffer_size];
237 for(
size_t i = 0; i < np; i++)
239 char* ptr = &buffer[0];
242 *((
float*)ptr) = points[3*i];
243 ptr +=
sizeof(float);
244 *((
float*)ptr) = points[3*i+1];
245 ptr +=
sizeof(float);
246 *((
float*)ptr) = points[3*i+2];
251 ptr +=
sizeof(float);
252 *((
unsigned char*)ptr) = colors[3 * i];
253 ptr +=
sizeof(
unsigned char);
254 *((
unsigned char*)ptr) = colors[3 * i + 1];
255 ptr +=
sizeof(
unsigned char);
256 *((
unsigned char*)ptr) = colors[3 * i + 2];
261 ptr +=
sizeof(
unsigned char);
262 *((
float*)ptr) = normals[3*i];
263 ptr +=
sizeof(float);
264 *((
float*)ptr) = normals[3*i+1];
265 ptr +=
sizeof(float);
266 *((
float*)ptr) = normals[3*i+2];
268 out.write((
const char*)buffer, buffer_size);
283 vector<pair<string, size_t> > ply_file_names;
285 bool mergeColors =
false;
286 bool mergeNormals =
false;
287 size_t totalNumPoints = 0;
290 boost::filesystem::path inputDir(options.
inputDir());
291 if(boost::filesystem::exists(inputDir) && boost::filesystem::is_directory(inputDir))
294 boost::filesystem::directory_iterator end;
295 for(boost::filesystem::directory_iterator it(inputDir); it != end; ++it)
297 std::string extension = it->path().extension().string();
298 if(extension ==
".ply")
300 ply_file_names.push_back(pair<string, size_t>(it->path().string(), 0));
304 size_t numFilesWithNormals = 0;
305 size_t numFilesWithColors = 0;
307 for(
auto it = ply_file_names.begin(); it != ply_file_names.end(); it++)
309 size_t numPoints = 0;
310 bool hasColors =
false;
311 bool hasNormals =
false;
316 numFilesWithColors++;
321 numFilesWithNormals++;
324 it->second = numPoints;
325 totalNumPoints += numPoints;
328 cout << numFilesWithNormals <<
" " << ply_file_names.size() << endl;
331 if(numFilesWithColors > 0 && numFilesWithColors == ply_file_names.size())
336 if(numFilesWithNormals > 0 && numFilesWithNormals == ply_file_names.size())
341 cout <<
timestamp <<
"Parsed directory. Reading " << totalNumPoints <<
" points from " << ply_file_names.size() <<
" files." << endl;
344 cout <<
timestamp <<
"Merging normals." << endl;
349 cout <<
timestamp <<
"Merging colors." << endl;
354 std::cout <<
timestamp << options.
inputDir() <<
" does not exist or is not a directory." << std::endl;
359 out.open(outfile_name.c_str(), std::ios::binary);
362 size_t maxChunkPoints = 1e7;
363 auto it = ply_file_names.begin();
367 while(it != ply_file_names.end())
369 size_t pointsInChunk = 0;
370 vector<string> filesInChunk;
373 filesInChunk.push_back(it->first);
374 pointsInChunk += it->second;
377 while(it != ply_file_names.end() && pointsInChunk < maxChunkPoints);
380 for(
auto chunkIt: filesInChunk)
385 for(
size_t c = 0; c < filesInChunk.size(); c++)
const kaboom::Options * options
int main(int argc, char **argv)
Main entry point for the LSSR surface executable.
static Timestamp timestamp
A global time stamp object for program runtime measurement.
static ModelPtr readModel(std::string filename)
int ply_get_property_info(p_ply_property property, const char **name, e_ply_type *type, e_ply_type *length_type, e_ply_type *value_type)
boost::shared_array< unsigned char > ucharArr
std::shared_ptr< PointBuffer > PointBufferPtr
p_ply_property ply_get_next_property(p_ply_element element, p_ply_property last)
A class to parse the program options for the reconstruction executable.
void addToFile(ofstream &out, string filename)
boost::shared_array< float > floatArr
string outputFile() const
p_ply_element ply_get_next_element(p_ply ply, p_ply_element last)
std::shared_ptr< Model > ModelPtr
int ply_get_element_info(p_ply_element element, const char **name, long *ninstances)
void writePLYHeader(ofstream &outfile, size_t numPoints, bool writeColors, bool writeNormals)
p_ply ply_open(const char *name, p_ply_error_cb error_cb, long idata, void *pdata)
int ply_read_header(p_ply ply)
void parsePLYHeader(string filename, size_t &numPoints, bool &hasNormals, bool &hasColors)