25 m_theAssociatedCloudAsGPC(aCloud),
29 m_frustumIntersector(nullptr) {}
39 std::vector<unsigned>& inCameraFrustum) {
40 if (!sensor)
return false;
43 float globalPlaneCoefficients[6][4];
48 globalPlaneCoefficients, globalCorners, globalEdges, globalCenter);
54 "[ccOctree::intersectWithFrustum] Not enough memory!");
60 std::vector<std::pair<unsigned, CCVector3>> pointsToTest;
62 pointsToTest, inCameraFrustum, globalPlaneCoefficients,
63 globalCorners, globalEdges, globalCenter);
66 for (
size_t i = 0; i < pointsToTest.size(); i++) {
68 inCameraFrustum.push_back(pointsToTest[i].first);
130 void* additionalParameters[] = {
134 additionalParameters);
143 void** additionalParameters,
147 bool visible = *(
static_cast<bool*
>(additionalParameters[1]));
174 ccBBox cellBox(bbMin, bbMax);
187 void** additionalParameters,
191 reinterpret_cast<glDrawParams*
>(additionalParameters[0]);
223 void** additionalParameters,
227 reinterpret_cast<glDrawParams*
>(additionalParameters[0]);
285 unsigned n = subset->
size();
286 for (
unsigned i = 0; i < n; ++i) {
289 sum.x += _theColor.
r;
290 sum.y += _theColor.
g;
291 sum.z += _theColor.
b;
309 unsigned n = subset->
size();
310 for (
unsigned i = 0; i < n; ++i) {
323 double pickWidth_pix )
const {
362 iTrans.
apply(rayOrigin);
370 double maxFOV_rad = 0;
372 maxFOV_rad = 0.002 * pickWidth_pix;
375 double maxRadius = pickWidth_pix * camera.
pixelSize / 2;
393 unsigned char level = 1;
400 bool skipThisCell =
false;
402 #ifdef DEBUG_PICKING_MECHANISM
433 for (cellsContainer::const_iterator it =
436 CellCode truncatedCode = (it->theCode >> currentBitDec);
439 if (truncatedCode != currentCellTruncatedCode) {
444 if ((it->theCode >> bitDec) == (currentCellCode >> bitDec)) {
451 currentCellCode = it->theCode;
454 while (level < maxLevel) {
456 getCellPos(it->theCode, level, cellPos,
false);
460 CCVector3 cellCenter((2 * cellPos.
x + 1) * halfCellSize,
461 (2 * cellPos.
y + 1) * halfCellSize,
462 (2 * cellPos.
z + 1) * halfCellSize);
465 CCVector3(halfCellSize, halfCellSize, halfCellSize);
468 double radialSqDist, sqDistToOrigin;
472 double dx = sqrt(sqDistToOrigin);
473 double dy = std::max<double>(
474 0, sqrt(radialSqDist) -
SQRT_3 * halfCellSize);
475 double fov_rad = atan2(dy, dx);
477 skipThisCell = (fov_rad > maxFOV_rad);
480 cellCenter - halfCell - margin,
481 cellCenter + halfCell + margin)
492 currentCellTruncatedCode = (currentCellCode >> currentBitDec);
495 #ifdef DEBUG_PICKING_MECHANISM
501 if ((!visTable || visTable->at(it->theIndex) ==
POINT_VISIBLE) &&
515 if (fabs(Q2D.
x - clickPos.
x) <= pickWidth_pix &&
516 fabs(Q2D.
y - clickPos.
y) <= pickWidth_pix) {
542 std::min<unsigned>(100, std::max<unsigned>(1, cloud->
size() / 100));
548 QWidget* parentWidget ) {
557 CVLog::Error(tr(
"Could not compute octree for cloud '%1'")
582 "[GuessBestRadius] Failed to compute the cloud octree");
588 if (bestRadius == 0) {
589 CVLog::Warning(
"[GuessBestRadius] The cloud has invalid dimensions");
593 if (cloud->
size() < 100) {
601 const unsigned sampleCount =
602 std::min<unsigned>(200, cloud->
size() / 10);
607 double lastMeanPop = 0;
609 std::random_device rd;
610 std::mt19937 gen(rd());
611 std::uniform_int_distribution<unsigned> dist(0, cloud->
size() - 1);
614 for (
size_t attempt = 0; attempt < 10; ++attempt) {
616 int totalSquareCount = 0;
619 int aboveMinPopCount = 0;
625 for (
size_t i = 0; i < sampleCount; ++i) {
626 unsigned randomIndex = dist(gen);
627 assert(randomIndex < cloud->
size());
636 totalSquareCount += n * n;
651 double meanPop =
static_cast<double>(totalCount) / sampleCount;
652 double stdDevPop = sqrt(std::abs(
653 static_cast<double>(totalSquareCount) / sampleCount -
655 double aboveMinPopRatio =
656 static_cast<double>(aboveMinPopCount) / sampleCount;
658 CVLog::Print(QString(
"[GuessBestRadius] Radius = %1 -> samples "
659 "population in [%2 ; %3] (mean %4 / std. dev. "
660 "%5 / %6% above minimum)")
666 .arg(aboveMinPopRatio * 100));
689 assert(meanPop >= 1.0);
694 newRadius = radius * sqrt(aimedPop / meanPop);
697 if (std::abs(meanPop - aimedPop) <
698 std::abs(bestRadius - aimedPop)) {
702 double slope = (radius * radius - lastRadius * lastRadius) /
703 (meanPop - lastMeanPop);
705 lastRadius * lastRadius +
706 (aimedPop - lastMeanPop) * slope;
707 if (newSquareRadius > 0) {
708 newRadius = sqrt(newSquareRadius);
716 lastMeanPop = meanPop;
722 if (
octree && !inputOctree) {
constexpr unsigned char POINT_VISIBLE
constexpr double SQRT_3
Square root of 3.
Vector3Tpl< double > CCVector3d
Double 3D Vector.
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.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
3-Tuple structure (templated version)
void normalize()
Sets vector norm to unity.
double norm2d() const
Returns vector square norm (forces double precision output)
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
void setValue(size_t index, const Type &value)
Camera (projective) sensor.
bool computeGlobalPlaneCoefficients(float planeCoefficients[6][4], CCVector3 ptsFrustum[8], CCVector3 edges[6], CCVector3 ¢er)
bool isGlobalCoordInFrustum(const CCVector3 &globalCoord) const
Tests if a 3D point is in the field of view of the camera.
virtual bool hasColors() const
Returns whether colors are enabled or not.
virtual bool sfShown() const
Returns whether active scalar field is visible.
virtual bool hasNormals() const
Returns whether normals are enabled or not.
virtual void getDrawingParameters(glDrawParams ¶ms) const
Returns main OpenGL parameters for this entity.
void applyRotation(Vector3Tpl< float > &vec) const
Applies rotation only to a 3D vector (in place) - float version.
ccGLMatrixTpl< T > inverse() const
Returns inverse transformation.
void apply(float vec[3]) const
Applies transformation to a 3D vector (in place) - float version.
Float version of ccGLMatrixTpl.
A 3D cloud interface with associated features (color, normals, octree, etc.)
virtual const CCVector3 & getPointNormal(unsigned pointIndex) const =0
Returns normal corresponding to a given point.
virtual const ecvColor::Rgb * getScalarValueColor(ScalarType d) const =0
Returns color corresponding to a given scalar value.
virtual ccOctree::Shared computeOctree(cloudViewer::GenericProgressCallback *progressCb=nullptr, bool autoAddChild=true)
Computes the cloud octree.
virtual bool isVisibilityTableInstantiated() const
Returns whether the visibility array is allocated or not.
virtual const ecvColor::Rgb & getPointColor(unsigned pointIndex) const =0
Returns color corresponding to a given point.
virtual ccOctree::Shared getOctree() const
Returns the associated octree (if any)
virtual VisibilityTableType & getTheVisibilityArray()
Returns associated visibility array.
ccBBox getOwnBB(bool withGLFeatures=false) override
Returns the entity's own bounding-box.
std::vector< unsigned char > VisibilityTableType
Array of "visibility" information for each point.
Generic primitive interface.
virtual void setColor(const ecvColor::Rgb &col)
Sets primitive color (shortcut)
void draw(CC_DRAW_CONTEXT &context) override
Draws entity and its children.
bool getAbsoluteGLTransformation(ccGLMatrix &trans) const
NormsIndexesTableType * getTriNormsTable() const override
Returns per-triangle normals shared array.
static CompressedNormType GetNormIndex(const PointCoordinateType N[])
Returns the compressed index corresponding to a normal vector.
virtual QString getName() const
Returns object name.
bool isA(CV_CLASS_ENUM type) const
void computeFrustumIntersectionWithOctree(std::vector< std::pair< unsigned, CCVector3 >> &pointsToTest, std::vector< unsigned > &inCameraFrustum, const float planesCoefficients[6][4], const CCVector3 ptsFrustum[8], const CCVector3 edges[6], const CCVector3 ¢er)
OctreeCellVisibility
Definition of the state of a cell compared to a frustum.
bool build(cloudViewer::DgmOctree *octree)
Prepares structure for frustum filtering.
OctreeCellVisibility positionFromFrustum(cloudViewer::DgmOctree::CellCode truncatedCode, unsigned char level) const
Returns the cell visibility.
int m_displayedLevel
Displayed level.
static CCVector3 ComputeAverageNorm(cloudViewer::ReferenceCloud *subset, ccGenericPointCloud *sourceCloud)
Computes the average normal of a set of points.
void setDisplayedLevel(int level)
Sets the currently displayed octree level.
virtual ~ccOctree()
Destructor.
static bool DrawCellAsAPrimitive(const cloudViewer::DgmOctree::octreeCell &cell, void **additionalParameters, cloudViewer::NormalizedProgress *nProgress=0)
static void ComputeAverageColor(cloudViewer::ReferenceCloud *subset, ccGenericPointCloud *sourceCloud, ColorCompType meanCol[])
Computes the average color of a set of points.
static bool DrawCellAsAPoint(const cloudViewer::DgmOctree::octreeCell &cell, void **additionalParameters, cloudViewer::NormalizedProgress *nProgress=0)
ccBBox getSquareBB() const
Returns the octree (square) bounding-box.
ccOctree(ccGenericPointCloud *cloud)
Default constructor.
static PointCoordinateType GuessBestRadiusAutoComputeOctree(ccGenericPointCloud *cloud, const BestRadiusParams ¶ms, QWidget *parentWidget=nullptr)
void setDisplayMode(DisplayMode mode)
Sets the currently display mode.
bool intersectWithFrustum(ccCameraSensor *sensor, std::vector< unsigned > &inCameraFrustum)
Intersects octree with a camera sensor.
static bool DrawCellAsABox(const cloudViewer::DgmOctree::octreeCell &cell, void **additionalParameters, cloudViewer::NormalizedProgress *nProgress=0)
void multiplyBoundingBox(const PointCoordinateType multFactor)
Multiplies the bounding-box of the octree.
ccGenericPointCloud * m_theAssociatedCloudAsGPC
Associated cloud (as a ccGenericPointCloud)
void updated()
Signal sent when the octree organization is modified (cleared, etc.)
DisplayMode
Octree displaying methods.
ccBBox getPointsBB() const
Returns the points bounding-box.
bool pointPicking(const CCVector2d &clickPos, const ccGLCameraParameters &camera, PointDescriptor &output, double pickWidth_pix=3.0) const
Octree-driven point picking algorithm.
ccOctreeFrustumIntersector * m_frustumIntersector
For frustum intersection.
virtual void clear() override
Clears the octree.
DisplayMode m_displayMode
Display mode.
static PointCoordinateType GuessBestRadius(ccGenericPointCloud *cloud, const BestRadiusParams ¶ms, cloudViewer::DgmOctree *cloudOctree=nullptr, cloudViewer::GenericProgressCallback *progressCb=nullptr)
Tries to guess the best 'local radius' for octree-based computation.
void draw(CC_DRAW_CONTEXT &context)
Draws the octree.
static PointCoordinateType GuessNaiveRadius(ccGenericPointCloud *cloud)
Tries to guess a very naive 'local radius' for octree-based computation.
bool m_visible
For Octree Display.
void translateBoundingBox(const CCVector3 &T)
Translates the bounding-box of the octree.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
ccScalarField * getCurrentDisplayedScalarField() const
Returns the currently displayed scalar (or 0 if none)
A scalar field associated to display-related parameters.
const ccColorScale::Shared & getColorScale() const
Returns associated color scale.
const ecvColor::Rgb * getColor(ScalarType value) const
bool mayHaveHiddenValues() const
T getMaxBoxDim() const
Returns maximal box dimension.
The octree structure used throughout the library.
static const CellCode INVALID_CELL_CODE
Invalid cell code.
unsigned CellCode
Type of the code of an octree cell.
GenericIndexedCloudPersist * m_theAssociatedCloud
Associated cloud.
void getCellPos(CellCode code, unsigned char level, Tuple3i &cellPos, bool isCodeTruncated) const
static const int MAX_OCTREE_LEVEL
Max octree subdivision level.
CCVector3 m_dimMax
Max coordinates of the octree bounding-box.
unsigned char findBestLevelForAGivenNeighbourhoodSizeExtraction(PointCoordinateType radius) const
PointCoordinateType m_cellSize[MAX_OCTREE_LEVEL+2]
Cell dimensions for all subdivision levels.
const PointCoordinateType & getCellSize(unsigned char level) const
Returns the octree cells length for a given level of subdivision.
int getPointsInSphericalNeighbourhood(const CCVector3 &sphereCenter, PointCoordinateType radius, NeighboursSet &neighbours, unsigned char level) const
Returns the points falling inside a sphere.
void computeCellCenter(CellCode code, unsigned char level, CCVector3 ¢er, bool isCodeTruncated=false) const
unsigned executeFunctionForAllCellsAtLevel(unsigned char level, octreeCellFunc func, void **additionalParameters, bool multiThread=false, GenericProgressCallback *progressCb=nullptr, const char *functionTitle=nullptr, int maxThreadCount=0)
void computeCellLimits(CellCode code, unsigned char level, CCVector3 &cellMin, CCVector3 &cellMax, bool isCodeTruncated=false) const
Returns the spatial limits of a given cell.
int build(GenericProgressCallback *progressCb=nullptr)
Builds the structure.
CCVector3 m_dimMin
Min coordinates of the octree bounding-box.
cellsContainer m_thePointsAndTheirCellCodes
The coded octree structure.
static unsigned char GET_BIT_SHIFT(unsigned char level)
Returns the binary shift for a given level of subdivision.
std::vector< PointDescriptor > NeighboursSet
A set of neighbours.
unsigned char findBestLevelForAGivenPopulationPerCell(unsigned indicativeNumberOfPointsPerCell) const
virtual bool enableScalarField()=0
Enables the scalar field associated to the cloud.
virtual unsigned size() const =0
Returns the number of points.
virtual void setPointScalarValue(unsigned pointIndex, ScalarType value)=0
Sets the ith point associated scalar value.
A generic 3D point cloud with index-based point access.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
const CCVector3 * getGravityCenter()
Returns gravity center.
A very simple point cloud (no point duplication)
virtual GenericIndexedCloudPersist * getAssociatedCloud()
Returns the associated (source) cloud.
unsigned size() const override
Returns the number of points.
virtual unsigned getPointGlobalIndex(unsigned localIndex) const
ScalarType & getValue(std::size_t index)
Graphical progress indicator (thread-safe)
unsigned char ColorCompType
Default color components type (R,G and B)
Generic file read and write utility for python interface.
constexpr Rgb magenta(MAX, 0, MAX)
constexpr Rgb blue(0, 0, MAX)
constexpr Rgb green(0, MAX, 0)
Simple axis aligned box structure.
bool intersects(const Ray< T > &r, T *t0=0, T *t1=0) const
void squareDistances(const Vector3Tpl< T > &P, double &radial, double &toOrigin) const
OpenGL camera parameters.
bool unproject(const CCVector3d &input2D, CCVector3d &output3D) const
Unprojects a 2D point (+ normalized 'z' coordinate) in 3D.
float pixelSize
Pixel size (i.e. zoom) - non perspective mode only.
bool perspective
Perspective mode.
bool project(const CCVector3d &input3D, CCVector3d &output2D, bool *inFrustum=nullptr) const
Projects a 3D point in 2D (+ normalized 'z' coordinate)
Parameters for the GuessBestRadius method.
int minCellPopulation
Minimum cell poulation.
int aimedPopulationPerCell
Aimed poulation per octree cell.
int aimedPopulationRange
Aimed poulation range per octree cell.
Structure used during nearest neighbour search.
const CCVector3 * point
Point.
double squareDistd
Point associated distance value.
unsigned pointIndex
Point index.
ReferenceCloud * points
Set of points lying inside this cell.
const DgmOctree * parentOctree
Octree to which the cell belongs.
unsigned char level
Cell level of subdivision.
CellCode truncatedCode
Truncated cell code.
Display parameters of a 3D entity.
bool showColors
Display colors.
bool showNorms
Display normals.
bool showSF
Display scalar field (prioritary on colors)