PointBufferSet Splitter::run(PointBufferPtr buf) { PointBufferSet pbSet; if (!buf->size()) return pbSet; CoordCompare compare; std::map<Coord, PointBufferPtr, CoordCompare> buffers(compare); // Use the location of the first point as the origin. double xOrigin = buf->getFieldAs<double>(Dimension::Id::X, 0); double yOrigin = buf->getFieldAs<double>(Dimension::Id::Y, 0); // Overlay a grid of squares on the points (m_length sides). Each square // corresponds to a new point buffer. Place the points falling in the // each square in the corresponding point buffer. for (PointId idx = 0; idx < buf->size(); idx++) { int xpos = (buf->getFieldAs<double>(Dimension::Id::X, idx) - xOrigin) / m_length; int ypos = (buf->getFieldAs<double>(Dimension::Id::Y, idx) - yOrigin) / m_length; Coord loc(xpos, ypos); PointBufferPtr& outbuf = buffers[loc]; if (!outbuf) outbuf = buf->makeNew(); outbuf->appendPoint(*buf, idx); } // Pull the buffers out of the map and stick them in the standard // output set, setting the bounds as we go. for (auto bi = buffers.begin(); bi != buffers.end(); ++bi) pbSet.insert(bi->second); return pbSet; }
BOX3D PointBuffer::calculateBounds(const PointBufferSet& set, bool is3d) { BOX3D out; for (auto iter = set.begin(); iter != set.end(); ++iter) { PointBufferPtr buf = *iter; out.grow(buf->calculateBounds(is3d)); } return out; }
TEST(IcebridgeReaderTest, testRead) { StageFactory f; ReaderPtr reader(f.createReader("readers.icebridge")); EXPECT_TRUE(reader.get()); Option filename("filename", getFilePath(), ""); Options options(filename); reader->setOptions(options); PointContext ctx; reader->prepare(ctx); PointBufferSet pbSet = reader->execute(ctx); EXPECT_EQ(pbSet.size(), 1u); PointBufferPtr buf = *pbSet.begin(); EXPECT_EQ(buf->size(), 2u); checkPoint( *buf, 0, 141437548, // time 82.605319, // latitude 301.406196, // longitude 18.678, // elevation 2408, // xmtSig 181, // rcvSig 49.91, // azimuth -4.376, // pitch 0.608, // roll 2.9, // gpsPdop 20.0, // pulseWidth 0.0); // relTime checkPoint( *buf, 1, 141437548, // time 82.605287, // latitude 301.404862, // longitude 18.688, // elevation 2642, // xmtSig 173, // rcvSig 52.006, // azimuth -4.376, // pitch 0.609, // roll 2.9, // gpsPdop 17.0, // pulseWidth 0.0); // relTime }
PointBufferSet Crop::run(PointBufferPtr buffer) { PointBufferSet pbSet; PointBufferPtr output = buffer->makeNew(); crop(*buffer, *output); pbSet.insert(output); return pbSet; }
void LVRMainWindow::exportSelectedModel() { // Get selected point cloud QList<QTreeWidgetItem*> items = treeWidget->selectedItems(); if(items.size() > 0) { QTreeWidgetItem* item = items.first(); if(item->type() == LVRPointCloudItemType) { if(item->parent() && item->parent()->type() == LVRModelItemType) { QString qFileName = QFileDialog::getSaveFileName(this, tr("Export Point Cloud As..."), "", tr("Point cloud Files(*.ply *.3d)")); LVRModelItem* model_item = static_cast<LVRModelItem*>(item->parent()); LVRPointCloudItem* pc_item = static_cast<LVRPointCloudItem*>(item); PointBufferPtr points = pc_item->getPointBuffer(); // Get transformation matrix Pose p = model_item->getPose(); Matrix4f mat(Vertexf(p.x, p.y, p.z), Vertexf(p.r, p.t, p.p)); // Allocate target buffer and insert transformed points size_t n; floatArr transformedPoints(new float[3 * points->getNumPoints()]); floatArr pointArray = points->getPointArray(n); for(size_t i = 0; i < points->getNumPoints(); i++) { Vertexf v(pointArray[3 * i], pointArray[3 * i + 1], pointArray[3 * i + 2]); Vertexf vt = mat * v; transformedPoints[3 * i ] = vt[0]; transformedPoints[3 * i + 1] = vt[1]; transformedPoints[3 * i + 2] = vt[2]; } // Save transformed points PointBufferPtr trans(new PointBuffer); trans->setPointArray(transformedPoints, n); ModelPtr model(new Model(trans)); ModelFactory::saveModel(model, qFileName.toStdString()); } } } }
TEST(SortFilterTest, pipeline) { PipelineManager mgr; PipelineReader reader(mgr); reader.readPipeline(Support::configuredpath("filters/sort.xml")); mgr.execute(); PointBufferSet pbSet = mgr.buffers(); EXPECT_EQ(pbSet.size(), 1u); PointBufferPtr buf = *pbSet.begin(); for (PointId i = 1; i < buf->size(); ++i) { double d1 = buf->getFieldAs<double>(Dimension::Id::X, i - 1); double d2 = buf->getFieldAs<double>(Dimension::Id::X, i); EXPECT_TRUE(d1 <= d2); } }
TEST(LasReaderTest, test_sequential) { PointContext ctx; Options ops1; ops1.add("filename", Support::datapath("las/1.2-with-color.las")); ops1.add("count", 103); LasReader reader; reader.setOptions(ops1); reader.prepare(ctx); PointBufferSet pbSet = reader.execute(ctx); EXPECT_EQ(pbSet.size(), 1u); PointBufferPtr buf = *pbSet.begin(); Support::check_p0_p1_p2(*buf); PointBufferPtr buf2 = buf->makeNew(); buf2->appendPoint(*buf, 100); buf2->appendPoint(*buf, 101); buf2->appendPoint(*buf, 102); Support::check_p100_p101_p102(*buf2); }
void MultiPointCloud::init(PointBufferPtr buffer) { if(buffer) { vector<indexPair> pairs = buffer->getSubClouds(); vector<indexPair>::iterator it; int c(1); size_t n; coord3fArr points = buffer->getIndexedPointArray( n ); color3bArr colors = buffer->getIndexedPointColorArray( n ); for(it = pairs.begin(); it != pairs.end(); it ++) { indexPair p = *it; // Create new point cloud from scan PointCloud* pc = new PointCloud; for(size_t a = p.first; a <= p.second; a++) { if(colors) { pc->addPoint(points[a][0], points[a][1], points[a][2], colors[a][0], colors[a][1], colors[a][2]); } else { pc->addPoint(points[a][0], points[a][1], points[a][2], 255, 0, 0); } } stringstream ss; pc->updateDisplayLists(); pc->setName(ss.str()); addCloud(pc); c++; } } }
static void test_a_format(const std::string& file, boost::uint8_t majorVersion, boost::uint8_t minorVersion, int pointFormat, double xref, double yref, double zref, double tref, boost::uint16_t rref, boost::uint16_t gref, boost::uint16_t bref) { PointContext ctx; Options ops1; ops1.add("filename", Support::datapath(file)); ops1.add("count", 1); pdal::drivers::las::Reader reader; reader.setOptions(ops1); reader.prepare(ctx); BOOST_CHECK_EQUAL(reader.header().pointFormat(), pointFormat); BOOST_CHECK_EQUAL(reader.header().versionMajor(), majorVersion); BOOST_CHECK_EQUAL(reader.header().versionMinor(), minorVersion); PointBufferSet pbSet = reader.execute(ctx); BOOST_CHECK_EQUAL(pbSet.size(), 1); PointBufferPtr buf = *pbSet.begin(); BOOST_CHECK_EQUAL(buf->size(), 1); Support::check_pN(*buf, 0, xref, yref, zref, tref, rref, gref, bref); }
void DatIO::save(string filename) { PointBufferPtr pointBuffer = m_model->m_pointCloud; float buffer[4]; if(pointBuffer) { ofstream out(filename.c_str(), std::ios::binary); if(out.good()) { size_t numPoints; size_t numIntensities; floatArr pointArray = pointBuffer->getPointArray(numPoints); floatArr intensityArray = pointBuffer->getPointIntensityArray(numIntensities); float buffer[4]; cout << timestamp << "Writing " << numPoints << " to " << filename << endl; for(size_t i = 0; i < numPoints; i++) { memset(buffer, 0, 4 * sizeof(float)); size_t pos = i * 3; buffer[0] = pointArray[pos]; buffer[1] = pointArray[pos + 1]; buffer[2] = pointArray[pos + 2]; if(intensityArray) { buffer[3] = intensityArray[i]; } out.write((char*)buffer, 4 * sizeof(float)); } out.close(); } else { cout << timestamp << "DatIO: Unable to open file " << filename << " for writing." << endl; } } }
void InteractivePointCloud::updateBuffer(PointBufferPtr buffer) { if(buffer) { if(!m_boundingBox) { m_boundingBox = new BoundingBox<Vertex<float> >; m_boundingBox->expand(8000, 8000, 8000); } size_t num_vertices; float* vertices = buffer->getPointArray(num_vertices).get(); // m_boundingBox = new BoundingBox<Vertex<float> >; // for (int i = 0; i < int(num_vertices); i++) // { // int index = 3 * i; // m_boundingBox->expand(vertices[index], vertices[index + 1], vertices[index + 2]); // } glVertexPointer(3, GL_FLOAT, 0, vertices); m_buffer = buffer; } }
int main(int argc, char** argv) { // Read given file ModelPtr model = ModelFactory::readModel(argv[1]); std::list<PointVectorPair> points; std::cout << timestamp << "Creating model.." << std::endl; // Get point buffer and convert to size_t n; floatArr b = model->m_pointCloud->getPointArray(n); for(size_t i = 0; i < n; i++) { points.push_back(PointVectorPair(Point(b[3 * i], b[3 * i + 1], b[3 * i + 2]), Vector(0.0, 0.0, 0.0))); } std::cout << timestamp << "Estimating normals..." << std::endl; // Estimates normals direction. // Note: pca_estimate_normals() requires an iterator over points // as well as property maps to access each point's position and normal. const int nb_neighbors = atoi(argv[2]); // K-nearest neighbors = 3 rings CGAL::pca_estimate_normals(points.begin(), points.end(), CGAL::First_of_pair_property_map<PointVectorPair>(), CGAL::Second_of_pair_property_map<PointVectorPair>(), nb_neighbors); std::cout << timestamp << "Orientating normals..." << std::endl; // Orients normals. // Note: mst_orient_normals() requires an iterator over points // as well as property maps to access each point's position and normal. std::list<PointVectorPair>::iterator unoriented_points_begin = CGAL::mst_orient_normals(points.begin(), points.end(), CGAL::First_of_pair_property_map<PointVectorPair>(), CGAL::Second_of_pair_property_map<PointVectorPair>(), nb_neighbors); // Optional: delete points with an unoriented normal // if you plan to call a reconstruction algorithm that expects oriented normals. points.erase(unoriented_points_begin, points.end()); // Optional: after erase(), use Scott Meyer's "swap trick" to trim excess capacity std::list<PointVectorPair>(points).swap(points); std::cout << timestamp << "Creating output buffer" << std::endl; PointBufferPtr buffer = PointBufferPtr(new PointBuffer); std::list<PointVectorPair>::iterator it; floatArr pts(new float[3 * points.size()]); floatArr normals(new float[3 * points.size()]); int c = 0; for(it = points.begin(); it != points.end(); it++) { Point p = it->first; Vector n = it->second; pts[3 * c ] = p[0]; pts[3 * c + 1] = p[1]; pts[3 * c + 2] = p[2]; normals[3 * c ] = n[0]; normals[3 * c + 1] = n[1]; normals[3 * c + 2] = n[2]; //std::cout << p[0] << " " << p[1] << " " << p[2] << std::endl; c++; } //std::cout << c << " & " << points.size() << std::endl; std::cout << timestamp << "Creating model" << std::endl; buffer->setPointArray(pts, points.size()); buffer->setPointNormalArray(normals, points.size()); ModelPtr outModel(new Model(buffer)); std::cout << timestamp << "Saving result" << std::endl; ModelFactory::saveModel(outModel, "normals.ply"); }
TEST(NitfReaderTest, test_one) { StageFactory f; Options nitf_opts; nitf_opts.add("filename", Support::datapath("nitf/autzen-utm10.ntf")); nitf_opts.add("count", 750); PointContext ctx; ReaderPtr nitf_reader(f.createReader("readers.nitf")); EXPECT_TRUE(nitf_reader.get()); nitf_reader->setOptions(nitf_opts); nitf_reader->prepare(ctx); PointBufferSet pbSet = nitf_reader->execute(ctx); EXPECT_EQ(nitf_reader->getDescription(), "NITF Reader"); EXPECT_EQ(pbSet.size(), 1u); PointBufferPtr buf = *pbSet.begin(); // check metadata //ABELL /** { Metadata metadata = nitf_reader.getMetadata(); /////////////////////////////////////////////////EXPECT_EQ(metadatums.size(), 80u); EXPECT_EQ(metadata.toPTree().get<std::string>("metadata.FH_FDT.value"), "20120323002946"); } **/ // // read LAS // Options las_opts; las_opts.add("count", 750); las_opts.add("filename", Support::datapath("nitf/autzen-utm10.las")); PointContext ctx2; ReaderPtr las_reader(f.createReader("readers.las")); EXPECT_TRUE(las_reader.get()); las_reader->setOptions(las_opts); las_reader->prepare(ctx2); PointBufferSet pbSet2 = las_reader->execute(ctx2); EXPECT_EQ(pbSet2.size(), 1u); PointBufferPtr buf2 = *pbSet.begin(); // // // compare the two buffers // EXPECT_EQ(buf->size(), buf2->size()); for (PointId i = 0; i < buf2->size(); i++) { int32_t nitf_x = buf->getFieldAs<int32_t>(Dimension::Id::X, i); int32_t nitf_y = buf->getFieldAs<int32_t>(Dimension::Id::Y, i); int32_t nitf_z = buf->getFieldAs<int32_t>(Dimension::Id::Z, i); int32_t las_x = buf2->getFieldAs<int32_t>(Dimension::Id::X, i); int32_t las_y = buf2->getFieldAs<int32_t>(Dimension::Id::Y, i); int32_t las_z = buf2->getFieldAs<int32_t>(Dimension::Id::Z, i); EXPECT_EQ(nitf_x, las_x); EXPECT_EQ(nitf_y, las_y); EXPECT_EQ(nitf_z, las_z); } }
int main( int argc, char ** argv ) { // Parse command line arguments convert::Options options(argc, argv); // Exit if options had to generate a usage message // (this means required parameters are missing) if ( options.printUsage() ) { return 0; } ::std::cout << options << ::std::endl; // Read input file ModelPtr model = ModelFactory::readModel(options.getInputFile()); if(model) { if(model->m_pointCloud) { // Get parameters bool convert = options.convertIntensity(); bool filterIntensity = options.getMinIntensity() > -1e10 || options.getMaxIntensity() < 1e10; // Check if we have to modify some data if(convert || filterIntensity) { PointBufferPtr points = model->m_pointCloud; size_t numPoints = points->getNumPoints(); if(points) { size_t n; if(convert && !points->getPointColorArray(n)) { cout << timestamp << "Allocating new point color array." << endl; ucharArr colors(new unsigned char[numPoints * 3]); points->setPointColorArray(colors, numPoints); } float max_i = -1e10; float min_i = +1e10; float maxCutOff = options.getMaxIntensity(); float minCutOff = options.getMinIntensity(); floatArr intensities = points->getPointIntensityArray(n); if(intensities) { // Cutoff intensity values for(size_t i = 0; i < numPoints; i++) { //cout << intensities[i] << endl; if(intensities[i] < minCutOff) intensities[i] = minCutOff; if(intensities[i] > maxCutOff) intensities[i] = maxCutOff; if(intensities[i] < min_i) min_i = intensities[i]; if(intensities[i] > max_i) max_i = intensities[i]; } // Map intensities to 0 .. 255 cout << max_i << " " << min_i << endl; float r_diff = max_i - min_i; if(r_diff > 0) { float b_size = r_diff / 255.0; for(int a = 0; a < numPoints; a++) { //cout << intensities[a] << endl; float value = intensities[a]; value -= min_i; value /= b_size; intensities[a] = value; //cout << intensities[a] << endl << endl; } } // Convert if(convert) { ucharArr colors = points->getPointColorArray(n); GradientType gradType = GREY; string gradientName = options.getColorMap(); if(gradientName == "HOT") gradType = HOT; if(gradientName == "HSV") gradType = HSV; if(gradientName == "SHSV") gradType = SHSV; if(gradientName == "JET") gradType = JET; ColorMap colorMap(255); for(size_t i = 0; i < numPoints; i++) { float color[3]; colorMap.getColor(color, (size_t)intensities[i], gradType ); colors[3 * i ] = (unsigned char)(color[0] * 255); colors[3 * i + 1] = (unsigned char)(color[1] * 255); colors[3 * i + 2] = (unsigned char)(color[2] * 255); //cout << intensities[i] << endl; //cout << (int) colors[3 * i ] << " " << (int)colors[3 * i + 1] << " " << (int)colors[3 * i + 2] << endl; } points->setPointColorArray(colors, numPoints); } model->m_pointCloud = points; } else { cout << timestamp << "Model contains no point intensities to convert." << endl; } } } } ModelFactory::saveModel(model, options.getOutputFile()); } else { cout << timestamp << "Error reading file " << options.getInputFile() << endl; } }
ModelPtr ModelFactory::readModel( std::string filename ) { ModelPtr m; // Check extension boost::filesystem::path selectedFile( filename ); std::string extension = selectedFile.extension().string(); // Try to parse given file BaseIO* io = 0; if(extension == ".ply") { io = new PLYIO; } else if(extension == ".pts" || extension == ".3d" || extension == ".xyz") { io = new AsciiIO; } else if (extension == ".obj") { io = new ObjIO; } else if (extension == ".las") { io = new LasIO; } else if (extension ==".dat") { io = new DatIO; } #ifdef LVR_USE_PCL else if (extension == ".pcd") { io = new PCDIO; } #endif /* LVR_USE_PCL */ else if (extension == "") { bool found_3d = false; bool found_boctree = false; // Check for supported data in directory. boost::filesystem::directory_iterator lastFile; for(boost::filesystem::directory_iterator it(filename); it != lastFile; it++ ) { boost::filesystem::path p = it->path(); // Check for 3d files if(p.extension().string() == ".3d") { // Check for naming convention "scanxxx.3d" int num = 0; if(sscanf(p.filename().string().c_str(), "scan%3d", &num)) { found_3d = true; } } // Check for .oct files if(p.extension().string() == ".oct") { // Check for naming convention "scanxxx.3d" int num = 0; if(sscanf(p.filename().string().c_str(), "scan%3d", &num)) { found_boctree = true; } } } // Check and create io if(!found_boctree && found_3d) { io = new UosIO; } else if(found_boctree && found_3d) { cout << timestamp << "Found 3d files and octrees. Loading octrees per default." << endl; io = new BoctreeIO; } else if(found_boctree && !found_3d) { io = new BoctreeIO; } else { cout << timestamp << "Given directory does not contain " << endl; } } // Return data model if( io ) { m = io->read( filename ); if(m_transform.convert) { // Convert coordinates in model PointBufferPtr points = m->m_pointCloud; size_t n_points = 0; size_t n_normals = 0; floatArr p = points->getPointArray(n_points); floatArr n = points->getPointNormalArray(n_normals); // If normals are present every point should habe one if(n_normals) { assert(n_normals == n_points); } // Convert coordinates float point[3]; float normal[3]; for(size_t i = 0; i < n_points; i++) { // Re-order and scale point coordinates point[0] = p[3 * i + m_transform.x] * m_transform.sx; point[1] = p[3 * i + m_transform.y] * m_transform.sy; point[2] = p[3 * i + m_transform.z] * m_transform.sz; p[3 * i] = point[0]; p[3 * i + 1] = point[1]; p[3 * i + 2] = point[2]; if(n_normals) { normal[0] = n[3 * i + m_transform.x] * m_transform.sx; normal[1] = n[3 * i + m_transform.y] * m_transform.sy; normal[2] = n[3 * i + m_transform.z] * m_transform.sz; n[3 * i] = normal[0]; n[3 * i + 1] = normal[1]; n[3 * i + 2] = normal[2]; } } } delete io; } return m; }
int Diff::execute() { PointContext sourceCtx; Options sourceOptions; { sourceOptions.add<std::string>("filename", m_sourceFile); sourceOptions.add<bool>("debug", isDebug()); sourceOptions.add<boost::uint32_t>("verbose", getVerboseLevel()); } std::unique_ptr<Stage> source(AppSupport::makeReader(m_sourceFile)); source->setOptions(sourceOptions); source->prepare(sourceCtx); PointBufferSet sourceSet = source->execute(sourceCtx); ptree errors; PointContext candidateCtx; Options candidateOptions; { candidateOptions.add<std::string>("filename", m_candidateFile); candidateOptions.add<bool>("debug", isDebug()); candidateOptions.add<boost::uint32_t>("verbose", getVerboseLevel()); } std::unique_ptr<Stage> candidate(AppSupport::makeReader(m_candidateFile)); candidate->setOptions(candidateOptions); candidate->prepare(candidateCtx); PointBufferSet candidateSet = candidate->execute(candidateCtx); assert(sourceSet.size() == 1); assert(candidateSet.size() == 1); PointBufferPtr sourceBuf = *sourceSet.begin(); PointBufferPtr candidateBuf = *candidateSet.begin(); if (candidateBuf->size() != sourceBuf->size()) { std::ostringstream oss; oss << "Source and candidate files do not have the same point count"; errors.put("count.error", oss.str()); errors.put("count.candidate", candidateBuf->size()); errors.put("count.source", sourceBuf->size()); } MetadataNode source_metadata = sourceCtx.metadata(); MetadataNode candidate_metadata = candidateCtx.metadata(); if (source_metadata != candidate_metadata) { std::ostringstream oss; oss << "Source and candidate files do not have the same metadata count"; errors.put("metadata.error", oss.str()); errors.put_child("metadata.source", pdal::utils::toPTree(source_metadata)); errors.put_child("metadata.candidate", pdal::utils::toPTree(candidate_metadata)); } if (candidateCtx.dims().size() != sourceCtx.dims().size()) { std::ostringstream oss; oss << "Source and candidate files do not have the same " "number of dimensions"; errors.put<std::string>("schema.error", oss.str()); //Need to "ptree" the PointContext dimension list in some way // errors.put_child("schema.source", sourceCtx.schema()->toPTree()); // errors.put_child("schema.candidate", // candidateCtx.schema()->toPTree()); } if (errors.size()) { write_json(std::cout, errors); return 1; } else { // If we made it this far with no errors, now we'll // check the points. checkPoints(*sourceBuf, *candidateBuf, errors); if (errors.size()) { write_json(std::cout, errors); return 1; } } return 0; }