18 #include <QApplication>
60 if (!kdTree)
return false;
64 if (!associatedGenericCloud ||
69 std::vector<ccKdTree::Leaf*> leaves;
70 if (!kdTree->
getLeaves(leaves) || leaves.empty())
return false;
74 progressCb,
static_cast<unsigned>(leaves.size()));
79 progressCb->
setInfo(qPrintable(QString(
"Cells: %1\nMax error: %2")
93 for (
size_t i = 0; i < leaves.size(); ++i) {
94 leaves[i]->userData = -1;
96 assert(
static_cast<double>(
103 const double c_minCosNormAngle =
107 const int unvisitedNeighborValue = -1;
108 bool cancelled =
false;
112 for (
size_t i = 0; i < leaves.size(); ++i) {
114 if (currentCell->
error >= maxError)
131 currentCell->
userData = macroIndex++;
144 std::list<Candidate> candidates;
149 cellsToTest.push_back(currentCell);
157 while (!cellsToTest.empty() || !candidates.empty()) {
159 if (!cellsToTest.empty()) {
161 while (!cellsToTest.empty()) {
163 cellsToTest.back(), neighbors,
164 &unvisitedNeighborValue))
172 cellsToTest.pop_back();
178 for (ccKdTree::LeafSet::iterator it = neighbors.begin();
179 it != neighbors.end(); ++it) {
181 std::pair<ccKdTree::LeafSet::iterator, bool> ret =
182 visitedNeighbors.insert(neighbor);
187 candidates.push_back(
Candidate(neighbor));
188 }
catch (
const std::bad_alloc&) {
191 "[ccKdTreeForFacetExtraction] Not "
200 if (!candidates.empty()) {
202 if (closestFirst && candidates.size() > 1) {
203 for (std::list<Candidate>::iterator it =
205 it != candidates.end(); ++it)
206 it->dist = (it->centroid - currentCentroid).norm2();
214 std::list<Candidate>::iterator bestIt = candidates.end();
217 double bestError = -1.0;
219 unsigned skipCount = 0;
220 for (std::list<Candidate>::iterator it = candidates.begin();
221 it != candidates.end();
223 assert(it->leaf && it->leaf->points);
225 it->leaf->points->getAssociatedCloud());
229 .
dot(currentNormal)) <
231 it = candidates.erase(it);
241 for (
unsigned j = 0; j < currentPointSet->
size();
246 (*P - it->centroid).norm2();
247 if (d2 < minDistToMainSet || j == 0)
248 minDistToMainSet = d2;
250 minDistToMainSet = sqrt(minDistToMainSet);
254 if (it->radius < minDistToMainSet / overlapCoef) {
264 if (!fused->
add(*(it->leaf->points))) {
267 "[ccKdTreeForFacetExtraction] Not enough "
270 if (currentPointSet != currentCell->
points)
271 delete currentPointSet;
282 fused, planeEquation, errorMeasure);
284 if (error < 0.0 || error > maxError) {
286 it = candidates.erase(it);
289 if (bestError < 0.0 ||
error < bestError) {
292 if (bestFused)
delete bestFused;
312 if (bestIt != candidates.end()) {
313 assert(bestFused && bestError >= 0.0);
314 if (currentPointSet != currentCell->
points)
315 delete currentPointSet;
316 currentPointSet = bestFused;
326 bestIt->leaf->userData = currentCell->
userData;
330 cellsToTest.push_back(bestIt->leaf);
341 QApplication::processEvents();
344 candidates.erase(bestIt);
347 if (skipCount == candidates.size() && cellsToTest.empty()) {
356 if (currentPointSet != currentCell->
points)
delete currentPointSet;
359 if (cancelled)
break;
367 for (
size_t i = 0; i < leaves.size(); ++i) {
370 ScalarType scalar = (ScalarType)leaves[i]->userData;
371 if (leaves[i]->userData <=
373 scalar =
static_cast<ScalarType
>(macroIndex++);
375 for (
unsigned j = 0; j < subset->
size(); ++j)
constexpr PointCoordinateType PC_NAN
'NaN' as a PointCoordinateType value
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
Type dot(const Vector3Tpl &v) const
Dot product.
A 3D cloud interface with associated features (color, normals, octree, etc.)
bool getNeighborLeaves(BaseNode *cell, ccKdTree::LeafSet &neighbors, const int *userDataFilter=0)
Returns the neighbor leaves around a given cell.
std::unordered_set< Leaf * > LeafSet
A set of leaves.
ccGenericPointCloud * associatedGenericCloud() const
Returns associated (generic) point cloud.
bool isA(CV_CLASS_ENUM type) const
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
virtual void setInfo(const char *infoStr)=0
Notifies some information about the ongoing process.
virtual void setMethodTitle(const char *methodTitle)=0
Notifies the algorithm title.
virtual bool textCanBeEdited() const
Returns whether the dialog title and info can be updated or not.
virtual void update(float percent)=0
Notifies the algorithm progress.
PointCoordinateType computeLargestRadius()
const PointCoordinateType * getLSPlane()
Returns best interpolating plane equation (Least-square)
const CCVector3 * getGravityCenter()
Returns gravity center.
bool oneStep()
Increments total progress value of a single unit.
bool enableScalarField() override
A very simple point cloud (no point duplication)
void setPointScalarValue(unsigned pointIndex, ScalarType value) override
Sets the ith point associated scalar value.
virtual GenericIndexedCloudPersist * getAssociatedCloud()
Returns the associated (source) cloud.
unsigned size() const override
Returns the number of points.
bool add(const ReferenceCloud &cloud)
Add another reference cloud.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
PointCoordinateType planeEq[4]
bool getLeaves(LeafVector &leaves) const
Returns all leaf nodes.
std::vector< Leaf * > LeafVector
A vector of leaves.
__host__ __device__ float2 fabs(float2 v)
static void error(char *msg)
float DegreesToRadians(int degrees)
Convert degrees to radians.
PointCoordinateType radius
Candidate(ccKdTree::Leaf *l)