[vtkusers] vtExtractEdges spurious behavior

BBerco bebe0705 at colorado.edu
Tue Aug 7 07:03:38 EDT 2018


I have encountered a spurious behaviour of vtkExtractEdges, simply triggered
by re-ordering the connectivity table of an input OBJ file.

I am trying to extract the edges of a polyhedron in the form of : 

edge = (i0,i1,f0,f1)

where (i0,i1) are the indices of the two points at both ends of the edge and
(f0,f1) the indices of the two facets delimiting the edge.

To my surprise, my approach (summarized in the code below) works fine for
some OBJ files. But in some odd cases, vtkExtractEdges brings up
combinations of (i0,i1) that do not form an edge

I have attached a minimal functional example hereunder.

In addition, here's an obj file revealing the issue. As is, everything works
fine. But try flipping two rows at the beginning of the connectivity table

f 1 2 3
f 1 3 4
f 1 4 5
f 1 5 6
f 1 6 7
f 1 7 2
f 2 8 9

into

f 2 8 9
f 1 2 3
f 1 3 4
f 1 4 5
f 1 5 6
f 1 6 7
f 1 7 2

and notice how the exception is raised.


Any advice?

https://github.com/bbercovici/SBGAT/blob/master/Tests/input/KW4Alpha.obj


#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkExtractEdges.h>
#include <vtkSphereSource.h>
#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkLine.h>
#include <vtkOBJReader.h>
#include <vector>
#include <array>


int main(int, char *[]){

  std::string filename  = "KW4Alpha.obj";

  // Reading
  vtkSmartPointer<vtkOBJReader> reader =
vtkSmartPointer<vtkOBJReader>::New();
  reader -> SetFileName(filename.c_str());
  reader -> Update(); 

  vtkPolyData * input = reader -> GetOutput();


  vtkSmartPointer<vtkExtractEdges> extractEdges =
  vtkSmartPointer<vtkExtractEdges>::New();
  extractEdges->SetInputConnection(reader->GetOutputPort());
  extractEdges->Update();

  
  unsigned int edge_count = extractEdges->GetOutput()->GetNumberOfCells();
  std::vector<std::array<vtkIdType,4>>
edge_points_ids_facet_ids(edge_count);

  // Should get rid of this map and use a vector instead
  // This loop cannot be parallelized since GetPointCells is 
  // not thread-safe
  for(vtkIdType i = 0; i < edge_count; i++){

    vtkSmartPointer<vtkLine> line =
vtkLine::SafeDownCast(extractEdges->GetOutput()->GetCell(i));
    
    edge_points_ids_facet_ids[i][0] = line->GetPointIds()->GetId(0);
    edge_points_ids_facet_ids[i][1] = line->GetPointIds()->GetId(1);

    // We need to find the facets forming this edge
    vtkSmartPointer<vtkIdList> facet_ids_point_1 =
vtkSmartPointer<vtkIdList>::New();
    vtkSmartPointer<vtkIdList> facet_ids_point_2 =
vtkSmartPointer<vtkIdList>::New();

    input -> GetPointCells  (
edge_points_ids_facet_ids[i][0],facet_ids_point_1 );
    input -> GetPointCells  (
edge_points_ids_facet_ids[i][1],facet_ids_point_2 );

    // Indices of points forming considered edge, 1-indexed so as to be
consistent with the input obj file
    std::cout << line->GetPointIds()->GetId(0) + 1 << " / " <<
line->GetPointIds()->GetId(1) + 1 << std::endl;

    // Now, we find the two facet indices showing up in both
facet_ids_point_1 and facet_ids_point_2
    facet_ids_point_1 -> IntersectWith  ( facet_ids_point_2 ) ;

    if (facet_ids_point_1 -> GetNumberOfIds() != 2){
      throw(std::runtime_error("the intersection of the facet id lists
should have exactly 2 items, not " + std::to_string(facet_ids_point_1 ->
GetNumberOfIds())));
    }

    edge_points_ids_facet_ids[i][2] = facet_ids_point_1->GetId(0);
    edge_points_ids_facet_ids[i][3] = facet_ids_point_1->GetId(1);
    
  }




  return EXIT_SUCCESS;
}






--
Sent from: http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html


More information about the vtkusers mailing list