11 #pragma warning(disable : 4996)
22 #include <pcl/common/io.h>
23 #include <pcl/io/vtk_io.h>
24 #include <pcl/io/vtk_lib_io.h>
26 #include <pcl/io/impl/vtk_lib_io.hpp>
43 #include <vtkFloatArray.h>
44 #include <vtkPolyData.h>
47 #ifdef vtkGenericDataArray_h
48 #define SetTupleValue SetTypedTuple
49 #define InsertNextTupleValue InsertNextTypedTuple
50 #define GetTupleValue GetTypedTuple
56 CVLog::Warning(
"[vtk2cc::ConvertToPointCloud] polydata is nullptr");
61 vtkIdType pointCount = polydata->GetNumberOfPoints();
64 if (pointCount == 0) {
67 "[vtk2cc::ConvertToPointCloud] polydata has 0 points");
72 vtkPointData* pointData = polydata->GetPointData();
73 vtkFieldData* fieldData = polydata->GetFieldData();
81 vtkUnsignedCharArray*
colors =
nullptr;
82 bool hasSourceRGBFlag =
false;
86 vtkIntArray* hasRGBArray =
87 vtkIntArray::SafeDownCast(fieldData->GetArray(
"HasSourceRGB"));
88 if (hasRGBArray && hasRGBArray->GetValue(0) == 1) {
89 hasSourceRGBFlag =
true;
97 if (hasSourceRGBFlag) {
99 const char* colorArrayNames[] = {
"RGB",
"Colors",
"rgba",
"rgb"};
100 for (
const char*
name : colorArrayNames) {
101 vtkDataArray* arr = pointData->GetArray(
name);
103 if (arr->GetNumberOfComponents() == 3 ||
104 arr->GetNumberOfComponents() == 4) {
105 colors = vtkUnsignedCharArray::SafeDownCast(arr);
118 vtkFloatArray*
normals =
nullptr;
121 normals = vtkFloatArray::SafeDownCast(pointData->GetNormals());
125 vtkDataArray* arr = pointData->GetArray(
"Normals");
126 if (arr && arr->GetNumberOfComponents() == 3) {
127 normals = vtkFloatArray::SafeDownCast(arr);
135 if (!cloud->
resize(
static_cast<unsigned>(pointCount))) {
138 "[vtk2cc::ConvertToPointCloud] not enough memory!"));
148 QString(
"[getPointCloudFromPolyData] not enough memory!"));
158 QString(
"[getPointCloudFromPolyData] not enough memory!"));
165 for (vtkIdType i = 0; i < pointCount; ++i) {
166 double coordinate[3];
167 polydata->GetPoint(i, coordinate);
168 cloud->
setPoint(
static_cast<std::size_t
>(i),
179 unsigned char color[3];
196 if (pointData && pointCount > 0) {
197 int numArrays = pointData->GetNumberOfArrays();
199 for (
int i = 0; i < numArrays; ++i) {
200 vtkDataArray* dataArray = pointData->GetArray(i);
203 if (!dataArray || dataArray->GetNumberOfComponents() != 1) {
208 if (dataArray->GetNumberOfTuples() < pointCount) {
211 QString(
"[vtk2cc] Scalar array %1 has only %2 "
212 "tuples but pointCount is %3")
213 .arg(dataArray->GetName()
214 ? dataArray->GetName()
216 .arg(dataArray->GetNumberOfTuples())
227 const char* arrayName = dataArray->GetName();
228 if (!arrayName || strlen(arrayName) == 0) {
234 if (!scalarField->
reserveSafe(
static_cast<unsigned>(pointCount))) {
245 if (!scalarField->
resizeSafe(
static_cast<unsigned>(pointCount))) {
256 for (vtkIdType j = 0; j < pointCount; ++j) {
257 double value = dataArray->GetTuple1(j);
258 scalarField->
setValue(
static_cast<unsigned>(j),
259 static_cast<ScalarType
>(value));
269 QString(
"[vtk2cc] Failed to add scalar field: %1")
275 QString fieldName = QString(arrayName).toLower();
276 if (fieldName.contains(
"label") ||
277 fieldName.contains(
"class") ||
278 fieldName.contains(
"segment") ||
279 fieldName.contains(
"cluster")) {
299 QString(
"[getMeshFromPolyData] polydata has no points!"));
305 static_cast<unsigned>(mesh_points->GetNumberOfPoints());
306 unsigned nr_polygons =
static_cast<unsigned>(polydata->GetNumberOfPolys());
307 if (nr_points == 0) {
310 QString(
"[getMeshFromPolyData] cannot find points data!"));
328 if (!mesh->
reserve(nr_polygons)) {
330 CVLog::Warning(QString(
"[getMeshFromPolyData] not enough memory!"));
336 #ifdef VTK_CELL_ARRAY_V2
337 const vtkIdType* cell_points;
339 vtkIdType* cell_points;
341 vtkIdType nr_cell_points;
342 vtkCellArray* mesh_polygons = polydata->GetPolys();
343 mesh_polygons->InitTraversal();
344 unsigned int validTriangles = 0;
345 unsigned int skippedCells = 0;
347 while (mesh_polygons->GetNextCell(nr_cell_points, cell_points)) {
348 if (nr_cell_points != 3) {
354 mesh->
addTriangle(
static_cast<unsigned>(cell_points[0]),
355 static_cast<unsigned>(cell_points[1]),
356 static_cast<unsigned>(cell_points[2]));
361 if (validTriangles == 0) {
364 "[getMeshFromPolyData] No triangles found in polydata"));
371 if (skippedCells > 0 && !silent) {
372 CVLog::Warning(QString(
"[getMeshFromPolyData] Skipped %1 non-triangle "
374 "added %2 triangle(s)")
376 .arg(validTriangles));
393 if (!polydata)
return nullptr;
398 QString(
"[getPolylineFromPolyData] failed to convert "
399 "vtkPolyData to ccPointCloud"));
403 if (obj->
size() == 0) {
405 "[getPolylineFromPolyData] polyline vertices is empty!"));
428 unsigned verticesCount = polyVertices->
size();
429 if (curvePoly->
reserve(verticesCount)) {
437 polyVertices->
getPoint(verticesCount - 1)->
u);
445 curvePoly->
setName(
"polyline");
465 vtkIdType iCells = polydata->GetNumberOfCells();
466 for (vtkIdType i = 0; i < iCells; i++) {
468 vtkCell* cell = polydata->GetCell(i);
469 vtkIdType ptsCount = cell->GetNumberOfPoints();
472 if (!vertices->
reserve(
static_cast<unsigned>(ptsCount))) {
473 CVLog::Error(
"not enough memory to allocate vertices...");
477 for (vtkIdType iPt = 0; iPt < ptsCount; ++iPt) {
485 if (vertices && vertices->
size() == 0) {
510 QString contourName = baseName;
511 if (poly->
size() > 1) {
512 contourName += QString(
" (part %1)").arg(i + 1);
519 container.push_back(poly);
float PointCoordinateType
Type of the coordinates of a (N-D) point.
virtual void release()
Decrease counter and deletes object when 0.
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Error(const char *format,...)
Display an error dialog with formatted message.
Array of compressed 3D normals (single index)
static Vector3Tpl fromArray(const int a[3])
Constructor from an int array.
virtual void setVisible(bool state)
Sets entity visibility.
virtual void setTempColor(const ecvColor::Rgb &col, bool autoActivate=true)
Sets current temporary (unique)
virtual void showNormals(bool state)
Sets normals visibility.
virtual void showColors(bool state)
Sets colors visibility.
virtual void showSF(bool state)
Sets active scalarfield visibility.
void setPointSize(unsigned size=0)
Sets point size.
static ccPointCloud * ToPointCloud(ccHObject *obj, bool *isLockedVertices=nullptr)
Converts current object to 'equivalent' ccPointCloud.
virtual bool addChild(ccHObject *child, int dependencyFlags=DP_PARENT_OF_OTHER, int insertIndex=-1)
Adds a child.
std::vector< ccHObject * > Container
Standard instances container (for children, etc.)
NormsIndexesTableType * getTriNormsTable() const override
Returns per-triangle normals shared array.
bool reserve(std::size_t n)
Reserves the memory to store the vertex indexes (3 per triangle)
void addTriangle(unsigned i1, unsigned i2, unsigned i3)
Adds a triangle to the mesh.
void shrinkToFit()
Removes unused capacity.
virtual void setLocked(bool state)
Sets the "enabled" property.
virtual void setName(const QString &name)
Sets object name.
virtual void setEnabled(bool state)
Sets the "enabled" property.
bool isKindOf(CV_CLASS_ENUM type) const
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
void setCurrentDisplayedScalarField(int index)
Sets the currently displayed scalar field.
void addNorm(const CCVector3 &N)
Pushes a normal vector on stack (shortcut)
int addScalarField(const char *uniqueName) override
Creates a new scalar field and registers it.
bool hasNormals() const override
Returns whether normals are enabled or not.
bool reserve(unsigned numberOfPoints) override
Reserves memory for all the active features.
bool reserveTheNormsTable()
Reserves memory to store the compressed normals.
bool reserveTheRGBTable()
Reserves memory to store the RGB colors.
bool resize(unsigned numberOfPoints) override
Resizes all the active features arrays.
void shrinkToFit()
Removes unused capacity.
void addRGBColor(const ecvColor::Rgb &C)
Pushes an RGB color on stack.
bool hasScalarFields() const override
Returns whether one or more scalar fields are instantiated.
void set2DMode(bool state)
Defines if the polyline is considered as 2D or 3D.
A scalar field associated to display-related parameters.
void computeMinAndMax() override
Determines the min and max values.
void addPoint(const CCVector3 &P)
Adds a 3D point to the database.
unsigned size() const override
void setPoint(size_t index, const CCVector3 &P)
const CCVector3 * getPoint(unsigned index) const override
void setClosed(bool state)
Sets whether the polyline is closed or not.
virtual bool addPointIndex(unsigned globalIndex)
Point global index insertion mechanism.
unsigned size() const override
Returns the number of points.
virtual bool reserve(unsigned n)
Reserves some memory for hosting the point references.
void setValue(std::size_t index, ScalarType value)
bool reserveSafe(std::size_t count)
Reserves memory (no exception thrown)
bool resizeSafe(std::size_t count, bool initNewElements=false, ScalarType valueForNewElements=0)
Resizes memory (no exception thrown)
static ccMesh * ConvertToMesh(vtkPolyData *polydata, bool silent=false)
static ccPolyline * ConvertToPolyline(vtkPolyData *polydata, bool silent=false)
static ccPointCloud * ConvertToPointCloud(vtkPolyData *polydata, bool silent=false)
static std::vector< ccHObject * > ConvertToMultiPolylines(vtkPolyData *polydata, QString baseName="Slice", const ecvColor::Rgb &color=ecvColor::green)
unsigned char ColorCompType
Default color components type (R,G and B)
bool LessThanEpsilon(float x)
Test a floating point number against our epsilon (a very small number).
constexpr Rgb red(MAX, 0, 0)
constexpr Rgb green(0, MAX, 0)