//    bbSetOutputOut( bbGetInputIn() );
 //    std::cout << "Output value = " <<bbGetOutputOut() << std::endl;
 
-       bbGetInputWidgetShowNPoints()->DeleteAllPoints();
+       bbGetInputWidgetShowNPoints()->DeleteAllPoints_();
        bbGetInputWidgetShowNPoints()->GetModelShowNPoints()->SetFirstTime(true);
 }
 //===== 
 
          (wsp->GetModelShowNPoints()->GetLstPointsSize()==4) &&
          (bbGetInputMesh()!=NULL ) )
     {
+        std::vector<long int>   lstIdNormal;
         double                  spc[3];
                                 spc[0]          = bbGetInputSpacing()[0];
                                 spc[1]          = bbGetInputSpacing()[1];
         p[2] = lstZ[0] + dz*s;
         NearestPointToMesh(points, pointLocator, spc, p,pM);
         wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
+        lstIdNormal.push_back( pointLocator->FindClosestPoint(pM) );
         s=s*2;
         p[0] = lstX[0] + dx*s;
         p[1] = lstY[0] + dy*s;
         p[2] = lstZ[0] + dz*s;
         NearestPointToMesh(points, pointLocator, spc, p,pM);
         wsp->InsertPoint(pM[0],pM[1], pM[2],"");
+        lstIdNormal.push_back( pointLocator->FindClosestPoint(pM) );
 
         // --- Group 1 ---
-        wsp->OnInsertCollectionAfter_();
+        wsp->InsertCollectionAfter_();
           p[0] = (lstX[0]+lstX[3])/2;
           p[1] = (lstY[0]+lstY[3])/2;
           p[2] = (lstZ[0]+lstZ[3])/2;
           NearestPointToMesh(points, pointLocator, spc, p,pM);
           wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
+          lstIdNormal.push_back( pointLocator->FindClosestPoint(pM) );
           p[0] = (lstX[1]+lstX[2])/2;
           p[1] = (lstY[1]+lstY[2])/2;
           p[2] = (lstZ[1]+lstZ[2])/2;
           NearestPointToMesh(points, pointLocator, spc, p,pM);
           wsp->InsertPoint(pM[0] ,pM[1], pM[2],"");
+          lstIdNormal.push_back( pointLocator->FindClosestPoint(pM) );
           p[0] = (lstX[0]+lstX[1]+lstX[2]+lstX[3])/4;          p[1] = (lstY[0]+lstY[1]+lstY[2]+lstY[3])/4;          p[2] = (lstZ[0]+lstZ[1]+lstZ[2]+lstZ[3])/4;
           wsp->InsertPoint(p[0] ,p[1], p[2],"");
 
         // --- Group 2 ---
-        wsp->OnInsertCollectionAfter_();
+        wsp->InsertCollectionAfter_();
           p[0] = lstX[3];
           p[1] = lstY[3];
           p[2] = lstZ[3];
           wsp->InsertPoint(p[0] ,p[1], p[2],"");
+          lstIdNormal.push_back( pointLocator->FindClosestPoint(p) );
           p[0] = lstX[2];
           p[1] = lstY[2];
           p[2] = lstZ[2];
           wsp->InsertPoint(p[0] ,p[1], p[2],"");
+          lstIdNormal.push_back( pointLocator->FindClosestPoint(p) );
           dx = lstX[2]-lstX[3];
           dy = lstY[2]-lstY[3];
           dz = lstZ[2]-lstZ[3];
 
         wsp->SetOutputBox();
         pointLocator->Delete();
+        
+        
+        // Check normals
+        1. Recorrer las normales de lstIdNormals y calcular el promedio  -> V1
+        2. Calcular el promedio de 4 normales de la nueva superficie     -> V2
+        3. Calcular el angulo entre V1 y V2
+        4. Si el angulo es major de 90 Invertir las normales de la superficie actual
+        
+        
+        // --- Finish ---
+        wsp->UndoRedo_SaveCollection();
     } else {
             printf("EED ShowNPoints_Tools::CreatePatch01  Warning patch not apply. Need juste one group with four points\n");
     } // if
         } // if Type
         if (bbGetInputType()==50)
         {
-            bbGetInputWidgetShowNPoints()->DeleteAllPoints();
+            bbGetInputWidgetShowNPoints()->OnDeleteAllPoints_();
         } // if Type
         if (bbGetInputType()==100)
         {
         } // if Type
         if (bbGetInputType()==210)
         {
-            bbGetInputWidgetShowNPoints()->InvertLstPoints();
+            bbGetInputWidgetShowNPoints()->OnInvertLstPoints_();
         } // if Type
     } // if bbGetInputWidgetShowNPoints
 }
 
     } else {//mpoint.size
         printf("creaMaracasVisu::ShowNPoints (not match point) \n");
     }
+    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
        } else {//mpoint.size
                printf("creaMaracasVisu::ShowNPoints (not match point) \n");
        }
+    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnAddPoint (wxCommandEvent& event)
 {
     OnAddPoint_();
-    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnInsertPoint (wxCommandEvent& event)//CFT
 {
     OnInsertPoint_();
-    UndoRedo_SaveCollection();
 }
 
 
         GetViewShowNPoints()->Render();
     } // if id
     SetOutputBox();
+    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnSetPoint(wxCommandEvent& event)
 {
     OnSetPoint_();
-    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
         //renderer->GetRenderWindow()->Render();
         GetViewShowNPoints()->Render();
         StopTrackPoint();
+        UndoRedo_SaveCollection();
     }
 
 //------------------------------------------------------------------------
        void WidgetShowNPoints::OnErasePoint(wxCommandEvent& event)
        {
                OnErasePoint_();
-        UndoRedo_SaveCollection();
        }
 
 //------------------------------------------------------------------------
        }
 
 //------------------------------------------------------------------------
-void WidgetShowNPoints::DeleteAllPoints()
+void WidgetShowNPoints::DeleteAllPoints_()
 {
     // EED 2022-05-19
     //int id,size=lstActorsSphere.size();
     }// for id
 }
 
+void WidgetShowNPoints::OnDeleteAllPoints_()
+{
+    DeleteAllPoints_();
+    UndoRedo_SaveCollection();
+}
 
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnDeleteAllPoints(wxCommandEvent& event)
 {
-       DeleteAllPoints();
+       OnDeleteAllPoints_();
     SetOutputBox();
     GetViewShowNPoints()->Render();
-    UndoRedo_SaveCollection();
 }
 
 //NTU: Method for updating points opacity and Radio
 }
 
 //------------------------------------------------------------------------
-void WidgetShowNPoints::OnInsertCollectionBefore(wxCommandEvent &event)
+void WidgetShowNPoints::InsertCollectionBefore_()
 {
     InsertCollection();
     RefreshCollectionText();
 }
 
 //------------------------------------------------------------------------
-void WidgetShowNPoints::OnInsertCollectionAfter_()
+void WidgetShowNPoints::OnInsertCollectionBefore_()
+{
+    InsertCollectionBefore_();
+    UndoRedo_SaveCollection();
+}
+
+
+//------------------------------------------------------------------------
+void WidgetShowNPoints::OnInsertCollectionBefore(wxCommandEvent &event)
+{
+    OnInsertCollectionBefore_();
+}
+
+
+//------------------------------------------------------------------------
+void WidgetShowNPoints::InsertCollectionAfter_()
 {
     mActualCollection++;
     InsertCollection();
     StopTrackPoint();
 }
 
+//------------------------------------------------------------------------
+void WidgetShowNPoints::OnInsertCollectionAfter_()
+{
+    InsertCollectionAfter_();
+    UndoRedo_SaveCollection();
+}
+
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnInsertCollectionAfter(wxCommandEvent &event)
 {
 {
     if ( lstModelShowNPoints.size()>1 )
     {
-        DeleteAllPoints();  // Actual Collection
+        DeleteAllPoints_();  // Actual Collection
         lstModelShowNPoints.erase( lstModelShowNPoints.begin()+mActualCollection );
         lstViewShowNPoints.erase( lstViewShowNPoints.begin()+mActualCollection );
         if ( mActualCollection>=lstModelShowNPoints.size() )
             mActualCollection--;
         } // if
     } else {
-        DeleteAllPoints();  // Actual Collection
+        DeleteAllPoints_();  // Actual Collection
     } // if
 }
 
     RefreshCollectionText();
     RefreshColourCollection();
     StopTrackPoint();
+    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnDeleteCollection(wxCommandEvent &event)
 {
     OnDeleteCollection_();
-    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
-void WidgetShowNPoints::OnResetCollections_()
+void WidgetShowNPoints::ResetCollections_()
 {
     int i,size=lstModelShowNPoints.size();
     for (i=0;i<size;i++)
     StopTrackPoint();
 }
 
+
+//------------------------------------------------------------------------
+void WidgetShowNPoints::OnResetCollections_()
+{
+    ResetCollections_();
+    UndoRedo_SaveCollection();
+}
+
+
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnResetCollections(wxCommandEvent &event)
 {
     OnResetCollections_();
-    UndoRedo_SaveCollection();
 }
 
 //------------------------------------------------------------------------
 }
 
 //------------------------------------------------------------------------
-void WidgetShowNPoints::InvertLstPoints()
+void WidgetShowNPoints::InvertLstPoints_()
 {
     int i,size=lstModelShowNPoints.size();
     for (i=0 ;  i < size ; i++)
     SetOutputBox();
 }
 
+//------------------------------------------------------------------------
+void WidgetShowNPoints::OnInvertLstPoints_()
+{
+    InvertLstPoints_();
+    UndoRedo_SaveCollection();
+}
+
 
 //------------------------------------------------------------------------
 std::string WidgetShowNPoints::GetUndoRedoFileName()
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnUndo(wxCommandEvent &event)
 {
-    OnResetCollections_();
+    ResetCollections_();
 //    if (idUndoRedo==maxUndoRedo+1)
 //    {
 //       idUndoRedo--;
 //    } // if idUndoRedo+1
     idUndoRedo--;
     idUndoRedo--;
-    printf("EED  WidgetShowNPoints::OnUndo %d  %d\n", idUndoRedo, maxUndoRedo);
     if (idUndoRedo<0)
     {
         idUndoRedo=-1;
 //------------------------------------------------------------------------
 void WidgetShowNPoints::OnRedo(wxCommandEvent &event)
 {
-    printf("EED  WidgetShowNPoints::OnRedo A  %d  %d\n", idUndoRedo, maxUndoRedo);
     if (idUndoRedo>maxUndoRedo)
     {
         idUndoRedo=maxUndoRedo+1;
     } else {
-        OnResetCollections_();
+        ResetCollections_();
         OnLoadCollections_( GetUndoRedoFileName() );
         idUndoRedo++;
     }// if idUndoRedo
-    
-    printf("EED  WidgetShowNPoints::OnRedo B  %d  %d\n", idUndoRedo, maxUndoRedo);
-
 }
 
 //------------------------------------------------------------------------
 void WidgetShowNPoints::UndoRedo_SaveCollection()
 {
-    printf("EED  \n EED WidgetShowNPoints::UndoRedo_SaveCollection %d  %d\n", idUndoRedo, maxUndoRedo);
     OnSaveCollections_( GetUndoRedoFileName() );
     maxUndoRedo = idUndoRedo;
     idUndoRedo++;
-    printf("EED  WidgetShowNPoints::UndoRedo_SaveCollection %d  %d\n", idUndoRedo, maxUndoRedo);
 }
 
 
 
       void OnErasePoint_();
          void OnErasePoint(wxCommandEvent& event);
          void OnEraseLastPoint(wxCommandEvent &event); 
+      void DeleteAllPoints_();
+      void OnDeleteAllPoints_();
          void OnDeleteAllPoints(wxCommandEvent &event);
-    
+
          void OnSavePoints(wxCommandEvent &event);   
          void OnLoadPoints(wxCommandEvent &event);
 
       void UpdatePoints_();
 
       void InsertCollection();
+      void InsertCollectionBefore_();
+      void OnInsertCollectionBefore_();
       void OnInsertCollectionBefore(wxCommandEvent &event);
+      void InsertCollectionAfter_();
       void OnInsertCollectionAfter_();
       void OnInsertCollectionAfter(wxCommandEvent &event);
       void OnDeleteCollection_();
       void OnSaveCollections_( std::string filename );
       void OnLoadCollections(wxCommandEvent &event);
       void OnLoadCollections_( std::string filename );
-      void OnResetCollections(wxCommandEvent &event);
+      void ResetCollections_();
       void OnResetCollections_();
-    
+      void OnResetCollections(wxCommandEvent &event);
+
       void OnUndo(wxCommandEvent &event);
       void OnRedo(wxCommandEvent &event);
       void UndoRedo_SaveCollection();
 
       void RefreshCollectionText();
       void RefreshColourCollection();
-      void InvertLstPoints();
-    
+      void InvertLstPoints_();
+      void OnInvertLstPoints_();
+
       // EED 2022-05-19
          //void RefreshPoint(int id);
       //void RefreshPoints();
          void AddPoint(int x, int y, int z, std::string label);
       void OnInsertPoint_();
          void InsertPoint(int x, int y, int z, std::string label);//CFT
-         void DeleteAllPoints();
 
       int GetLstModelShowNPointsSize();
          ModelShowNPoints* GetModelShowNPoints();
       ViewShowNPoints* GetViewShowNPoints();
          void SetInitLstPoints( std::vector<int> initLstPointsX,  std::vector<int> initLstPointsY, std::vector<int> initLstPointsZ, std::vector<std::string> initLstLabels );
 
-               void SetType(int type);
-               int  GetType();
-
-               double GetRadio();
-               double GetOpacity();
-
-    virtual void                      SetOutputBox();
-    void                              ErasePoint(int id);
-
-    
-    
-    std::vector<int> GetLstPointsX();
-    std::vector<int> GetLstPointsY();
-    std::vector<int> GetLstPointsZ();
-    std::vector<std::string> GetLstLabels();
-    std::vector<int> GetLstIndexs();
+      void          SetType(int type);
+      int           GetType();
+      double        GetRadio();
+      double        GetOpacity();
+      virtual void  SetOutputBox();
+      void          ErasePoint(int id);
+
+      std::vector<int> GetLstPointsX();
+      std::vector<int> GetLstPointsY();
+      std::vector<int> GetLstPointsZ();
+      std::vector<std::string> GetLstLabels();
+      std::vector<int> GetLstIndexs();