//===== // 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) //===== #include "bbcreaVtkCleanMeshWithPatch.h" #include "bbcreaVtkPackage.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // #include namespace bbcreaVtk { BBTK_ADD_BLACK_BOX_TO_PACKAGE(creaVtk,CleanMeshWithPatch) BBTK_BLACK_BOX_IMPLEMENTATION(CleanMeshWithPatch,bbtk::AtomicBlackBox); //===== // 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) //===== void CleanMeshWithPatch::Process() { // THE MAIN PROCESSING METHOD BODY // Here we simply set the input 'In' value to the output 'Out' // And print out the output value // INPUT/OUTPUT ACCESSORS ARE OF THE FORM : // void bbSet{Input|Output}NAME(const TYPE&) // const TYPE& bbGet{Input|Output}NAME() const // Where : // * NAME is the name of the input/output // (the one provided in the attribute 'name' of the tag 'input') // * TYPE is the C++ type of the input/output // (the one provided in the attribute 'type' of the tag 'input') // bbSetOutputOut( bbGetInputIn() ); // std::cout << "Output value = " < lstIndexs = bbGetInputLstIndexs(); if (( lstIndexs.size()>=3 ) && (bbGetInputMesh()!=NULL) ) { // Step 1. ----Get perimeter CtrlPoints----- std::vector lstX = bbGetInputLstX(); std::vector lstY = bbGetInputLstY(); std::vector lstZ = bbGetInputLstZ(); std::vector perimeterX; std::vector perimeterY; std::vector perimeterZ; std::vector tmpX; std::vector tmpY; std::vector tmpZ; int iGroup,sizeGroups = lstIndexs.size(); int i,iGeneral=0,size; for (iGroup=0 ; iGroup=iGeneral ; i--) { perimeterX.push_back( lstX[i] ); perimeterY.push_back( lstY[i] ); perimeterZ.push_back( lstZ[i] ); } // for i last group } // if iGroup == 0 iGeneral=iGeneral+lstIndexs[iGroup]; } // for size=tmpX.size(); for (i=0; i spc; if (bbGetInputSpacing().size()<3) { spc.push_back(1); spc.push_back(1); spc.push_back(1); } else { spc = bbGetInputSpacing(); }// vtkStaticPointLocator *pointLocator; pointLocator = vtkStaticPointLocator::New(); pointLocator->SetDataSet( bbGetInputMesh() ); pointLocator->BuildLocator(); long int id; size=perimeterX.size(); std::vector lstIdsCtrlPoints; for (i=0;iFindClosestPoint( perimeterX[i]*spc[0] ,perimeterY[i]*spc[1] , perimeterZ[i]*spc[2] ) ; lstIdsCtrlPoints.push_back( id ); } // for i perimeter // Step 3 Get geodesic path from segments long int id1,id2; std::vector lstIdsGeodesicPerimter; vtkAppendPolyData* append = vtkAppendPolyData::New(); for (i=0;iSetInputData( bbGetInputMesh() ); pathFilter->SetStartVertex( id1 ); pathFilter->SetEndVertex( id2 ); pathFilter->Update(); append->AddInputData( pathFilter->GetOutput() ); append->Update(); // Step 3.1 Puts ids of perimeter Subsegment in vector lstIdsGeodesicPerimter vtkIdList *IdsList = pathFilter->GetIdList(); long int iIdLst,sizeIdLst = IdsList->GetNumberOfIds(); for (iIdLst=0; iIdLstGetId(iIdLst) ); }// for iIdLst pathFilter->Delete(); } // 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; iMPsSetValue(iMPs,15); } // for iMPs long int iIdLst,sizeIdLst = lstIdsGeodesicPerimter.size(); for (iIdLst=0; iIdLstSetValue( 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; iIdsGetPoint( 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; iIds2GetPoint( 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() ); // imp->SetImprintData( bbGetInputMesh() ); // imp->SetTargetData( bbGetInputMesh() ); // imp->SetImprintData( append->GetOutput() ); // imp->SetTargetData( bbGetInputMesh() ); // imp->SetImprintData( bbGetInputPatch() ); imp->SetTargetData( bbGetInputMesh() ); imp->SetImprintData( bbGetInputPatch() ); // imp->SetOutputTypeToProjectedImprint(); imp->SetOutputTypeToTargetCells(); // imp->SetOutputTypeToImprintedCells(); // imp->SetOutputTypeToImprintedRegion(); // imp->SetOutputTypeToMergedImprint(); imp->SetTolerance(500); imp->Update(); bbSetOutputOut( imp->GetOutput() ); */ } else { bbSetOutputOut( NULL ); } // if LstIndexs size >=3 } 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; iIdsGetPoint( 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) //===== void CleanMeshWithPatch::bbUserSetDefaultValues() { // SET HERE THE DEFAULT INPUT/OUTPUT VALUES OF YOUR BOX // Here we initialize the input 'In' to 0 bbSetInputMesh(NULL); bbSetInputPatch(NULL); bbSetOutputOut(NULL); } //===== // 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) //===== void CleanMeshWithPatch::bbUserInitializeProcessing() { // THE INITIALIZATION METHOD BODY : // Here does nothing // but this is where you should allocate the internal/output pointers // if any } //===== // 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) //===== void CleanMeshWithPatch::bbUserFinalizeProcessing() { // THE FINALIZATION METHOD BODY : // Here does nothing // but this is where you should desallocate the internal/output pointers // if any } } // EO namespace bbcreaVtk