Skip to content

Commit 9c2c636

Browse files
committed
Address MR comments.
Make point duplication user selectable Make tolerance used for point duplication adjustable User better name for test PNG.
1 parent e83695b commit 9c2c636

File tree

5 files changed

+121
-71
lines changed

5 files changed

+121
-71
lines changed

IO/PLY/Testing/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ vtk_module_test_data(
55
Data/squareTextured.ply
66
Data/squareTexturedFaces.ply
77
Data/vtk.png
8-
Data/2vtk.png)
8+
Data/two_vtk_logos_stacked.png)
99

1010
add_subdirectory(Cxx)
1111

IO/PLY/Testing/Cxx/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ vtk_add_test_cxx(vtkIOPLYCxxTests tests
1111
)
1212
vtk_add_test_cxx(vtkIOPLYCxxTests tests
1313
TestPLYReaderTextureUVFaces,TestPLYReaderTextureUV.cxx squareTexturedFaces.ply
14-
2vtk.png
14+
two_vtk_logos_stacked.png
1515
)
1616
vtk_test_cxx_executable(vtkIOPLYCxxTests tests)

IO/PLY/vtkPLYReader.cxx

Lines changed: 93 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ namespace {
9898
vtkPLYReader::vtkPLYReader()
9999
{
100100
this->Comments = vtkStringArray::New();
101+
this->FaceTextureTolerance = 0.000001;
102+
this->DuplicatePointsForFaceTexture = true;
101103
}
102104

103105
vtkPLYReader::~vtkPLYReader()
@@ -431,8 +433,7 @@ int vtkPLYReader::RequestData(
431433
pointIds.resize(output->GetNumberOfPoints());
432434
// Used to detect different texture values at a vertex.
433435
vtkNew<vtkIncrementalOctreePointLocator> texLocator;
434-
float tolerance = 0.000001;
435-
texLocator->SetTolerance(tolerance);
436+
texLocator->SetTolerance(this->FaceTextureTolerance);
436437
double bounds[] = {0.0, 1.0, 0.0, 1.0, 0.0, 0.0};
437438
texLocator->InitPointInsertion(texCoords, bounds);
438439

@@ -467,10 +468,13 @@ int vtkPLYReader::RequestData(
467468
{
468469
vtkPLY::ply_get_property(ply, elemName, &faceProps[6]);
469470
texCoordsPoints->SetNumberOfTuples(numPts);
470-
// initialize texture coordinates with invalid value
471-
for (int j = 0; j < numPts; ++j)
471+
if (this->DuplicatePointsForFaceTexture)
472472
{
473-
texCoordsPoints->SetTuple2(j, -1, -1);
473+
// initialize texture coordinates with invalid value
474+
for (int j = 0; j < numPts; ++j)
475+
{
476+
texCoordsPoints->SetTuple2(j, -1, -1);
477+
}
474478
}
475479
}
476480

@@ -512,82 +516,105 @@ int vtkPLYReader::RequestData(
512516
//Test to know if there is a texcoord for every vertex
513517
if (face.nverts == (face.ntexcoord / 2))
514518
{
515-
for (int k = 0; k < face.nverts; k++)
519+
if (this->DuplicatePointsForFaceTexture)
516520
{
517-
// texture stored at vtkVerts[k] point
518-
float currentTex[2];
519-
texCoordsPoints->GetTypedTuple(vtkVerts[k], currentTex);
520-
// new texture stored at the current face
521-
float newTex[] = {face.texcoord[k * 2],
522-
face.texcoord[k * 2 + 1]};
523-
double newTex3[] = {newTex[0], newTex[1], 0};
524-
if (currentTex[0] == -1.0)
525-
{
526-
// newly seen texture coordinates for vertex
527-
texCoordsPoints->SetTuple2(vtkVerts[k], newTex[0], newTex[1]);
528-
vtkIdType ti;
529-
texLocator->InsertUniquePoint(newTex3, ti);
530-
pointIds.resize(
531-
std::max(ti+1,
532-
static_cast<vtkIdType>(pointIds.size())));
533-
pointIds[ti].push_back(vtkVerts[k]);
534-
}
535-
else
521+
for (int k = 0; k < face.nverts; k++)
536522
{
537-
if (! vtkMathUtilities::FuzzyCompare(
538-
currentTex[0], newTex[0], tolerance) ||
539-
! vtkMathUtilities::FuzzyCompare(
540-
currentTex[1], newTex[1], tolerance))
523+
// new texture stored at the current face
524+
float newTex[] = {face.texcoord[k * 2],
525+
face.texcoord[k * 2 + 1]};
526+
// texture stored at vtkVerts[k] point
527+
float currentTex[2];
528+
texCoordsPoints->GetTypedTuple(vtkVerts[k], currentTex);
529+
double newTex3[] = {newTex[0], newTex[1], 0};
530+
if (currentTex[0] == -1.0)
541531
{
542-
// different texture coordinate than stored at point vtkVerts[k]
532+
// newly seen texture coordinates for vertex
533+
texCoordsPoints->SetTuple2(
534+
vtkVerts[k], newTex[0], newTex[1]);
543535
vtkIdType ti;
544-
int inserted = texLocator->InsertUniquePoint(newTex3, ti);
545-
if (inserted)
546-
{
547-
// newly seen texture coordinate for vertex which already has
548-
// some texture coordinates.
549-
vtkIdType dp = duplicateCellPoint(
550-
output, cell, k);
551-
texCoordsPoints->SetTuple2(dp, newTex[0], newTex[1]);
552-
pointIds.resize(
553-
std::max(ti+1, static_cast<vtkIdType>(pointIds.size())));
554-
pointIds[ti].push_back(dp);
555-
}
556-
else
536+
texLocator->InsertUniquePoint(newTex3, ti);
537+
pointIds.resize(
538+
std::max(ti+1,
539+
static_cast<vtkIdType>(pointIds.size())));
540+
pointIds[ti].push_back(vtkVerts[k]);
541+
}
542+
else
543+
{
544+
if (! vtkMathUtilities::FuzzyCompare(
545+
currentTex[0], newTex[0],
546+
this->FaceTextureTolerance) ||
547+
! vtkMathUtilities::FuzzyCompare(
548+
currentTex[1], newTex[1],
549+
this->FaceTextureTolerance))
557550
{
558-
size_t sameTexIndex = 0;
559-
if (pointIds[ti].size() > 1)
551+
// different texture coordinate
552+
// than stored at point vtkVerts[k]
553+
vtkIdType ti;
554+
int inserted = texLocator->InsertUniquePoint(newTex3, ti);
555+
if (inserted)
560556
{
561-
double first[3];
562-
output->GetPoint(vtkVerts[k], first);
563-
for (;sameTexIndex < pointIds[ti].size(); ++sameTexIndex)
557+
// newly seen texture coordinate for vertex
558+
// which already has some texture coordinates.
559+
vtkIdType dp = duplicateCellPoint(
560+
output, cell, k);
561+
texCoordsPoints->SetTuple2(dp, newTex[0], newTex[1]);
562+
pointIds.resize(
563+
std::max(
564+
ti+1, static_cast<vtkIdType>(pointIds.size())));
565+
pointIds[ti].push_back(dp);
566+
}
567+
else
568+
{
569+
size_t sameTexIndex = 0;
570+
if (pointIds[ti].size() > 1)
564571
{
565-
double second[3];
566-
output->GetPoint(pointIds[ti][sameTexIndex],second);
567-
if (FuzzyEqual(first, second, tolerance))
572+
double first[3];
573+
output->GetPoint(vtkVerts[k], first);
574+
for (;sameTexIndex < pointIds[ti].size();
575+
++sameTexIndex)
568576
{
569-
break;
577+
double second[3];
578+
output->GetPoint(pointIds[ti][sameTexIndex],second);
579+
if (FuzzyEqual(first, second,
580+
this->FaceTextureTolerance))
581+
{
582+
break;
583+
}
584+
}
585+
if (sameTexIndex == pointIds[ti].size())
586+
{
587+
// newly seen point for this texture coordinate
588+
vtkIdType dp = duplicateCellPoint(
589+
output, cell, k);
590+
texCoordsPoints->SetTuple2(dp, newTex[0], newTex[1]);
591+
pointIds[ti].push_back(dp);
570592
}
571593
}
572-
if (sameTexIndex == pointIds[ti].size())
573-
{
574-
// newly seen point for this texture coordinate
575-
vtkIdType dp = duplicateCellPoint(
576-
output, cell, k);
577-
texCoordsPoints->SetTuple2(dp, newTex[0], newTex[1]);
578-
pointIds[ti].push_back(dp);
579-
}
580-
}
581594

582-
// texture coordinate already seen before, use the vertex
583-
// associated with these texture coordinates
584-
vtkIdType vi = pointIds[ti][sameTexIndex];
585-
setCellPoint(cell, k, vi);
595+
// texture coordinate already seen before, use the vertex
596+
// associated with these texture coordinates
597+
vtkIdType vi = pointIds[ti][sameTexIndex];
598+
setCellPoint(cell, k, vi);
599+
}
586600
}
601+
// same texture coordinate, nothing to do.
587602
}
588-
// same texture coordinate, nothing to do.
589603
}
590604
}
605+
else
606+
{
607+
// if we don't want point duplication we only need to set
608+
// the texture coordinates
609+
for (int k = 0; k < face.nverts; k++)
610+
{
611+
// new texture stored at the current face
612+
float newTex[] = {face.texcoord[k * 2],
613+
face.texcoord[k * 2 + 1]};
614+
texCoordsPoints->SetTuple2(vtkVerts[k], newTex[0], newTex[1]);
615+
}
616+
}
617+
591618
}
592619
else
593620
{

IO/PLY/vtkPLYReader.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@
2727
* to the output data.
2828
* If the "face" element has the property "texcoord" a new TCoords
2929
* point array is created and points are duplicated if they have 2 or
30-
* more different texture coordinates. This creates a polygonal data
31-
* that can be textured without artifacts. If unique points are
32-
* required use a vtkCleanPolyData filter after this reader.
30+
* more different texture coordinates. Points are duplicated only if
31+
* DuplicatePointsForFaceTexture is true (default).
32+
* This creates a polygonal data that can be textured without
33+
* artifacts. If unique points are required use a vtkCleanPolyData
34+
* filter after this reader or use this reader with DuplicatePointsForFaceTexture
35+
* set to false.
3336
*
3437
* @sa
3538
* vtkPLYWriter, vtkCleanPolyData
@@ -61,6 +64,23 @@ class VTKIOPLY_EXPORT vtkPLYReader : public vtkAbstractPolyDataReader
6164

6265
vtkGetObjectMacro(Comments, vtkStringArray);
6366

67+
/**
68+
* Tolerance used to detect different texture coordinates for shared
69+
* points for faces.
70+
*/
71+
vtkGetMacro(FaceTextureTolerance, float);
72+
vtkSetMacro(FaceTextureTolerance, float);
73+
74+
/**
75+
* If true (default) and the "face" element has the property "texcoord" duplicate
76+
* face points if they have 2 or more different texture coordinates.
77+
* Otherwise, each texture coordinate for a face point overwrites previously set
78+
* texture coordinates for that point.
79+
*/
80+
vtkGetMacro(DuplicatePointsForFaceTexture, bool);
81+
vtkSetMacro(DuplicatePointsForFaceTexture, bool);
82+
83+
6484
protected:
6585
vtkPLYReader();
6686
~vtkPLYReader() override;
@@ -71,6 +91,9 @@ class VTKIOPLY_EXPORT vtkPLYReader : public vtkAbstractPolyDataReader
7191
private:
7292
vtkPLYReader(const vtkPLYReader&) = delete;
7393
void operator=(const vtkPLYReader&) = delete;
94+
95+
float FaceTextureTolerance;
96+
bool DuplicatePointsForFaceTexture;
7497
};
7598

7699
#endif

0 commit comments

Comments
 (0)