/* ---- This file is part of SECONDO. Copyright (C) 2019, Faculty of Mathematics and Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- //[<] [\ensuremath{<}] //[>] [\ensuremath{>}] \setcounter{tocdepth}{3} \tableofcontents 0 Header for the Geometric Primitives Most top-level documentation can be found here. We are using a threefold structure: * the Interface GeomPrimitiveInterface, which is used for the iteration over all registered primitives in the analyze procedure (Pointcloud2::analyzeGeom); * the abstract template GeomPrimitive which implements all functionality common across all primitives; * the implementations of the primitives and their specific functions. Extensions of the latter are fairly easy as each primitive must implement the following functions: * get-caption * get-tuple-size * project-tuple-to-dual * get-predicate-for-shape * get-bbox-predicate-for-shape */ #pragma once #include #include #include #include "AbstractGeomPrimitive.h" namespace pointcloud2 { /* Returns true if the given point is considered part of the specific shape from which this predicate was created. */ typedef std::function&)> GeomPredicate; /* Returns true if the given bounding box possibly intersects with the specific shape from which this predicate was created. In the case of an intersection, the points in the bounding box will be individually tested with the GeomPredicate. */ typedef std::function&)> BboxPredicate; /* 2 Abstract Template Class GeomPrimitive */ template class GeomPrimitive : public AbstractGeomPrimitive { protected: /* whether the dual points should be reported to the console */ static const bool REPORT_TO_CONSOLE = true; static const bool REPORT_DETAILED = REPORT_TO_CONSOLE && false; public: virtual ~GeomPrimitive() = default; /* 2.1 Functions implemented by this class. 2.1.1 project\_cluster\_setObjID For documentation see the project\_cluster\_setObjID method in GeomPrimitiveInterface. */ void projectClusterSetObjID(const std::vector& sample, std::shared_ptr cloud, const ParamsAnalyzeGeom& params, std::shared_ptr objManager, Timer& timer) override; private: /* 2.1.2 project sample to dual This function takes a sample of regular points from the Pointcloud2 and returns a vector of points in dual space. */ std::shared_ptr>> projectSampleToDual( const std::vector& sample, const ParamsAnalyzeGeom& params, const Rectangle& bboxOfEntireCloud); /* 2.1.3 project neighborhood to dual Adds dual points from the given neighborhood to the vector dualPoints. neighbors contains indices of points in the sample; centerPoint is the point around which this neighborhood was retrieved. */ std::vector> projectNeighborhoodToDual( const std::vector& neighbors, const PointIndex centerPoint, const BitArray& neighborIndexSelector, const std::vector& sample, const ParamsAnalyzeGeom& params, const Rectangle& bboxOfEntireCloud); /* 2.1.4 cluster and reduce to centers This function is mainly a templating-wrapper of the DbScan interface. It uses recursive DBSCAN on the given dualPoints to obtain for each cluster a single point in dual space. The recursion ensures that the bounding box of the clusters gets small enough and then returns the weighted center of every cluster that contains enough points. A vector of those centers is returned, each representing a geometric shape in normal space. */ std::vector> clusterAndReduceToCenters( std::shared_ptr>> dualPoints, const ParamsAnalyzeGeom& params); /* 2.1.5 match shapes with points This function iterates over the given shapes and uses the given mmRTree to identify all candidate points in the Pointcloud2 that may belong to the respective shape. It then calls DBSCAN to identify clusters among the candidate points. For all points in large enough clusters, the \_clusterId is set to a new object id. */ void matchShapesWithPoints( const std::vector>& shapes, std::shared_ptr cloud, const ParamsAnalyzeGeom& params, std::shared_ptr iih) const; protected: /* 2.1.5 is point far outside Returns true if the given point is far outside the given bbox. This helps identify unlikely shape candidates (e.g. huge spheres the center of which lies far outside the bbox; this can occur when a sphere is calculated from points that are almost on a plane). */ static bool isPointFarOutside(const double x, const double y, const double z, const Rectangle& bbox); public: /* 2.2 Functions that must be implemented by Geometric Primitives. 2.2.1 Name of this primitive Returns the name of this primitive used for console outputs. */ virtual std::string getCaption(const bool plural) const override = 0; /* 2.2.2 get tuple size Returns the number of points needed in a tuple for project\_tuple\_to\_dual (e.g., three points are needed to define a plane in the 3-dimensional space). Note that the tuple size is often, but not necessarily equal to the dimension of the dual space. */ virtual unsigned getTupleSize() const = 0; /* 2.2.3 project tuple into dual space This function must be implemented by each primitive. The given vector "tuple" holds the (indexes of the) required number of points from the given "sample". It is then assumed that these points define a primitive of the current type, and the coordinates in dual space which represent that specific primitive are calculated. This dual point is then entered to the vector \_dualPoints. The function returns true if a dual point could be added to the given vector, or false if no dual point could be calculated from the given tuple. */ virtual std::unique_ptr>> projectTupleToDual( const std::vector& tuple, const ParamsAnalyzeGeom& params, const Rectangle& bboxOfEntireCloud) = 0; /* 2.2.4 Calculation of a Predicate for a given Shape This function must be implemented by each Primitive. It returns a function that tests whether a Point is contained in the shape which is represented by the argument dual point. The returned function will be used to test whether specific points from the Pointcloud2 can be assigned to the shape. */ virtual GeomPredicate getPredicateForShape( const PointBase& shape, const ParamsAnalyzeGeom& params) const = 0; /* 2.2.5 Calculation of bbox Predicate for a given Shape This function must be implemented by each Primitive. It returns a function that tests whether a bounding box may intersect with the shape which is represented by the argument dual point. If the function evaluates to true, all points in the bounding box will be tested individually using the predicate created by get\_predicate\_for\_shape. */ virtual BboxPredicate getBboxPredicateForShape( const PointBase& shape, const ParamsAnalyzeGeom& params) const = 0; }; } //end of namespace