25 #include <QMainWindow>
44 double r =
static_cast<double>(x * x + y * y);
50 return atan(z / sqrt(
static_cast<double>(r)));
60 QVariant x = polyline->
getMetaData(key + QString(
".x"));
61 QVariant y = polyline->
getMetaData(key + QString(
".y"));
62 QVariant z = polyline->
getMetaData(key + QString(
".z"));
63 if (x.isValid() && y.isValid() && z.isValid()) {
64 bool ok[3] = {
true,
true,
true};
68 return (ok[0] && ok[1] && ok[2]);
82 polyline->
setMetaData(key + QString(
".x"), QVariant(P.
x));
83 polyline->
setMetaData(key + QString(
".y"), QVariant(P.
y));
84 polyline->
setMetaData(key + QString(
".z"), QVariant(P.
z));
98 axis.
u[
revolDim] + std::numeric_limits<PointCoordinateType>::epsilon() <
104 cloudToSurfaceOrigin = rotation * cloudToSurfaceOrigin;
107 return cloudToSurfaceOrigin;
114 ccGLMatrix cloudToPolylineOrigin = computeCloudToSurfaceOriginTrans();
119 return cloudToPolylineOrigin;
127 QVariant dim(revolDim);
137 if (axis.isValid()) {
139 int dim = axis.toInt(&ok);
140 if (ok && dim >= 0 && dim <= 2)
return dim;
184 if (shift.isValid()) {
222 bool storeRadiiAsSF ,
228 QString(
"Internal error: invalid input parameters"),
237 unsigned vertexCount = vertices->
size();
238 if (vertexCount < 2) {
241 QString(
"Invalid polyline (not enough vertices)"),
251 QString(
"Invalid polyline (bad or missing meta-data)"),
262 QString(
"Failed to allocate a new scalar field for "
263 "computing distances! Try to free some memory ..."),
269 unsigned pointCount = cloud->
size();
270 sf->resize(pointCount);
274 if (storeRadiiAsSF) {
277 if (sfIdxRadii < 0) {
280 QString(
"Failed to allocate a new scalar field for "
281 "storing radii! You should try to free some "
288 radiiSf->resize(pointCount);
301 const unsigned char dim1 =
static_cast<unsigned char>(
303 const unsigned char dim2 = (dim1 < 2 ? dim1 + 1 : 0);
306 dlg.
setMethodTitle(QObject::tr(
"Cloud to profile radial distance"));
307 dlg.
setInfo(QObject::tr(
"Polyline: %1 vertices\nCloud: %2 points")
315 for (
unsigned i = 0; i < pointCount; ++i) {
325 double radius = sqrt(Prel.
u[dim1] * Prel.
u[dim1] +
326 Prel.
u[dim2] * Prel.
u[dim2]);
329 ScalarType radiusVal =
static_cast<ScalarType
>(radius);
335 for (
unsigned j = 1; j < vertexCount; ++j) {
339 double alpha = (
height - A->
y) / (B->
y - A->
y);
340 if (alpha >= 0.0 && alpha <= 1.0) {
342 double radius_th = A->
x + alpha * (B->
x - A->
x);
343 double dist = radius - radius_th;
349 minDist =
static_cast<ScalarType
>(
dist);
358 for (
unsigned j = i; j < pointCount; ++j)
386 unsigned char revolutionAxisDim) {
387 minLat_rad = maxLat_rad = 0.0;
391 if (!cloud || revolutionAxisDim > 2)
return false;
394 if (
count == 0)
return true;
397 const unsigned char Z = revolutionAxisDim;
399 const unsigned char X = (Z < 2 ? Z + 1 : 0);
400 const unsigned char Y = (
X < 2 ?
X + 1 : 0);
402 for (
unsigned n = 0; n <
count; ++n) {
404 CCVector3 relativePos = cloudToSurfaceOrigin * (*P);
411 if (lat_rad < minLat_rad)
412 minLat_rad = lat_rad;
413 else if (lat_rad > maxLat_rad)
414 maxLat_rad = lat_rad;
416 minLat_rad = maxLat_rad = lat_rad;
424 if (phi1 >= phi2)
return 1.0;
432 return (log(cos(phi1)) - log(cos(phi2))) / (log(tan_pl1) - log(tan_pl2));
443 return cos(phi1) * pow(tan_pl / tan_pl1, n) / n;
446 QSharedPointer<DistanceMapGenerationTool::Map>
450 unsigned char revolutionAxisDim,
456 bool counterclockwise,
463 app->
dispToConsole(QString(
"[DistanceMapGenerationTool] Internal "
464 "error: invalid input structures!"),
466 return QSharedPointer<Map>(0);
470 if (xStep_rad <= 0.0 || yStep <= 0.0 || yMax <= yMin ||
471 revolutionAxisDim > 2) {
473 app->
dispToConsole(QString(
"[DistanceMapGenerationTool] Internal "
474 "error: invalid grid parameters!"),
476 return QSharedPointer<Map>(0);
482 app->
dispToConsole(QString(
"[DistanceMapGenerationTool] Cloud is "
483 "empty! Nothing to do!"),
485 return QSharedPointer<Map>(0);
489 const unsigned char Z = revolutionAxisDim;
491 const unsigned char X = (Z < 2 ? Z + 1 : 0);
492 const unsigned char Y = (
X < 2 ?
X + 1 : 0);
498 xSteps =
static_cast<unsigned>(
ceil((2 *
M_PI) / xStep_rad));
502 "Invalid longitude step/boundaries! "
503 "Can't generate a proper map!"),
505 return QSharedPointer<Map>(0);
512 ySteps =
static_cast<unsigned>(
ceil((yMax - yMin) / yStep));
516 "Invalid latitude step/boundaries! "
517 "Can't generate a proper map!"),
519 return QSharedPointer<Map>(0);
523 unsigned cellCount = xSteps * ySteps;
525 app->
dispToConsole(QString(
"[DistanceMapGenerationTool] Projected map "
526 "size: %1 x %2 (%3 cells)")
533 QSharedPointer<Map> grid(
new Map);
535 grid->resize(cellCount);
536 }
catch (
const std::bad_alloc&) {
539 QString(
"[DistanceMapGenerationTool] Not enough memory!"),
541 return QSharedPointer<Map>(0);
545 grid->xSteps = xSteps;
547 grid->xMax = 2 *
M_PI;
548 grid->xStep = xStep_rad;
549 grid->ySteps = ySteps;
553 grid->conical = conical;
556 grid->counterclockwise = counterclockwise;
557 double ccw = (counterclockwise ? -1.0 : 1.0);
559 for (
unsigned n = 0; n <
count; ++n) {
561 const ScalarType& val = sf->
getValue(n);
565 CCVector3 relativePos = cloudToSurface * (*P);
569 ccw * atan2(relativePos.
u[
X], relativePos.
u[Y]);
577 relativePos.
u[
X], relativePos.
u[Y],
580 y = relativePos.
u[Z];
583 int i =
static_cast<int>((x - grid->xMin) / grid->xStep);
584 int j =
static_cast<int>((y - grid->yMin) / grid->yStep);
587 if (i ==
static_cast<int>(grid->xSteps)) --i;
588 if (j ==
static_cast<int>(grid->ySteps)) --j;
591 if (i < 0 || i >=
static_cast<int>(grid->xSteps) || j < 0 ||
592 j >=
static_cast<int>(grid->ySteps)) {
595 assert(i >= 0 && j >= 0);
597 MapCell& cell = (*grid)[j *
static_cast<int>(grid->xSteps) + i];
600 switch (fillStrategy) {
607 cell.
value +=
static_cast<double>(val);
631 for (
unsigned i = 0; i < cellCount; ++i, ++cell)
633 cell->
value /=
static_cast<double>(cell->
count);
639 for (
unsigned i = 0; i < cellCount; ++i, ++cell) {
640 if (cell->
count == 0) {
647 unsigned fillCount = 0;
650 for (
unsigned i = 0; i < cellCount; ++i, ++cell)
651 if (cell->
count != 0) ++fillCount;
656 std::vector<CCVector2> the2DPoints;
658 the2DPoints.reserve(fillCount);
663 QString(
"[DistanceMapGenerationTool] Not enough "
664 "memory to interpolate!"),
668 if (the2DPoints.capacity() == fillCount) {
671 const MapCell* cell = &grid->at(0);
672 for (
unsigned j = 0; j < grid->ySteps; ++j)
673 for (
unsigned i = 0; i < grid->xSteps; ++i, ++cell)
683 std::string errorStr;
689 QString(
"[DistanceMapGenerationTool] "
690 "Interpolation failed: Triangle lib. "
692 .arg(QString::fromStdString(errorStr)),
695 unsigned triNum = dm->
size();
699 for (
unsigned k = 0; k < triNum; ++k) {
704 int xMin = 0, yMin = 0, xMax = 0, yMax = 0;
706 for (
unsigned j = 0; j < 3; ++j) {
707 const CCVector2& P2D = the2DPoints[tsi->
i[j]];
708 P[j][0] =
static_cast<int>(P2D.
x);
709 P[j][1] =
static_cast<int>(P2D.
y);
724 cells[P[0][0] + P[0][1] * grid->xSteps]
727 cells[P[1][0] + P[1][1] * grid->xSteps]
730 cells[P[2][0] + P[2][1] * grid->xSteps]
733 (P[1][1] - P[2][1]) * (P[0][0] - P[2][0]) +
734 (P[2][0] - P[1][0]) * (P[0][1] - P[2][1]);
736 for (
int j = yMin; j <= yMax; ++j) {
739 static_cast<unsigned>(j) * grid->xSteps;
741 for (
int i = xMin; i <= xMax; ++i) {
743 if (!cell[i].
count) {
749 for (
int ti = 0; ti < 3; ++ti) {
750 const int* P1 = P[ti];
751 const int* P2 = P[(ti + 1) % 3];
752 if ((P2[1] <= j && j < P1[1]) ||
753 (P1[1] <= j && j < P2[1])) {
754 int t = (i - P2[0]) * (P1[1] -
758 if (P1[1] < P2[1]) t = -t;
759 if (t < 0) inside = !inside;
786 double l3 = 1.0 - l1 - l2;
789 cell[i].
value = l1 * valA +
808 const MapCell* cell = &grid->at(0);
809 grid->minVal = grid->maxVal = cell->
value;
811 for (
unsigned i = 1; i < cellCount; ++i, ++cell) {
812 if (cell->
value < grid->minVal)
813 grid->minVal = cell->
value;
814 else if (cell->
value > grid->maxVal)
815 grid->maxVal = cell->
value;
827 bool counterclockwise) {
828 double theta = nProj * (lon_rad -
M_PI);
839 const QSharedPointer<Map>& map,
840 bool counterclockwise,
841 QImage mapTexture ) {
844 unsigned meshVertCount = map->xSteps * map->ySteps;
845 unsigned meshFaceCount = (map->xSteps - 1) * (map->ySteps - 1) * 2;
849 if (!cloud->
reserve(meshVertCount) || !mesh->
reserve(meshFaceCount)) {
858 assert(nProj >= -1.0 && nProj <= 1.0);
862 double cwSign = (counterclockwise ? -1.0 : 1.0);
863 for (
unsigned j = 0; j < map->xSteps; ++j) {
866 static_cast<double>(j) / map->xSteps * (2.0 *
M_PI);
868 double theta = nProj *
871 double sin_theta = sin(theta);
872 double cos_theta = cos(theta);
874 for (
unsigned i = 0; i < map->ySteps; ++i) {
876 map->yMin +
static_cast<double>(i) * map->yStep;
890 for (
unsigned j = 0; j + 1 < map->xSteps; ++j) {
891 for (
unsigned i = 0; i + 1 < map->ySteps; ++i) {
892 unsigned vertA = j * map->ySteps + i;
893 unsigned vertB = vertA + map->ySteps;
894 unsigned vertC = vertB + 1;
895 unsigned vertD = vertA + 1;
916 for (
unsigned j = 0; j < map->xSteps; ++j) {
917 TexCoords2D T(
static_cast<float>(j) / (map->xSteps - 1), 0.0f);
918 for (
unsigned i = 0; i < map->ySteps; ++i) {
919 T.
ty =
static_cast<float>(i) / (map->ySteps - 1);
932 for (
unsigned j = 0; j + 1 < map->xSteps; ++j) {
933 for (
unsigned i = 0; i + 1 < map->ySteps; ++i) {
934 unsigned vertA = j * map->ySteps + i;
935 unsigned vertB = vertA + map->ySteps;
936 unsigned vertC = vertB + 1;
937 unsigned vertD = vertA + 1;
952 for (
unsigned i = 0; i < meshFaceCount; ++i) {
960 material->setTexture(mapTexture, QString(),
false);
978 const QSharedPointer<Map>& map,
988 unsigned vertexCount = vertices ? vertices->
size() : 0;
989 if (vertexCount < 2) {
1007 double surfaceProd = 0.0;
1008 double volumeProd = 0.0;
1009 const double yMax = map->yMin + map->yStep * map->ySteps;
1010 for (
unsigned i = 1; i < pcVertices->
size(); ++i) {
1027 if (y1 < map->yMin || y0 > yMax) {
1032 if (y0 < map->yMin) {
1034 double alpha = (map->yMin - y0) / (y1 - y0);
1035 assert(alpha >= 0.0 && alpha <= 1.0);
1036 r0 = r0 + alpha * (r1 - r0);
1038 }
else if (y1 > yMax) {
1040 double alpha = (yMax - y0) / (y1 - y0);
1041 assert(alpha >= 0.0 && alpha <= 1.0);
1042 r1 = r0 + alpha * (r1 - r0);
1048 double segmentLength =
1049 sqrt((r1 - r0) * (r1 - r0) + (y1 - y0) * (y1 - y0));
1050 surfaceProd += (r0 + r1) * segmentLength;
1054 volumeProd += (y1 - y0) * (r0 * r0 + r1 * r1 + r0 * r1);
1062 if (revolDim < 0)
return false;
1065 const double surfPart =
1069 const double volPart = map->yStep * map->xStep /
1073 const MapCell* cell = &map->at(0);
1075 for (
unsigned j = 0; j < map->ySteps; ++j) {
1077 double height1 = map->yMin + j * map->yStep;
1078 double height2 = height1 + map->yStep;
1079 double r_th1 = -1.0;
1080 double r_th2 = -1.0;
1083 double height_middle = (height1 + height2) / 2.0;
1084 for (
unsigned k = 1; k < vertexCount; ++k) {
1088 double alpha = (height_middle - A->
y) / (B->
y - A->
y);
1089 if (alpha >= 0.0 && alpha <= 1.0) {
1090 r_th1 = A->
x + (height1 - A->
y) / (B->
y - A->
y) * (B->
x - A->
x);
1091 r_th2 = A->
x + (height2 - A->
y) / (B->
y - A->
y) * (B->
x - A->
x);
1097 if (r_th1 >= 0.0 ) {
1099 for (
unsigned i = 0; i < map->xSteps; ++i, ++cell) {
1101 double d = (cell->
count != 0 ? cell->
value : 0.0);
1104 double r1 = r_th1 + d;
1112 double s = sqrt((r2 - r1) * (r2 - r1) +
1113 map->yStep * map->yStep);
1114 double externalSurface = (r1 + r2) * s;
1115 surface.
total += externalSurface;
1118 surface.
positive += externalSurface;
1120 surface.
negative += externalSurface;
1126 (r1 * r1 + r2 * r2 + r1 * r2);
1128 double diffVolume =
fabs(
1140 cell += map->xSteps;
1145 surface.
total *= surfPart;
1149 volume.
total *= volPart;
1160 unsigned char revolutionAxisDim,
1161 bool counterclockwise ) {
1163 if (!cloud || cloud->
size() == 0)
return false;
1166 const unsigned char Z = revolutionAxisDim;
1168 const unsigned char X = (Z < 2 ? Z + 1 : 0);
1169 const unsigned char Y = (
X < 2 ?
X + 1 : 0);
1175 for (
unsigned n = 0; n < cloud->
size(); ++n) {
1177 CCVector3 relativePos = cloudToSurface * (*P);
1181 ccw * atan2(relativePos.
u[
X], relativePos.
u[Y]);
1182 if (lon_rad < 0.0) {
1183 lon_rad += 2 *
M_PI;
1207 unsigned char revolutionAxisDim,
1210 double conicalSpanRatio ,
1211 bool counterclockwise ) {
1213 if (!cloud || cloud->
size() == 0)
return false;
1216 const unsigned char Z = revolutionAxisDim;
1218 const unsigned char X = (Z < 2 ? Z + 1 : 0);
1219 const unsigned char Y = (
X < 2 ?
X + 1 : 0);
1224 double nProj =
ConicalProjectN(latMin_rad, latMax_rad) * conicalSpanRatio;
1227 for (
unsigned n = 0; n < cloud->
size(); ++n) {
1229 CCVector3 relativePos = cloudToSurface * (*P);
1233 ccw * atan2(relativePos.
u[
X], relativePos.
u[Y]);
1256 const QSharedPointer<Map>& map,
1260 double xConversionFactor ,
1261 double yConversionFactor ,
1265 app->
dispToConsole(QString(
"[SaveMapAsCSVMatrix] Internal error: "
1266 "invalid input map!"),
1273 if (!file.open(QFile::WriteOnly | QFile::Text)) {
1275 app->
dispToConsole(QString(
"[SaveMapAsCSVMatrix] Failed to open "
1276 "file for writing! Check access rights"),
1280 QTextStream stream(&file);
1285 stream << QString(
"Height min (%1);").arg(yUnit);
1286 stream << QString(
"Height max (%1);").arg(yUnit);
1289 for (
unsigned i = 0; i < map->xSteps; ++i) {
1291 double minX = xConversionFactor * (map->xMin + i * map->xStep);
1293 xConversionFactor * (map->xMin + (i + 1) * map->xStep);
1294 stream << QString(
"%1-%2 (%3);").arg(minX).arg(maxX).arg(xUnit);
1302 for (
unsigned j = 0; j < map->ySteps; ++j) {
1304 double minY = yConversionFactor *
1305 (map->yMin + (map->ySteps - 1 - j) * map->yStep);
1306 double maxY = yConversionFactor *
1307 (map->yMin + (map->ySteps - j) * map->yStep);
1308 stream << QString::number(minY) << QString(
";");
1309 stream << QString::number(maxY) << QString(
";");
1312 for (
unsigned i = 0; i < map->xSteps; ++i) {
1314 stream << QString::number(map->at(i + j * map->xSteps).value)
1318 stream << QString(
"\n");
1329 bool counterclockwise,
1330 unsigned angularSteps ,
1331 QImage mapTexture ) {
1332 if (!
profile || angularSteps < 3) {
1338 profile->getAssociatedCloud();
1339 unsigned profVertCount = profileVertices->
size();
1340 if (profVertCount < 2) {
1351 unsigned char Z =
static_cast<unsigned char>(profileDesc.
revolDim);
1353 const unsigned char X = (Z < 2 ? Z + 1 : 0);
1354 const unsigned char Y = (
X < 2 ?
X + 1 : 0);
1356 unsigned meshVertCount = profVertCount * angularSteps;
1357 unsigned meshFaceCount = (profVertCount - 1) * angularSteps * 2;
1360 if (!cloud->
reserve(meshVertCount) || !mesh->
reserve(meshFaceCount)) {
1371 double cwSign = (counterclockwise ? -1.0 : 1.0);
1372 for (
unsigned j = 0; j < angularSteps; ++j) {
1374 static_cast<double>(j) / angularSteps * (2 *
M_PI);
1376 CCVector3d N(sin(angle_rad) * cwSign, cos(angle_rad), 0);
1378 for (
unsigned i = 0; i < profVertCount; ++i) {
1380 double radius =
static_cast<double>(P->
x);
1387 profileToCloud.
apply(Pxyz);
1397 profileVertices->
getPoint(profVertCount - 1)->
y - h0;
1398 bool invertedHeight = (dH < 0);
1402 for (
unsigned j = 0; j < angularSteps; ++j) {
1403 unsigned nextJ = ((j + 1) % angularSteps);
1404 for (
unsigned i = 0; i + 1 < profVertCount; ++i) {
1405 unsigned vertA = j * profVertCount + i;
1406 unsigned vertB = nextJ * profVertCount + i;
1407 unsigned vertC = vertB + 1;
1408 unsigned vertD = vertA + 1;
1410 if (invertedHeight) {
1422 if (!mapTexture.isNull()) {
1435 for (
unsigned j = 0; j <= angularSteps; ++j) {
1436 TexCoords2D T(
static_cast<float>(j) / angularSteps, 0.0f);
1437 for (
unsigned i = 0; i < profVertCount; ++i) {
1438 T.
ty = (profileVertices->
getPoint(i)->
y - h0) / dH;
1439 if (invertedHeight) T.
ty = 1.0f - T.
ty;
1451 for (
unsigned j = 0; j < angularSteps; ++j) {
1452 unsigned nextJ = ((j + 1) );
1453 for (
unsigned i = 0; i + 1 < profVertCount; ++i) {
1454 unsigned vertA = j * profVertCount + i;
1455 unsigned vertB = nextJ * profVertCount + i;
1456 unsigned vertC = vertB + 1;
1457 unsigned vertD = vertA + 1;
1459 if (invertedHeight) {
1477 for (
unsigned i = 0; i < meshFaceCount; ++i) {
1485 material->setTexture(mapTexture, QString(),
false);
1504 const QSharedPointer<Map>& map,
1507 bool keepNaNPoints ) {
1508 if (!map || !
profile)
return 0;
1510 unsigned count = map->ySteps * map->xSteps;
1523 profile->getAssociatedCloud();
1524 unsigned polyVertCount = polyVertices->
size();
1525 if (polyVertCount < 2) {
1539 unsigned char Z =
static_cast<unsigned char>(profileDesc.
revolDim);
1541 const unsigned char X = (Z < 2 ? Z + 1 : 0);
1542 const unsigned char Y = (
X < 2 ?
X + 1 : 0);
1544 const double xStep =
1545 baseRadius * (2 *
M_PI) /
static_cast<double>(map->xSteps);
1547 const MapCell* cell = &map->at(0);
1548 for (
unsigned j = 0; j < map->ySteps; ++j) {
1551 (j + 0.5) * map->yStep);
1554 for (
unsigned i = 0; i < map->xSteps; ++i, ++cell) {
1555 if (keepNaNPoints || cell->
count != 0) {
1560 for (
unsigned k = 1; k < polyVertCount; ++k) {
1566 if (alpha >= 0.0 && alpha <= 1.0) {
1568 double radius_th = A->
x + alpha * (B->
x - A->
x);
1579 ScalarType val = cell->
count
1580 ?
static_cast<ScalarType
>(cell->
value)
1597 const QSharedPointer<Map>& map,
1599 unsigned colorScaleSteps ) {
1600 if (!map || !colorScale)
return QImage();
1603 QImage
image(QSize(map->xSteps, map->ySteps), QImage::Format_ARGB32);
1604 if (
image.isNull()) {
1611 bool csIsRelative = colorScale->isRelative();
1613 const MapCell* cell = &map->at(0);
1614 for (
unsigned j = 0; j < map->ySteps; ++j) {
1616 for (
unsigned i = 0; i < map->xSteps; ++i, ++cell) {
1619 if (cell->
count != 0) {
1620 double relativePos =
1621 csIsRelative ? (cell->
value - map->minVal) /
1622 (map->maxVal - map->minVal)
1623 : colorScale->getRelativePosition(
1625 if (relativePos < 0.0)
1627 else if (relativePos > 1.0)
1629 rgb = colorScale->getColorByRelativePos(
1634 image.setPixel(
static_cast<int>(i),
static_cast<int>(j),
1635 qRgb(rgb->
r, rgb->
g, rgb->
b));
constexpr PointCoordinateType PC_ONE
'1' as a PointCoordinateType value
constexpr ScalarType NAN_VALUE
NaN as a ScalarType value.
Vector2Tpl< PointCoordinateType > CCVector2
Default 2D Vector.
float PointCoordinateType
Type of the coordinates of a (N-D) point.
std::shared_ptr< core::Tensor > image
CloudViewerScene::LightingProfile profile
virtual void release()
Decrease counter and deletes object when 0.
Array of 2D texture coordinates.
bool reserveSafe(size_t count)
Reserves memory (no exception thrown)
void addElement(const Type &value)
QSharedPointer< ccColorScale > Shared
Shared pointer type.
virtual void setVisible(bool state)
Sets entity visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
static ccGLMatrixTpl< float > FromToRotation(const Vector3Tpl< float > &from, const Vector3Tpl< float > &to)
Creates a transformation matrix that rotates a vector to another.
T * getTranslation()
Retruns a pointer to internal translation.
ccGLMatrixTpl< T > inverse() const
Returns inverse transformation.
void apply(float vec[3]) const
Applies transformation to a 3D vector (in place) - float version.
void setTranslation(const Vector3Tpl< float > &Tr)
Sets translation (float version)
Float version of ccGLMatrixTpl.
virtual void showMaterials(bool state)
Sets whether textures should be displayed or not.
virtual void deleteOctree()
Erases the octree.
virtual ccOctree::Shared getOctree() const
Returns the associated octree (if any)
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
void removeChild(ccHObject *child)
Mesh (triangle) material.
int addMaterial(ccMaterial::CShared mat, bool allowDuplicateNames=false)
Adds a material.
Mesh (triangle) material.
QSharedPointer< ccMaterial > Shared
Shared type.
bool reservePerTriangleMtlIndexes()
Reserves memory to store per-triangle material index.
void addTriangleMtlIndex(int mtlIndex)
Adds triangle material index for next triangle.
void setMaterialSet(ccMaterialSet *materialSet, bool autoReleaseOldMaterialSet=true)
Sets associated material set (may be shared)
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
void addTriangleTexCoordIndexes(int i1, int i2, int i3)
Adds a triplet of tex coords indexes for next triangle.
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
void removePerTriangleTexCoordIndexes()
Remove per-triangle tex coords indexes.
void setTexCoordinatesTable(TextureCoordsContainer *texCoordsTable, bool autoReleaseOldTable=true)
Sets per-triangle texture coordinates array (may be shared)
bool reservePerTriangleTexCoordIndexes()
Reserves memory to store per-triangle triplets of tex coords indexes.
void setMetaData(const QString &key, const QVariant &data)
Sets a meta-data element.
QVariant getMetaData(const QString &key) const
Returns a given associated meta data.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
void refreshBB() override
Forces bounding-box update.
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool resize(unsigned numberOfPoints) override
Resizes all the active features arrays.
A scalar field associated to display-related parameters.
void computeMinAndMax() override
Determines the min and max values.
A class to compute and handle a Delaunay 2D mesh on a subset of points.
virtual unsigned size() const override
Returns the number of triangles.
void placeIteratorAtBeginning() override
Places the mesh iterator at the beginning.
virtual bool buildMesh(const std::vector< CCVector2 > &points2D, std::size_t pointCountToUse, std::string &outputErrorStr)
Build the Delaunay mesh on top a set of 2D points.
VerticesIndexes * getNextTriangleVertIndexes() override
static constexpr int USE_ALL_POINTS
virtual unsigned size() const =0
Returns the number of points.
A generic 3D point cloud with index-based and presistent access to points.
virtual const CCVector3 * getPoint(unsigned index) const =0
Returns the ith point.
bool oneStep()
Increments total progress value of a single unit.
int getScalarFieldIndexByName(const char *name) const
Returns the index of a scalar field represented by its name.
ScalarField * getScalarField(int index) const
Returns a pointer to a specific scalar field.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
const CCVector3 * getPoint(unsigned index) const override
void addElement(ScalarType value)
ScalarType & getValue(std::size_t index)
void setValue(std::size_t index, ScalarType value)
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
static bool ValidValue(ScalarType value)
Returns whether a scalar value is valid or not.
Main application interface (for plugins)
virtual QMainWindow * getMainWindow()=0
Returns main window.
virtual void dispToConsole(QString message, ConsoleMessageLevel level=STD_CONSOLE_MESSAGE)=0
Graphical progress indicator (thread-safe)
virtual void start() override
virtual void setInfo(const char *infoStr) override
Notifies some information about the ongoing process.
virtual void setMethodTitle(const char *methodTitle) override
Notifies the algorithm title.
__host__ __device__ float2 fabs(float2 v)
static double dist(double x1, double y1, double x2, double y2)
QTextStream & endl(QTextStream &stream)
MiniVec< float, N > ceil(const MiniVec< float, N > &a)
constexpr Rgb lightGrey(static_cast< ColorCompType >(MAX *0.8), static_cast< ColorCompType >(MAX *0.8), static_cast< ColorCompType >(MAX *0.8))
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Triangle described by the indexes of its 3 vertices.