]> Creatis software - creaVtk.git/blobdiff - bbtk_creaVtk_PKG/src/bbcreaVtkCleanMeshWithPatch.cxx
#3526 Active option in HausdorffDistancePointSetFilter box
[creaVtk.git] / bbtk_creaVtk_PKG / src / bbcreaVtkCleanMeshWithPatch.cxx
index 2cdb49b4c02ee2824f2f020b3a37319d70b03345..9fd42dc41b49edcf8abb3b3ee8e97d078b251a50 100644 (file)
@@ -7,7 +7,25 @@
 #include <vtkAppendPolyData.h>
 #include <vtkStaticPointLocator.h>
 #include <vtkDijkstraGraphGeodesicPath.h>
-#include <vtkImprintFilter.h>
+#include <vtkIdList.h>
+#include <vtkCharArray.h>
+#include <vtkPolyDataConnectivityFilter.h>
+#include <vtkPointData.h>
+#include <vtkCellData.h>
+#include <vtkFillHolesFilter.h>
+#include <vtkPolyDataNormals.h>
+#include <vtkIdFilter.h>
+#include <vtkFeatureEdges.h>
+#include <vtkCleanPolyData.h>
+#include <vtkTriangleFilter.h>
+#include <vtkStripper.h>
+#include <vtkTriangleStrip.h>
+#include <vtkRuledSurfaceFilter.h>
+
+
+
+// #include <vtkImprintFilter.h>
+
 
 namespace bbcreaVtk
 {
@@ -33,10 +51,10 @@ void CleanMeshWithPatch::Process()
 //    bbSetOutputOut( bbGetInputIn() );
 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
   
-    printf("EED CleanMeshWithPatch::Process Start \n");
     std::vector<int>    lstIndexs   = bbGetInputLstIndexs();
     if (( lstIndexs.size()>=3 ) && (bbGetInputMesh()!=NULL) ) {
         
+        
         // Step 1. ----Get perimeter CtrlPoints-----
         std::vector<double> lstX        = bbGetInputLstX();
         std::vector<double> lstY        = bbGetInputLstY();
@@ -104,25 +122,24 @@ void CleanMeshWithPatch::Process()
         pointLocator->BuildLocator();
         long int id;
         size=perimeterX.size();
-        std::vector<long int> lstIds;
+        std::vector<long int> lstIdsCtrlPoints;
         for (i=0;i<size;i++)
         {
             id = pointLocator->FindClosestPoint( perimeterX[i]*spc[0] ,perimeterY[i]*spc[1] , perimeterZ[i]*spc[2] ) ;
-            lstIds.push_back( id );
-            printf("EED id=%ld    spc=%f %f %f   point=%f %f %f \n",id,  spc[0],spc[1],spc[2],  perimeterX[i],  perimeterY[i],   perimeterZ[i]  );
+            lstIdsCtrlPoints.push_back( id );
         } // for i  perimeter
         // Step 3 Get geodesic path from segments
         long int id1,id2;
-        vtkAppendPolyData* append                   = vtkAppendPolyData::New();
-        vtkPoints               *points ;
+        std::vector<long int> lstIdsGeodesicPerimter;
+        vtkAppendPolyData* append = vtkAppendPolyData::New();
         for (i=0;i<size;i++)
         {
-            id1=lstIds[i];
+            id1=lstIdsCtrlPoints[i];
             if (i<size-1)
             {
-                id2 = lstIds[i+1];
+                id2 = lstIdsCtrlPoints[i+1];
             } else {
-                id2 = lstIds[0];
+                id2 = lstIdsCtrlPoints[0];
             }// if
             vtkDijkstraGraphGeodesicPath *pathFilter    = vtkDijkstraGraphGeodesicPath::New();
             pathFilter->SetInputData( bbGetInputMesh() );
@@ -131,14 +148,250 @@ void CleanMeshWithPatch::Process()
             pathFilter->Update();
             append->AddInputData( pathFilter->GetOutput() );
             append->Update();
-
-            points         =  pathFilter->GetOutput()->GetPoints();
-            printf("EED nrP=%d \n", points->GetNumberOfPoints()  );
+            
+            // Step 3.1 Puts ids of perimeter Subsegment in vector  lstIdsGeodesicPerimter
+            vtkIdList   *IdsList            = pathFilter->GetIdList();
+            long int    iIdLst,sizeIdLst    = IdsList->GetNumberOfIds();
+            for (iIdLst=0; iIdLst<sizeIdLst; iIdLst++)
+            {
+                lstIdsGeodesicPerimter.push_back( IdsList->GetId(iIdLst) );
+            }// for iIdLst
+            
             pathFilter->Delete();
-//            if (i==0) bbSetOutputOut(  pathFilter->GetOutput() );
         } // for i  perimeter
         append->Update();
+//        bbSetOutputOut( append->GetOutput() );
+
+        // Step 4. -- Define scalars ---
+        vtkCharArray    *scalarsArray   = vtkCharArray::New();
+        vtkPoints       *points         = bbGetInputMesh()->GetPoints();
+        long int        iMPs,sizeMPs    = points->GetNumberOfPoints();
+        scalarsArray->SetNumberOfValues(sizeMPs);
+        for (iMPs=0; iMPs<sizeMPs; iMPs++)
+        {
+            scalarsArray->SetValue(iMPs,15);
+        } // for iMPs
+        long int    iIdLst,sizeIdLst    = lstIdsGeodesicPerimter.size();
+        for (iIdLst=0; iIdLst<sizeIdLst; iIdLst++)
+        {
+            scalarsArray->SetValue( lstIdsGeodesicPerimter[iIdLst]  ,100 );
+        }// for iIdLst
+        scalarsArray->SetName("scalarsPerimeterPatch");
+        bbGetInputMesh()->GetPointData()->AddArray( scalarsArray );
+        bbGetInputMesh()->GetPointData()->SetActiveScalars( "scalarsPerimeterPatch" );
+        bbGetInputMesh()->GetCellData()->SetActiveScalars( "scalarsPerimeterPatch" );
+
+        // Step 5.  -- Connectivity Filter
+        vtkPolyDataConnectivityFilter *connectivity = vtkPolyDataConnectivityFilter::New();
+        connectivity->SetInputData( bbGetInputMesh() );
+        connectivity->SetScalarConnectivity(true);
+
+        // just perimeter mesh
+//        connectivity->SetExtractionModeToPointSeededRegions();
+//        connectivity->InitializeSeedList();
+//        connectivity->AddSeed( lstIdsGeodesicPerimter[0] );
+//        connectivity->SetScalarRange(90,110);
+//        connectivity->SetFullScalarConnectivity(false);
+
+        //connectivity->SetExtractionModeToCellSeededRegions();
+        //connectivity->InitializeSeedList();
+        //connectivity->AddSeed(0);
+        //connectivity->SetScalarRange(10,20);
+        //connectivity->SetFullScalarConnectivity(true);
+
+        //connectivity->SetExtractionModeToPointSeededRegions();
+        //connectivity->InitializeSeedList();
+        //connectivity->AddSeed(0);
+        //connectivity->SetScalarRange(10,20);
+        //connectivity->SetFullScalarConnectivity(true);
+
+        // OK
+
+        connectivity->SetExtractionModeToLargestRegion();
+        connectivity->SetScalarRange(10,20);
+        connectivity->SetFullScalarConnectivity(true);
+
+        
+        connectivity->Update();
+//        bbSetOutputOut( connectivity->GetOutput() );
+
+//        printf("EED CleanMeshWithPatch::Process   connectivity GetNumberOfPoints  %ld \n   ", connectivity->GetOutput()->GetNumberOfPoints() );
+
+/*
+        vtkAppendPolyData* append3 = vtkAppendPolyData::New();
+        append3->AddInputData( connectivity->GetOutput()  );
+        append3->AddInputData( bbGetInputPatch()  );
+        append3->Update();
+
+        vtkStripper *stripper = vtkStripper::New();
+        stripper->SetInputData( append3->GetOutput() );
+        stripper->Update();
+        bbSetOutputOut( stripper->GetOutput() );
+*/
+        
+/*
+        vtkFeatureEdges *edges1 = vtkFeatureEdges::New();
+        edges1->SetInputData( connectivity->GetOutput() );
+        edges1->BoundaryEdgesOn();
+        edges1->ManifoldEdgesOff();
+        edges1->NonManifoldEdgesOff();
+        edges1->FeatureEdgesOff();
+        edges1->Update();
+//        bbSetOutputOut( edges1->GetOutput() );
+
+        vtkFeatureEdges *edges2 = vtkFeatureEdges::New();
+        edges2->SetInputData( bbGetInputPatch() );
+        edges2->BoundaryEdgesOn();
+        edges2->ManifoldEdgesOff();
+        edges2->NonManifoldEdgesOff();
+        edges2->FeatureEdgesOff();
+        edges2->Update();
+//        bbSetOutputOut( edges1->GetOutput() );
+
+        vtkAppendPolyData* append3 = vtkAppendPolyData::New();
+        append3->AddInputData( edges1->GetOutput()  );
+        append3->AddInputData( edges2->GetOutput()  );
+        append3->Update();
+//        bbSetOutputOut( append3->GetOutput() );
+        vtkRuledSurfaceFilter *ruledSurfaceFilter = vtkRuledSurfaceFilter::New();
+        ruledSurfaceFilter->SetInputData( append3->GetOutput() );
+        ruledSurfaceFilter->Update();
+        bbSetOutputOut( ruledSurfaceFilter->GetOutput() );
+
+ */
+        
+        
+        // ok
+//        bbSetOutputOut( connectivity->GetOutput() );
+
+        
+        vtkCleanPolyData *connectivityClean = vtkCleanPolyData::New();
+        connectivityClean->SetInputData( connectivity->GetOutput() );
+        connectivityClean->Update();
+        
+        //step 6.2.  -- connect both meshes     ConnectivityClean->Patch    --
+        Stretch(  bbGetInputPatch(), connectivityClean->GetOutput()  );
+        //step 6.1.  -- connect both meshes     Patch->ConnectivityClean    --
+        Stretch( connectivityClean->GetOutput() , bbGetInputPatch() );
+
+     /*
+        //step 6.1.  -- connect both meshes     Patch->ConnectivityClean    --
+        vtkIdFilter *idFilter = vtkIdFilter::New();
+        idFilter->SetInputData( bbGetInputPatch() );
+        //idFilter->SetIdsArrayName("ids");
+        //idFilter->SetCellIdsArrayName("ids");
+        idFilter->SetPointIdsArrayName("ids");
+        idFilter->SetPointIds(true);
+        idFilter->SetCellIds(false);
+//# Available for vtk>=8.3:
+//           #idFilter.SetPointIdsArrayName(arrayName)
+//           #idFilter.SetCellIdsArrayName(arrayName)
+        idFilter->Update();
+        vtkFeatureEdges *edges = vtkFeatureEdges::New();
+        edges->SetInputData( idFilter->GetOutput() );
+        edges->BoundaryEdgesOn();
+        edges->ManifoldEdgesOff();
+        edges->NonManifoldEdgesOff();
+        edges->FeatureEdgesOff();
+        edges->Update();
+        vtkIdTypeArray* arrayIds = vtkIdTypeArray::SafeDownCast(edges->GetOutput()->GetPointData()->GetArray("ids"));
+        long int iIds,sizeArrayIds    = edges->GetOutput()->GetNumberOfPoints();
+printf("\n EED CleanMeshWithPatch::Process  sizeArrayIds=%ld \n", sizeArrayIds);
+        
+        
+        vtkPolyData             *newMesh        = connectivityClean->GetOutput();
+        vtkStaticPointLocator   *pointLocator2  = vtkStaticPointLocator::New();
+        pointLocator2->SetDataSet( newMesh );
+        pointLocator2->BuildLocator();
+        vtkPoints *pointsPatch    = bbGetInputPatch()->GetPoints();
+        vtkPoints *pointsNewMesh  = newMesh->GetPoints();
+        double pP[3], pPP[3];
+        long int idNewMesh;
+        for (iIds=0; iIds<sizeArrayIds ; iIds++ )
+        {
+            pointsPatch->GetPoint( arrayIds->GetValue(iIds) , pP );
+            idNewMesh = pointLocator2->FindClosestPoint(pP);
+            pointsNewMesh->GetPoint( idNewMesh , pPP );
+            pointsPatch->SetPoint( arrayIds->GetValue(iIds) , pPP );
+ printf(" iIds=%ld   pP=%f %f %f     idNewMesh=%ld   pPP=%f %f %f \n", arrayIds->GetValue(iIds) , pP[0], pP[1], pP[2], idNewMesh, pPP[0], pPP[1], pPP[2]  );
+        } // for iIds
+        bbGetInputPatch()->Modified();
 
+        //step 6.2.  -- connect both meshes     ConnectivityClean->Patch    --
+        vtkIdFilter *idFilter2 = vtkIdFilter::New();
+        idFilter2->SetInputData( newMesh );
+        //idFilter->SetIdsArrayName("ids");
+        //idFilter->SetCellIdsArrayName("ids");
+        idFilter2->SetPointIdsArrayName("ids");
+        idFilter2->SetPointIds(true);
+        idFilter2->SetCellIds(false);
+//# Available for vtk>=8.3:
+//           #idFilter.SetPointIdsArrayName(arrayName)
+//           #idFilter.SetCellIdsArrayName(arrayName)
+        idFilter2->Update();
+        vtkFeatureEdges *edges2 = vtkFeatureEdges::New();
+        edges2->SetInputData( idFilter2->GetOutput() );
+        edges2->BoundaryEdgesOn();
+        edges2->ManifoldEdgesOff();
+        edges2->NonManifoldEdgesOff();
+        edges2->FeatureEdgesOff();
+        edges2->Update();
+        vtkIdTypeArray* arrayIds2 = vtkIdTypeArray::SafeDownCast(edges2->GetOutput()->GetPointData()->GetArray("ids"));
+        long int iIds2,sizeArrayIds2    = edges2->GetOutput()->GetNumberOfPoints();
+printf("\n EED CleanMeshWithPatch::Process  sizeArrayIds2=%ld \n", sizeArrayIds2);
+//        vtkPolyData             *newMesh        = connectivityClean->GetOutput();
+        vtkStaticPointLocator   *pointLocator3  = vtkStaticPointLocator::New();
+        pointLocator3->SetDataSet( bbGetInputPatch() );
+        pointLocator3->BuildLocator();
+        vtkPoints *pointsNewMesh2   = newMesh->GetPoints();
+        vtkPoints *pointsPatch2     = bbGetInputPatch()->GetPoints();
+        double pP2[3], pPP2[3];
+        long int idPatch;
+        for (iIds2=0; iIds2<sizeArrayIds2 ; iIds2++ )
+        {
+            pointsNewMesh2->GetPoint( arrayIds2->GetValue(iIds2) , pP2 );
+            idPatch = pointLocator3->FindClosestPoint(pP2);
+            pointsPatch2->GetPoint( idPatch , pPP2 );
+            pointsNewMesh2->SetPoint( arrayIds2->GetValue(iIds) , pPP2 );
+ printf(" iIds=%ld   pP=%f %f %f     idNewMesh=%ld   pPP=%f %f %f \n", arrayIds2->GetValue(iIds) , pP2[0], pP2[1], pP2[2], idPatch, pPP2[0], pPP2[1], pPP2[2]  );
+        } // for iIds
+        newMesh->Modified();
+*/
+        
+        
+        // step 7. -- Append meshes--
+        vtkAppendPolyData* append2 = vtkAppendPolyData::New();
+        append2->AddInputData( connectivityClean->GetOutput()  );
+        append2->AddInputData( bbGetInputPatch()  );
+        append2->Update();
+
+        vtkCleanPolyData *append2Clean = vtkCleanPolyData::New();
+        append2Clean->SetInputData( append2->GetOutput() );
+        append2Clean->Update();
+        
+        vtkTriangleFilter *triangles = vtkTriangleFilter::New();
+        triangles->SetInputData( append2Clean->GetOutput() );
+        triangles->Update();
+//        bbSetOutputOut( triangles->GetOutput() );
+        
+        //step 8.  -- Clean  --
+
+        vtkPolyDataNormals *normals =vtkPolyDataNormals::New();
+        normals->SetInputConnection( triangles->GetOutputPort() );
+       normals->SetInputConnection( append2Clean->GetOutputPort() );
+        normals->ConsistencyOn();
+        normals->SplittingOff();
+        normals->Update();
+//       bbSetOutputOut( normals->GetOutput() );
+
+        vtkFillHolesFilter *fillHoles = vtkFillHolesFilter::New();
+        fillHoles->SetInputData( normals->GetOutput() );
+        fillHoles->SetHoleSize(1000);
+        fillHoles->Update();
+        bbSetOutputOut( fillHoles->GetOutput() );
+        
+        
+        /*
         // Step 4. -- vtkImprintFilter ---
         vtkImprintFilter *imp = vtkImprintFilter::New();
 //        imp->SetTargetData( append->GetOutput() );
@@ -161,13 +414,92 @@ void CleanMeshWithPatch::Process()
         
         imp->SetTolerance(500);
         imp->Update();
-
-        bbSetOutputOut( imp->GetOutput() );
-        printf("EED CleanMeshWithPatch::Process size=%d \n", perimeterX.size());
+         bbSetOutputOut( imp->GetOutput() );
+*/
+        
+    } else {
+        bbSetOutputOut( NULL );
     } // if LstIndexs size >=3
-    printf("EED CleanMeshWithPatch::Process End \n");
+        
+}
+
+
+
+void CleanMeshWithPatch::Stretch(vtkPolyData *newMesh, vtkPolyData *patchMesh)
+{
+    
+    vtkIdFilter *idFilter = vtkIdFilter::New();
+    idFilter->SetInputData( patchMesh );
+    //idFilter->SetIdsArrayName("ids");
+    //idFilter->SetCellIdsArrayName("ids");
+    idFilter->SetPointIdsArrayName("ids");
+    idFilter->SetPointIds(true);
+    idFilter->SetCellIds(false);
+//# Available for vtk>=8.3:
+//           #idFilter.SetPointIdsArrayName(arrayName)
+//           #idFilter.SetCellIdsArrayName(arrayName)
+    idFilter->Update();
+    vtkFeatureEdges *edges = vtkFeatureEdges::New();
+    edges->SetInputData( idFilter->GetOutput() );
+    edges->BoundaryEdgesOn();
+    edges->ManifoldEdgesOff();
+    edges->NonManifoldEdgesOff();
+    edges->FeatureEdgesOff();
+    edges->Update();
+    vtkIdTypeArray* arrayIds = vtkIdTypeArray::SafeDownCast(edges->GetOutput()->GetPointData()->GetArray("ids"));
+    long int iIds,sizeArrayIds    = edges->GetOutput()->GetNumberOfPoints();
+    
+    
+//EED2
+    vtkIdFilter *idFilter2 = vtkIdFilter::New();
+    idFilter2->SetInputData( newMesh );
+    //idFilter2->SetIdsArrayName("ids");
+    //idFilter2->SetCellIdsArrayName("ids");
+    idFilter2->SetPointIdsArrayName("ids");
+    idFilter2->SetPointIds(true);
+    idFilter2->SetCellIds(false);
+//# Available for vtk>=8.3:
+//           #idFilter2.SetPointIdsArrayName(arrayName)
+//           #idFilter2.SetCellIdsArrayName(arrayName)
+    idFilter2->Update();
+    vtkFeatureEdges *edges2 = vtkFeatureEdges::New();
+    edges2->SetInputData( idFilter2->GetOutput() );
+    edges2->BoundaryEdgesOn();
+    edges2->ManifoldEdgesOff();
+    edges2->NonManifoldEdgesOff();
+    edges2->FeatureEdgesOff();
+    edges2->Update();
+    vtkIdTypeArray* arrayIds2       = vtkIdTypeArray::SafeDownCast(edges2->GetOutput()->GetPointData()->GetArray("ids"));
+    long int iIds2,sizeArrayIds2    = edges2->GetOutput()->GetNumberOfPoints();
+    
+
+    
+    
+    vtkStaticPointLocator   *pointLocator2  = vtkStaticPointLocator::New();
+//EED2    pointLocator2->SetDataSet( newMesh );
+    pointLocator2->SetDataSet( edges2->GetOutput() );
+
+    pointLocator2->BuildLocator();
+    vtkPoints *pointsPatch    = patchMesh->GetPoints();
+    vtkPoints *pointsNewMesh  = newMesh->GetPoints();
+    double pP[3], pPP[3];
+    long int idNewMesh;
+    for (iIds=0; iIds<sizeArrayIds ; iIds++ )
+    {
+        pointsPatch->GetPoint( arrayIds->GetValue(iIds) , pP );
+        
+//EED2        idNewMesh =   pointLocator2->FindClosestPoint(pP);
+        iIds2 =    pointLocator2->FindClosestPoint(pP);
+        idNewMesh = arrayIds2->GetValue(iIds2);
+        
+        pointsNewMesh->GetPoint( idNewMesh , pPP );
+        pointsPatch->SetPoint( arrayIds->GetValue(iIds) , pPP );
+    } // for iIds
+    patchMesh->Modified();
 }
 
+
+
 //===== 
 // Before editing this file, make sure it's a file of your own (i.e.: it wasn't generated from xml description; if so : your modifications will be lost)
 //=====