]> Creatis software - creaMaracasVisu.git/blobdiff - bbtk/src/bbcreaMaracasVisuShowNPoints_Tools.cxx
#3528 Contour ordering around axis
[creaMaracasVisu.git] / bbtk / src / bbcreaMaracasVisuShowNPoints_Tools.cxx
index 0d76ac3ddf54633515715ab69a6ca05dbf0129b3..fa719af0edf67ec31544ecf0b35a200b8c61422c 100644 (file)
@@ -862,6 +862,112 @@ void ShowNPoints_Tools::SetMesh()
     wsp->SetAuxMesh(bbGetInputMesh(), bbGetInputSpacing(), bbGetInputParams() );
 }
 
+void ShowNPoints_Tools::SeparateSplines()
+{
+       WidgetShowNPoints* wsp = bbGetInputWidgetShowNPoints();
+       if((wsp->GetLstModelShowNPointsSize() > 0) && (bbGetInputParams().size() == 3))
+       {
+               std::vector<double> refPoint = bbGetInputParams();
+               std::vector<double> pointsX, pointsY, pointsZ;
+               std::vector<std::vector<std::vector<double>>> newGroups;
+               std::vector<std::vector<double>> planesNorm;
+               
+               double rotAxis[3] = {0,0,1};
+               
+               double vector1[3], vector2[3], planeNormal[3], rotatedNormal[3], axisPoint[3], refPlaneNorm[3];
+               int idPoint2, idPoint3;
+               
+               int numGroups = wsp->GetLstModelShowNPointsSize();
+               for(int i = 0; i < numGroups; i++){
+                       pointsX = wsp->GetModelShowNPoints(i)->GetLstPointsX();
+                       pointsY = wsp->GetModelShowNPoints(i)->GetLstPointsY();
+                       pointsZ = wsp->GetModelShowNPoints(i)->GetLstPointsZ();
+                       
+                       idPoint2 = ((int)pointsX.size()/3)-1;
+                       idPoint3 = idPoint2*2;
+                       
+                       vector1[0] = pointsX[idPoint2]-refPoint[0];
+                       vector1[1] = pointsY[idPoint2]-refPoint[1];
+                       vector1[2] = pointsZ[idPoint2]-refPoint[2];
+                       
+                       vector2[0] = pointsX[idPoint3]-refPoint[0];
+                       vector2[1] = pointsY[idPoint3]-refPoint[1];
+                       vector2[2] = pointsZ[idPoint3]-refPoint[2];
+                       
+                       vtkMath::Cross(vector1, vector2, planeNormal);
+                       vtkMath::Normalize(planeNormal);
+                       vtkMath::Cross(planeNormal, rotAxis, rotatedNormal);
+                       vtkMath::Normalize(rotatedNormal);
+                       
+                       if(i == 0){
+                               std::copy(std::begin(planeNormal), std::end(planeNormal), std::begin(refPlaneNorm));
+                       }
+                       
+                       std::vector<std::vector<double>> pointsOver, pointsUnder, pointsOn;
+                       std::vector<double> point(3);
+                       for(int j = 0; j < pointsX.size(); j++){
+                               point[0] = pointsX[j];
+                               point[1] = pointsY[j];
+                               point[2] = pointsZ[j];
+                               vtkMath::Subtract(point.data(), refPoint.data(), vector1);
+                               if(vtkMath::Dot(vector1, rotatedNormal) > 0){
+                                       pointsOver.push_back(point);
+                               }
+                               else if (vtkMath::Dot(vector1, rotatedNormal) < 0){
+                                       pointsUnder.push_back(point);
+                               }
+                               //else{
+                               //      pointsOn.push_back(j);
+                               //}
+                       }
+                       
+                       std::vector<double> normalToSave(std::begin(planeNormal), std::end(planeNormal));
+                       if(!pointsOver.empty()){                        
+                               newGroups.push_back(pointsOver);
+                               planesNorm.push_back(normalToSave);
+                       }
+                       if(!pointsUnder.empty()){       
+                               std::reverse(pointsUnder.begin(), pointsUnder.end());
+                               newGroups.push_back(pointsUnder);
+                               vtkMath::MultiplyScalar(planeNormal, -1);
+                               normalToSave[0] = planeNormal[0]; normalToSave[1] = planeNormal[1]; normalToSave[2] = planeNormal[2];
+                               planesNorm.push_back(normalToSave);
+                       }
+                       
+
+               }
+               
+               auto comp = [&](int id1,int id2)-> bool {
+                       //double dot = vtkMath::Dot(planesNorm[id1].data(), refPlaneNorm);
+                       //double det = vtkMath::Determinant3x3(planesNorm[id1].data(), refPlaneNorm, rotAxis);
+                       //double angle1 = atan2(det, dot);
+                       double angle1 = vtkMath::SignedAngleBetweenVectors(planesNorm[id1].data(), refPlaneNorm, rotAxis);
+                       if(angle1 < 0) angle1 += 2*vtkMath::Pi();
+                       double angle2 = vtkMath::SignedAngleBetweenVectors(planesNorm[id2].data(), refPlaneNorm, rotAxis);
+                       if(angle2 < 0) angle2 += 2*vtkMath::Pi();
+                       return angle1 < angle2;
+       };
+               
+               std::vector<int> indexVect((int)newGroups.size());
+               std::iota(std::begin(indexVect), std::end(indexVect), 0);
+               std::sort(indexVect.begin(), indexVect.end(), comp);
+               
+               wsp->ResetCollections_();
+               for(int i = 0; i < newGroups.size(); i++){
+                       std::vector<std::vector<double>> group = newGroups[indexVect[i]];
+                       for(int j = 0; j < group.size(); j++){
+                               std::vector<double> point = group[j];
+                               wsp->AddPoint(point[0] ,point[1], point[2],"");
+                       }
+                       if(i < newGroups.size()-1){
+                               wsp->InsertCollectionAfter_();
+                       }
+               }
+               wsp->SetOutputBox();
+        wsp->UndoRedo_SaveCollection();
+       }
+}
+
 //=====
 // 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)
 //===== 
@@ -978,6 +1084,10 @@ void ShowNPoints_Tools::Process()
         {
                ExpandPatch();
         } // if Type
+        if(bbGetInputType()==400)
+        {
+               SeparateSplines();
+        } // if Type
     } // if bbGetInputWidgetShowNPoints
 }
 //=====