TriangleSetTopologyAlgorithms.inl

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_TOPOLOGY_TRIANGLESETTOPOLOGYALGORITHMS_INL
00026 #define SOFA_COMPONENT_TOPOLOGY_TRIANGLESETTOPOLOGYALGORITHMS_INL 
00027 
00028 #include <sofa/component/topology/TriangleSetTopologyContainer.h>
00029 #include <sofa/component/topology/TriangleSetTopologyModifier.h>
00030 #include <sofa/component/topology/TriangleSetTopologyAlgorithms.h>
00031 #include <sofa/component/topology/TriangleSetGeometryAlgorithms.h>
00032 
00033 #include <sofa/component/MechanicalObject.h>
00034 
00035 #include <algorithm>
00036 #include <functional>
00037 
00038 namespace sofa
00039 {
00040 namespace component
00041 {
00042 namespace topology
00043 {
00044 
00045     using namespace sofa::defaulttype;    
00046       
00047     template<class DataTypes>
00048     void TriangleSetTopologyAlgorithms< DataTypes >::init()
00049     {
00050         EdgeSetTopologyAlgorithms< DataTypes >::init();     
00051         this->getContext()->get(m_container);
00052         this->getContext()->get(m_modifier);
00053         this->getContext()->get(m_geometryAlgorithms);
00054     }   
00055 
00056     // Move and fix the two closest points of two triangles to their median point
00057     template<class DataTypes>
00058     bool TriangleSetTopologyAlgorithms< DataTypes >::Suture2Points(unsigned int ind_ta, unsigned int ind_tb, 
00059         unsigned int &ind1, unsigned int &ind2)
00060     {
00061         // Access the topology
00062         m_geometryAlgorithms->closestIndexPair(ind_ta, ind_tb, ind1, ind2);
00063 
00064         //std::cout << "INFO_print : ind1 = " << ind1 << std::endl;
00065         //std::cout << "INFO_print : ind2 = " << ind2 << std::endl;
00066 
00067         sofa::helper::vector< unsigned int > indices;
00068         indices.push_back(ind1); indices.push_back(ind2);
00069 
00070         Vec<3,Real> point_created=(Vec<3,double>) m_geometryAlgorithms->computeBaryEdgePoint(indices, (double) 0.5);
00071 
00072         sofa::helper::vector< double > x_created;
00073         x_created.push_back((double) point_created[0]); 
00074         x_created.push_back((double) point_created[1]);
00075         x_created.push_back((double) point_created[2]);
00076 
00078         MechanicalState<DataTypes>* state = m_geometryAlgorithms->getDOF();
00079         MechanicalObject<DataTypes> *temp = dynamic_cast<MechanicalObject<DataTypes> *>(state);
00080         temp->forcePointPosition(ind1, x_created);
00081         temp->forcePointPosition(ind2, x_created);
00082 
00083         return true;
00084     }
00085 
00086     // Incises along the list of points (ind_edge,coord) intersected by the segment from point a to point b and the triangular mesh
00087     // Point a belongs to the triangle sindexed by ind_ta
00088     // Point b belongs to the triangle sindexed by ind_tb
00089 
00090     template<class DataTypes>
00091     bool TriangleSetTopologyAlgorithms< DataTypes >::InciseAlongPointsList(bool is_first_cut, 
00092                                             const Vec<3,double>& a, 
00093                                             const Vec<3,double>& b, 
00094                                             const unsigned int ind_ta, 
00095                                             const unsigned int ind_tb,
00096                                             unsigned int& a_last, 
00097                                             sofa::helper::vector< unsigned int > &a_p12_last, 
00098                                             sofa::helper::vector< unsigned int > &a_i123_last, 
00099                                             unsigned int& b_last, 
00100                                             sofa::helper::vector< unsigned int > &b_p12_last, 
00101                                             sofa::helper::vector< unsigned int > &b_i123_last, 
00102                                             sofa::helper::vector< sofa::helper::vector<unsigned int> > &new_points, 
00103                                             sofa::helper::vector< sofa::helper::vector<unsigned int> > &closest_vertices)
00104     {
00105 
00106         double epsilon = 0.2; // INFO : epsilon is a threshold in [0,1] to control the snapping of the extremities to the closest vertex
00107 
00108         unsigned int x_i1 = 0;
00109         unsigned int x_i2 = 0; 
00110         unsigned int x_i3 = 0;
00111         unsigned int x_i1_to = 0;
00112         unsigned int x_i2_to = 0; 
00113         unsigned int x_p1 = 0;
00114         unsigned int x_p2 = 0;
00115         unsigned int x_p1_to = 0;
00116         unsigned int x_p2_to = 0;
00117 
00118         Vec<3,Real> a_new = a;
00119         unsigned int ind_ta_new = ind_ta;
00120         Vec<3,Real> b_new = b;
00121         unsigned int ind_tb_new = ind_tb;
00122 
00123         unsigned int ind_ta_test_init;
00124         unsigned int ind_tb_test_init;
00125 
00126         unsigned int &ind_ta_test = ind_ta_test_init;
00127         unsigned int &ind_tb_test = ind_tb_test_init;
00128 
00129         unsigned int ind_tb_final_init;
00130         unsigned int &ind_tb_final = ind_tb_final_init;
00131 
00132         bool is_on_boundary_init=false;
00133         bool &is_on_boundary=is_on_boundary_init;
00134 
00135         if(is_first_cut)
00136         {
00137             bool is_a_inside = m_geometryAlgorithms->is_PointinTriangle(true, a_new, ind_ta_new, ind_ta_test);
00138             if(is_a_inside)
00139             {
00140                 //std::cout << "a is inside" <<  std::endl;
00141             }
00142             else
00143             {
00144                 //std::cout << "a is NOT inside !!!" <<  std::endl;
00145                 if(ind_ta_new == ind_ta_test) // fail
00146                 { 
00147                     //std::cout << "fail !!!" <<  std::endl;
00148                     return false;
00149                 }
00150                 else
00151                 {
00152                     ind_ta_new=ind_ta_test;
00153                 }
00154             }
00155         }
00156 
00157         bool is_b_inside = m_geometryAlgorithms->is_PointinTriangle(true, b_new, ind_tb_new, ind_tb_test);
00158         if(is_b_inside)
00159         {
00160             //std::cout << "b is inside" <<  std::endl;
00161         }
00162         else
00163         {
00164             //std::cout << "b is NOT inside !!!" <<  std::endl;
00165             if(ind_tb_new==ind_tb_test) // fail
00166             { 
00167                 //std::cout << "fail !!!" <<  std::endl;
00168                 return false;
00169             }
00170             else
00171             {
00172                 ind_tb_new=ind_tb_test;
00173             }
00174         }
00175 
00176         if(ind_ta_new==ind_tb_new)
00177         {
00178             return false;
00179         }
00180 
00181         //const typename DataTypes::VecCoord& vect_c = *topology->getDOF()->getX();
00182         unsigned int nb_points =  m_container->getTriangleVertexShellArray().size() - 1; //vect_c.size() -1;
00183 
00184         const sofa::helper::vector<Triangle> &vect_t = m_container->getTriangleArray();
00185         unsigned int nb_triangles =  vect_t.size() -1;
00186 
00187         // Variables to accumulate the number of elements registered to be created (so as to remember their indices)
00188         unsigned int acc_nb_points = nb_points;
00189         unsigned int acc_nb_triangles = nb_triangles;
00190 
00191         // Variables to accumulate the elements registered to be created or to be removed
00192         sofa::helper::vector< sofa::helper::vector< unsigned int > > p_ancestors;
00193         sofa::helper::vector< sofa::helper::vector< double > > p_baryCoefs;
00194         sofa::helper::vector< Triangle > triangles_to_create;
00195         sofa::helper::vector< unsigned int > trianglesIndexList;
00196         sofa::helper::vector< unsigned int > triangles_to_remove;
00197 
00198         // Initialization for INTERSECTION method
00199         sofa::helper::vector< unsigned int > triangles_list_init;
00200         sofa::helper::vector< unsigned int > &triangles_list = triangles_list_init;
00201 
00202         sofa::helper::vector< sofa::helper::vector<unsigned int> > indices_list_init;
00203         sofa::helper::vector< sofa::helper::vector<unsigned int> > &indices_list = indices_list_init;
00204 
00205         sofa::helper::vector< double > coords_list_init;
00206         sofa::helper::vector< double >& coords_list=coords_list_init;
00207 
00208         bool is_intersected=false;
00209 
00210         // Pre-treatment if is_first_cut ==false :
00211 
00212         if(!is_first_cut)
00213         {
00214             x_p1 = b_p12_last[0];
00215             x_p2 = b_p12_last[1];
00216             x_i1 = b_i123_last[0];
00217             x_i2 = b_i123_last[1];
00218             x_i3 = b_i123_last[2];
00219 
00220             const typename DataTypes::Coord& b_point_last = m_geometryAlgorithms->getPositionPoint(b_last); //vect_c[b_last];
00221 
00222             a_new[0]= (Real) b_point_last[0]; 
00223             a_new[1]= (Real) b_point_last[1]; 
00224             a_new[2]= (Real) b_point_last[2]; 
00225 
00226             bool is_crossed = false;
00227             double coord_kmin = 0.0;
00228 
00229             const sofa::helper::vector< sofa::helper::vector<unsigned int> > &tvsa=m_container->getTriangleVertexShellArray();
00230             if (tvsa.size()>0) 
00231             { 
00232                 sofa::helper::vector< unsigned int > shell_b =(sofa::helper::vector< unsigned int >) (tvsa[b_last]);
00233                 unsigned int ind_t_test;
00234                 unsigned int i=0;
00235 
00236                 if(shell_b.size()>0){
00237 
00238                     while(i < shell_b.size())
00239                     {
00240                         ind_t_test=shell_b[i];
00241                         triangles_to_remove.push_back(ind_t_test);
00242 
00243                         sofa::helper::vector<unsigned int> c_indices_init; sofa::helper::vector<unsigned int> &c_indices=c_indices_init;
00244                         double c_baryCoef_init; double &c_baryCoef=c_baryCoef_init;
00245                         double c_coord_k_init; double &c_coord_k = c_coord_k_init; 
00246 
00247                         bool is_intersection_found = m_geometryAlgorithms
00248                                                     ->computeSegmentTriangleIntersection(false, 
00249                                                                                         (const Vec<3,double>&) a_new, 
00250                                                                                         (const Vec<3,double>&) b, 
00251                                                                                         ind_t_test, 
00252                                                                                         c_indices, c_baryCoef, c_coord_k);
00253 
00254                         if(is_intersection_found)
00255                         {
00256                             is_intersection_found=is_intersection_found && (c_indices[0] != b_last && c_indices[1] != b_last);
00257                         }
00258 
00259                         if(is_intersection_found && c_coord_k>coord_kmin)
00260                         {
00261                             ind_ta_new=ind_t_test;
00262                             coord_kmin=c_coord_k;
00263                         }
00264 
00265                         is_crossed = is_crossed || is_intersection_found;
00266 
00267                         i++;
00268                     }
00269 
00270                     if(is_crossed)
00271                     {
00272                         if(ind_ta_new==ind_tb_new)
00273                         {
00274                             return false;
00275                         }
00276 
00277                         ind_tb_final=ind_tb_new;
00278                         is_intersected = m_geometryAlgorithms
00279                                         ->computeIntersectedPointsList((const Vec<3,double>&) a_new, b, 
00280                                                                         ind_ta_new, ind_tb_final, 
00281                                                                         triangles_list, indices_list, 
00282                                                                         coords_list, is_on_boundary);
00283                     }
00284                     else
00285                     {
00286                         return false;
00287                     }
00288                 }
00289             }
00290         }
00291         else
00292         {
00293 
00294             // Call the method "computeIntersectedPointsList" to get the list of points (ind_edge,coord) intersected by the segment from point a to point b and the triangular mesh
00295             ind_tb_final=ind_tb_new;
00296             is_intersected = m_geometryAlgorithms
00297                             ->computeIntersectedPointsList(a, b, ind_ta_new, ind_tb_final, 
00298                                                             triangles_list, indices_list, 
00299                                                             coords_list, is_on_boundary);
00300         }
00301 
00302         unsigned int elem_size = triangles_list.size();
00303 
00304         if(elem_size>0) // intersection successfull
00305         {
00307             m_container->getTriangleEdgeShellArray();
00309             m_container->getTriangleVertexShellArray();
00310 
00311             // Initialization for the indices of the previous intersected edge
00312             unsigned int p1_prev = 0;
00313             unsigned int p2_prev = 0;
00314 
00315             // Treatment of particular case for first extremity a
00316 
00317             const Triangle &ta = m_container->getTriangle(ind_ta_new);
00318             unsigned int ta_to_remove;
00319             unsigned int p1_a = indices_list[0][0];
00320             unsigned int p2_a = indices_list[0][1];
00321 
00322             // Plan to remove triangles indexed by ind_ta_new
00323             if(is_first_cut)
00324             {
00325                 triangles_to_remove.push_back(ind_ta_new);
00326             }
00327 
00328             // Initialization for SNAPPING method for point a
00329 
00330             bool is_snap_a0_init=false; bool is_snap_a1_init=false; bool is_snap_a2_init=false;
00331             bool& is_snap_a0=is_snap_a0_init;
00332             bool& is_snap_a1=is_snap_a1_init;
00333             bool& is_snap_a2=is_snap_a2_init;
00334 
00335             sofa::helper::vector< double > a_baryCoefs = m_geometryAlgorithms
00336                                                         ->computeTriangleBarycoefs((const Vec<3,double> &) a_new, ind_ta_new);
00337             snapping_test_triangle(epsilon, a_baryCoefs[0], a_baryCoefs[1], a_baryCoefs[2], 
00338                                 is_snap_a0, is_snap_a1, is_snap_a2);
00339 
00340             double is_snapping_a = is_snap_a0 || is_snap_a1 || is_snap_a2;
00341 
00342             //std::cout << "a_baryCoefs = " << a_baryCoefs[0] << ", " << a_baryCoefs[1] << ", " << a_baryCoefs[2] <<  std::endl;
00343 
00344             sofa::helper::vector< unsigned int > a_first_ancestors;
00345             sofa::helper::vector< double > a_first_baryCoefs;
00346 
00347             if((is_first_cut) && (!is_snapping_a))
00348             {
00350 
00351                 a_first_ancestors.push_back(ta[0]); 
00352                 a_first_ancestors.push_back(ta[1]); 
00353                 a_first_ancestors.push_back(ta[2]);
00354                 p_ancestors.push_back(a_first_ancestors);
00355                 p_baryCoefs.push_back(a_baryCoefs);
00356 
00357                 acc_nb_points=acc_nb_points+1;
00358 
00360 
00361                 unsigned int ind_a =  acc_nb_points; // last point registered to be created
00362 
00363                 a_last=ind_a; // OUPTUT
00364 
00365                 a_p12_last.clear();
00366                 a_p12_last.push_back(acc_nb_points+2); // OUPTUT
00367                 a_p12_last.push_back(acc_nb_points+1); // OUPTUT
00368 
00369                 sofa::helper::vector< Triangle > a_triangles;
00370                 Triangle t_a01 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_a,
00371                                                                             (unsigned int)ta[0],
00372                                                                             (unsigned int) ta[1])); 
00373                 Triangle t_a12 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_a,
00374                                                                             (unsigned int)ta[1],
00375                                                                             (unsigned int) ta[2]));
00376                 Triangle t_a20 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_a,
00377                                                                             (unsigned int)ta[2],
00378                                                                             (unsigned int) ta[0]));
00379                 triangles_to_create.push_back(t_a01); 
00380                 triangles_to_create.push_back(t_a12); 
00381                 triangles_to_create.push_back(t_a20); 
00382 
00383                 trianglesIndexList.push_back(acc_nb_triangles); 
00384                 trianglesIndexList.push_back(acc_nb_triangles+1); 
00385                 trianglesIndexList.push_back(acc_nb_triangles+2);
00386                 acc_nb_triangles=acc_nb_triangles+3;
00387 
00389 
00390                 a_i123_last.clear();
00391                 a_i123_last.push_back(p2_a); // OUPTUT
00392                 a_i123_last.push_back(p1_a); // OUPTUT
00393 
00394                 if(ta[0]!=p1_a && ta[0]!=p2_a)
00395                 {
00396                     ta_to_remove=acc_nb_triangles-1;
00397                     a_i123_last.push_back(ta[0]); // OUPTUT
00398 
00399                 }
00400                 else
00401                 {
00402                     if(ta[1]!=p1_a && ta[1]!=p2_a)
00403                     {
00404                         ta_to_remove=acc_nb_triangles;
00405                         a_i123_last.push_back(ta[1]); // OUPTUT
00406                     }
00407                     else
00408                     { // (ta[2]!=p1_a && ta[2]!=p2_a)
00409                         ta_to_remove=acc_nb_triangles-2;
00410                         a_i123_last.push_back(ta[2]); // OUPTUT
00411                     }
00412                 }
00413 
00414                 triangles_to_remove.push_back(ta_to_remove);
00415 
00416                 Triangle t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
00417                                                                             (unsigned int) ind_a,
00418                                                                             (unsigned int) p1_a));
00419                 Triangle t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
00420                                                                             (unsigned int) p2_a, 
00421                                                                             (unsigned int)ind_a));
00422                 triangles_to_create.push_back(t_pa1);
00423                 triangles_to_create.push_back(t_pa2);
00424 
00425                 trianglesIndexList.push_back(acc_nb_triangles); 
00426                 trianglesIndexList.push_back(acc_nb_triangles+1);
00427                 acc_nb_triangles=acc_nb_triangles+2;
00428 
00429             }
00430             else
00431             { // (is_first_cut == false) or : snapping a to the vertex indexed by ind_a, which is the closest to point a
00432                 x_p1_to = acc_nb_points + 1;
00433                 x_p2_to = acc_nb_points + 2; 
00434 
00435                 x_i1_to = p1_a;
00436                 x_i2_to = p2_a;
00437 
00438                 // localize the closest vertex 
00439 
00440                 unsigned int ind_a;
00441                 unsigned int p0_a;
00442 
00443                 if(ta[0]!=p1_a && ta[0]!=p2_a)
00444                 {
00445                     p0_a=ta[0];
00446                 }
00447                 else
00448                 {
00449                     if(ta[1]!=p1_a && ta[1]!=p2_a)
00450                     {
00451                         p0_a=ta[1];
00452                     }
00453                     else // ta[2]!=p1_a && ta[2]!=p2_a
00454                     {
00455                         p0_a=ta[2];
00456                     }
00457                 }
00458 
00459                 if(is_snap_a0) // is_snap_a1 == false and is_snap_a2 == false
00460                 {
00462                     ind_a=ta[0];
00463                 }
00464                 else
00465                 {
00466                     if(is_snap_a1) // is_snap_a0 == false and is_snap_a2 == false
00467                     {
00469                         ind_a=ta[1];
00470                     }
00471                     else // is_snap_a2 == true and (is_snap_a0 == false and is_snap_a1 == false)
00472                     {
00474                         ind_a=ta[2];
00475                     }
00476                 }
00477 
00479 
00480                 Triangle t_pa1;
00481                 Triangle t_pa2;
00482 
00483                 if(ind_a==p1_a)
00484                 {
00485                     t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
00486                                                                         (unsigned int) p0_a,
00487                                                                         (unsigned int) p1_a));
00488                     t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
00489                                                                         (unsigned int) p2_a, 
00490                                                                         (unsigned int) p0_a));
00491                     triangles_to_create.push_back(t_pa1); triangles_to_create.push_back(t_pa2);
00492                 }
00493                 else
00494                 {
00495                     if(ind_a==p2_a)
00496                     {
00497                         t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
00498                                                                             (unsigned int) p0_a,
00499                                                                             (unsigned int) p1_a));
00500                         t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
00501                                                                             (unsigned int) p2_a, 
00502                                                                             (unsigned int) p0_a));
00503                         triangles_to_create.push_back(t_pa1); triangles_to_create.push_back(t_pa2);
00504                     }
00505                     else
00506                     {
00507                         t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
00508                                                                             (unsigned int) ind_a,
00509                                                                             (unsigned int) p1_a));
00510                         t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
00511                                                                             (unsigned int) p2_a, 
00512                                                                             (unsigned int)ind_a));
00513                         triangles_to_create.push_back(t_pa1); triangles_to_create.push_back(t_pa2);
00514                     }
00515                 }
00516 
00517                 trianglesIndexList.push_back(acc_nb_triangles); trianglesIndexList.push_back(acc_nb_triangles+1);
00518                 acc_nb_triangles+=2;
00519 
00520                 if(!is_first_cut)
00521                 {
00522                     triangles_to_remove.push_back(acc_nb_triangles-1);
00523                     triangles_to_remove.push_back(acc_nb_triangles);
00524                 }
00525             }
00526 
00527             // Traverse the loop of interected edges
00528 
00529             for (unsigned int i=0;i<indices_list.size();i++)
00530             {
00532 
00533                 unsigned int p1 = indices_list[i][0];
00534                 unsigned int p2 = indices_list[i][1];
00535 
00536                 sofa::helper::vector< unsigned int > p_first_ancestors;
00537                 p_first_ancestors.push_back(p1); p_first_ancestors.push_back(p2);
00538                 p_ancestors.push_back(p_first_ancestors); p_ancestors.push_back(p_first_ancestors);
00539 
00540                 sofa::helper::vector< double > p_first_baryCoefs;
00541                 p_first_baryCoefs.push_back(1.0 - coords_list[i]); p_first_baryCoefs.push_back(coords_list[i]);
00542                 p_baryCoefs.push_back(p_first_baryCoefs); p_baryCoefs.push_back(p_first_baryCoefs);
00543 
00544                 acc_nb_points=acc_nb_points+2;
00545 
00546                 sofa::helper::vector<unsigned int> new_points_current;
00547                 new_points_current.push_back(acc_nb_points-1); new_points_current.push_back(acc_nb_points);
00548                 new_points.push_back(new_points_current);
00549                 closest_vertices.push_back(indices_list[i]);
00550 
00551                 if(i>0) // not to treat particular case of first extremitiy
00552                 {
00553                     // SNAPPING TEST
00554 
00555                     double gamma = 0.3;
00556                     bool is_snap_p1;
00557                     bool is_snap_p2;
00558 
00559                     snapping_test_edge(gamma, 1.0 - coords_list[i], coords_list[i], is_snap_p1, is_snap_p2);
00560                     double is_snapping_p = is_snap_p1 || is_snap_p2;
00561 
00562                     unsigned int ind_p;
00563 
00564                     if(is_snapping_p && i<indices_list.size()-1) // not to treat particular case of last extremitiy
00565                     {
00566                         if(is_snap_p1)
00567                         { 
00569                             ind_p=p1;
00570                         }
00571                         else // is_snap_p2 == true
00572                         {
00574                             ind_p=p2;
00575                         }
00576 
00577                         // std::cout << "INFO_print : DO is_snapping_p, i = " << i << " on vertex " << ind_p <<  std::endl;
00578 
00579                         sofa::helper::vector< unsigned int > triangles_list_1_init;
00580                         sofa::helper::vector< unsigned int > &triangles_list_1 = triangles_list_1_init;
00581 
00582                         sofa::helper::vector< unsigned int > triangles_list_2_init;
00583                         sofa::helper::vector< unsigned int > &triangles_list_2 = triangles_list_2_init;
00584 
00585                         // std::cout << "INFO_print : DO Prepare_VertexDuplication " <<  std::endl;
00586                         m_geometryAlgorithms->Prepare_VertexDuplication(ind_p, triangles_list[i], triangles_list[i+1], indices_list[i-1], coords_list[i-1], indices_list[i+1], coords_list[i+1], triangles_list_1, triangles_list_2);
00587                         // std::cout << "INFO_print : DONE Prepare_VertexDuplication " <<  std::endl;
00588 
00589                         // std::cout << "INFO_print : triangles_list_1.size() = " << triangles_list_1.size() <<  std::endl;
00590                         //for (unsigned int k=0;k<triangles_list_1.size();k++){
00591                         // std::cout << "INFO_print : triangles_list_1 number " << k << " = " << triangles_list_1[k] <<  std::endl;
00592                         //}
00593 
00594                         // std::cout << "INFO_print : triangles_list_2.size() = " << triangles_list_2.size() <<  std::endl;
00595                         //for (unsigned int k=0;k<triangles_list_2.size();k++){
00596                         // std::cout << "INFO_print : triangles_list_2 number " << k << " = " << triangles_list_2[k] <<  std::endl;
00597                         //}
00598                     } 
00599 
00601 
00602                     triangles_to_remove.push_back(triangles_list[i]);
00603 
00605 
00606                     unsigned int p1_created=acc_nb_points - 3;
00607                     unsigned int p2_created=acc_nb_points - 2;
00608 
00609                     unsigned int p1_to_create=acc_nb_points - 1;
00610                     unsigned int p2_to_create=acc_nb_points;
00611 
00612                     unsigned int p0_t = m_container->getTriangle(triangles_list[i])[0];
00613                     unsigned int p1_t = m_container->getTriangle(triangles_list[i])[1];
00614                     unsigned int p2_t = m_container->getTriangle(triangles_list[i])[2];
00615 
00616                     Triangle t_p1;
00617                     Triangle t_p2;
00618                     Triangle t_p3;
00619 
00620                     unsigned int ind_quad;
00621                     Vec<3,Real> point_created=(Vec<3,double>) m_geometryAlgorithms->computeBaryEdgePoint(indices_list[i-1], coords_list[i-1]);
00622                     Vec<3,Real> point_to_create=(Vec<3,double>) m_geometryAlgorithms->computeBaryEdgePoint(indices_list[i], coords_list[i]);
00623 
00624                     if(p0_t!=p1_prev && p0_t!=p2_prev)
00625                     {
00626                         ind_quad=p0_t;
00627                     }
00628                     else
00629                     {
00630                         if(p1_t!=p1_prev && p1_t!=p2_prev)
00631                         {
00632                             ind_quad=p1_t;
00633                         }
00634                         else // (p2_t!=p1_prev && p2_t!=p2_prev)
00635                         { 
00636                             ind_quad=p2_t;
00637                         }
00638                     }
00639 
00640                     if(ind_quad==p1) // *** p1_to_create - p1_created - p1_prev - ind_quad
00641                     {
00642 
00643                         t_p1 = Triangle(helper::make_array<unsigned int>(p2_created, p2_to_create, p2_prev));
00644                         if(m_geometryAlgorithms->isQuadDeulaunayOriented(point_to_create, point_created, p1_prev, ind_quad))
00645                         {
00646                             t_p2 = Triangle(helper::make_array<unsigned int>(p1_to_create, p1_created, p1_prev));
00647                             t_p3 = Triangle(helper::make_array<unsigned int>(p1_prev, ind_quad, p1_to_create));
00648                         }
00649                         else
00650                         {
00651                             t_p2 = Triangle(helper::make_array<unsigned int>(p1_created, p1_prev, ind_quad));
00652                             t_p3 = Triangle(helper::make_array<unsigned int>(ind_quad, p1_to_create, p1_created));
00653                         }
00654                     }
00655                     else // ind_quad==p2 // *** p2_created - p2_to_create - ind_quad - p2_prev
00656                     {
00657                         t_p1 = Triangle(helper::make_array<unsigned int>(p1_to_create, p1_created, p1_prev));
00658                         if(m_geometryAlgorithms->isQuadDeulaunayOriented(point_created, point_to_create, ind_quad, p2_prev))
00659                         {
00660                             t_p2 = Triangle(helper::make_array<unsigned int>(p2_created, p2_to_create, ind_quad));
00661                             t_p3 = Triangle(helper::make_array<unsigned int>(ind_quad, p2_prev, p2_created));
00662                         }
00663                         else
00664                         {
00665                             t_p2 = Triangle(helper::make_array<unsigned int>(p2_to_create, ind_quad, p2_prev));
00666                             t_p3 = Triangle(helper::make_array<unsigned int>(p2_prev, p2_created, p2_to_create));
00667                         }
00668                     }
00669 
00670                     triangles_to_create.push_back(t_p1); 
00671                     triangles_to_create.push_back(t_p2); 
00672                     triangles_to_create.push_back(t_p3);
00673 
00674                     trianglesIndexList.push_back(acc_nb_triangles); 
00675                     trianglesIndexList.push_back(acc_nb_triangles+1); 
00676                     trianglesIndexList.push_back(acc_nb_triangles+2);
00677                     acc_nb_triangles=acc_nb_triangles+3;
00678                 }
00679 
00680                 // Update the previous "duplicated points" 
00681                 p1_prev=p1;
00682                 p2_prev=p2;
00683             }
00684 
00685             if(is_intersected || !is_on_boundary)
00686             {
00687                 ind_tb_new=ind_tb_final;
00688 
00689                 b_p12_last.clear();
00690                 b_p12_last.push_back(acc_nb_points-1); // OUPTUT
00691                 b_p12_last.push_back(acc_nb_points); // OUPTUT
00692 
00693                 // Treatment of particular case for second extremity b
00694 
00695                 const Triangle &tb=m_container->getTriangle(ind_tb_new);
00696                 unsigned int tb_to_remove;
00697                 unsigned int p1_b=indices_list[indices_list.size()-1][0];
00698                 unsigned int p2_b=indices_list[indices_list.size()-1][1];
00699 
00700                 b_i123_last.clear();
00701                 b_i123_last.push_back(p1_b); // OUPTUT
00702                 b_i123_last.push_back(p2_b); // OUPTUT
00703 
00704                 // Plan to remove triangles indexed by ind_tb_new
00705                 triangles_to_remove.push_back(ind_tb_new);
00706 
00707                 // Initialization for SNAPPING method for point b
00708 
00709                 bool is_snap_b0_init=false; bool is_snap_b1_init=false; bool is_snap_b2_init=false;
00710                 bool& is_snap_b0=is_snap_b0_init;
00711                 bool& is_snap_b1=is_snap_b1_init;
00712                 bool& is_snap_b2=is_snap_b2_init;
00713 
00714                 sofa::helper::vector< double > b_baryCoefs = m_geometryAlgorithms->computeTriangleBarycoefs((const Vec<3,double> &) b, ind_tb_new);
00715 
00716                 if(!is_intersected && !is_on_boundary)
00717                 {
00718                     b_baryCoefs[0] = (double) (1.0/3.0);
00719                     b_baryCoefs[1] = (double) (1.0/3.0);
00720                     b_baryCoefs[2] = (double) (1.0 - (b_baryCoefs[0] + b_baryCoefs[1]));
00721                 }
00722 
00723                 snapping_test_triangle(epsilon, b_baryCoefs[0], b_baryCoefs[1], b_baryCoefs[2], 
00724                                         is_snap_b0, is_snap_b1, is_snap_b2);
00725 
00726                 double is_snapping_b = is_snap_b0 || is_snap_b1 || is_snap_b2;
00727 
00728                 //std::cout << "b_baryCoefs = " << b_baryCoefs[0] << ", " << b_baryCoefs[1] << ", " << b_baryCoefs[2] <<  std::endl;
00729 
00730                 sofa::helper::vector< unsigned int > b_first_ancestors;
00731                 sofa::helper::vector< double > b_first_baryCoefs;
00732 
00733                 is_snapping_b = false; // COMMENT : point b will not be snapped
00734 
00735                 if(!is_snapping_b)
00736                 {
00738 
00739                     b_first_ancestors.push_back(tb[0]); 
00740                     b_first_ancestors.push_back(tb[1]); 
00741                     b_first_ancestors.push_back(tb[2]);
00742                     p_ancestors.push_back(b_first_ancestors);
00743                     p_baryCoefs.push_back(b_baryCoefs);
00744 
00745                     acc_nb_points=acc_nb_points+1;
00746 
00748 
00749                     unsigned int ind_b =  acc_nb_points; // last point registered to be created
00750 
00751                     b_last=ind_b; // OUPTUT
00752 
00753                     sofa::helper::vector< Triangle > b_triangles;
00754                     Triangle t_b01 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_b,
00755                                                                                 (unsigned int)tb[0],
00756                                                                                 (unsigned int) tb[1]));
00757                     Triangle t_b12 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_b,
00758                                                                                 (unsigned int)tb[1],
00759                                                                                 (unsigned int) tb[2]));
00760                     Triangle t_b20 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_b,
00761                                                                                 (unsigned int)tb[2],
00762                                                                                 (unsigned int) tb[0]));
00763                     triangles_to_create.push_back(t_b01); 
00764                     triangles_to_create.push_back(t_b12); 
00765                     triangles_to_create.push_back(t_b20); 
00766 
00767                     trianglesIndexList.push_back(acc_nb_triangles); 
00768                     trianglesIndexList.push_back(acc_nb_triangles+1); 
00769                     trianglesIndexList.push_back(acc_nb_triangles+2);
00770                     acc_nb_triangles=acc_nb_triangles+3;
00771 
00773 
00774                     if(tb[0]!=p1_b && tb[0]!=p2_b)
00775                     {
00776                         tb_to_remove=acc_nb_triangles-1;
00777                         b_i123_last.push_back(tb[0]); // OUTPUT
00778                     }
00779                     else
00780                     {
00781                         if(tb[1]!=p1_b && tb[1]!=p2_b)
00782                         {
00783                             tb_to_remove=acc_nb_triangles;
00784                             b_i123_last.push_back(tb[1]); // OUTPUT
00785                         }
00786                         else // (tb[2]!=p1_b && tb[2]!=p2_b)
00787                         { 
00788                             tb_to_remove=acc_nb_triangles-2;
00789                             b_i123_last.push_back(tb[2]); // OUTPUT
00790                         }
00791                     }
00792                     triangles_to_remove.push_back(tb_to_remove);
00793 
00794                     Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 2,
00795                                                                                 (unsigned int) p1_b,
00796                                                                                 (unsigned int)ind_b));
00797                     Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,
00798                                                                                 (unsigned int)ind_b,
00799                                                                                 (unsigned int) p2_b));
00800                     triangles_to_create.push_back(t_pb1); 
00801                     triangles_to_create.push_back(t_pb2);
00802 
00803                     trianglesIndexList.push_back(acc_nb_triangles); 
00804                     trianglesIndexList.push_back(acc_nb_triangles+1);
00805                     acc_nb_triangles=acc_nb_triangles+2;
00806                 }
00807                 else // snapping b to the vertex indexed by ind_b, which is the closest to point b
00808                 {
00809                     // localize the closest vertex 
00810                     unsigned int ind_b;
00811                     unsigned int p0_b;
00812 
00813                     if(tb[0]!=p1_b && tb[0]!=p2_b)
00814                     {
00815                         p0_b=tb[0];
00816                         b_i123_last.push_back(tb[0]); // OUTPUT
00817                     }
00818                     else
00819                     {
00820                         if(tb[1]!=p1_b && tb[1]!=p2_b)
00821                         {
00822                             p0_b=tb[1];
00823                             b_i123_last.push_back(tb[1]); // OUTPUT
00824                         }
00825                         else// tb[2]!=p1_b && tb[2]!=p2_b
00826                         {
00827                             p0_b=tb[2];
00828                             b_i123_last.push_back(tb[2]); // OUTPUT
00829                         }
00830                     }
00831 
00832                     if(is_snap_b0) // is_snap_b1 == false and is_snap_b2 == false
00833                     {
00835                         ind_b=tb[0];
00836                     }
00837                     else
00838                     {
00839                         if(is_snap_b1) // is_snap_b0 == false and is_snap_b2 == false
00840                         {
00842                             ind_b=tb[1];
00843                         }
00844                         else // is_snap_b2 == true and (is_snap_b0 == false and is_snap_b1 == false)
00845                         {
00847                             ind_b=tb[2];
00848                         }
00849                     }
00850 
00851                     b_last=ind_b; // OUTPUT
00852 
00854 
00855                     if(ind_b==p1_b)
00856                     {
00857                         Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points,
00858                                                                                     (unsigned int) p1_b,
00859                                                                                     (unsigned int) p0_b));
00860                         Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points,
00861                                                                                     (unsigned int) p0_b, 
00862                                                                                     (unsigned int) p2_b));
00863                         triangles_to_create.push_back(t_pb1); 
00864                         triangles_to_create.push_back(t_pb2);
00865                     }
00866                     else
00867                     {
00868                         if(ind_b==p2_b)
00869                         {
00870                             Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,
00871                                                                                         (unsigned int) p1_b,
00872                                                                                         (unsigned int) p0_b));
00873                             Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,
00874                                                                                         (unsigned int) p0_b, 
00875                                                                                         (unsigned int) p2_b));
00876                             triangles_to_create.push_back(t_pb1); 
00877                             triangles_to_create.push_back(t_pb2);
00878                         }
00879                         else
00880                         {
00881                             Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,
00882                                                                                         (unsigned int) p1_b,
00883                                                                                         (unsigned int) ind_b));
00884                             Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points,
00885                                                                                         (unsigned int) ind_b, 
00886                                                                                         (unsigned int)p2_b));
00887                             triangles_to_create.push_back(t_pb1); 
00888                             triangles_to_create.push_back(t_pb2);
00889                         }
00890                     }
00891 
00892                     trianglesIndexList.push_back(acc_nb_triangles); 
00893                     trianglesIndexList.push_back(acc_nb_triangles+1);
00894                     acc_nb_triangles+=2;
00895                 }
00896             }
00897 
00898             // POINT SEPARATING
00899 
00900             if(!is_first_cut)
00901             {
00902                 sofa::helper::vector< unsigned int > bb_first_ancestors;
00903                 bb_first_ancestors.push_back(x_i1); 
00904                 bb_first_ancestors.push_back(x_i2); 
00905                 bb_first_ancestors.push_back(x_i3);
00906                 sofa::helper::vector< double > bb_baryCoefs = m_geometryAlgorithms->compute3PointsBarycoefs((const Vec<3,double> &) a_new, x_i1, x_i2, x_i3);
00907 
00908                 // Add point B1
00909                 p_ancestors.push_back(bb_first_ancestors);
00910                 p_baryCoefs.push_back(bb_baryCoefs);
00911                 acc_nb_points=acc_nb_points+1;
00912                 unsigned int B1 = acc_nb_points;
00913 
00914                 // Add point B2
00915                 p_ancestors.push_back(bb_first_ancestors);
00916                 p_baryCoefs.push_back(bb_baryCoefs);
00917                 acc_nb_points=acc_nb_points+1;
00918                 unsigned int B2 = acc_nb_points;
00919 
00920                 Triangle T1 = Triangle(helper::make_array<unsigned int>(B1, x_p1, x_i1));
00921                 Triangle T1_to = Triangle(helper::make_array<unsigned int>(B1, x_i1_to, x_p1_to));
00922 
00923                 Triangle T2 = Triangle(helper::make_array<unsigned int>(B2, x_i2, x_p2));
00924                 Triangle T2_to = Triangle(helper::make_array<unsigned int>(B2, x_p2_to, x_i2_to));
00925 
00926                 Triangle Ti1 = Triangle(helper::make_array<unsigned int>(B1, x_i1, x_i1_to));
00927                 Triangle Ti2 = Triangle(helper::make_array<unsigned int>(B2, x_i2_to, x_i2));
00928 
00929                 Triangle Tp1 = Triangle(helper::make_array<unsigned int>(B1, x_p1, x_p1_to));
00930                 Triangle Tp2 = Triangle(helper::make_array<unsigned int>(B2, x_p2_to, x_p2));
00931 
00932                 Triangle T1_13 = Triangle(helper::make_array<unsigned int>(B1, x_i1, x_i3));
00933                 Triangle T1_23 = Triangle(helper::make_array<unsigned int>(B1, x_i3, x_i2));
00934                 Triangle T2_13 = Triangle(helper::make_array<unsigned int>(B2, x_i1, x_i3));
00935                 Triangle T2_23 = Triangle(helper::make_array<unsigned int>(B2, x_i3, x_i2));
00936 
00937                 if(x_i1 == x_i1_to)
00938                 {
00939                     triangles_to_create.push_back(T1);
00940                     triangles_to_create.push_back(T1_to);
00941                     triangles_to_create.push_back(T2);
00942                     triangles_to_create.push_back(T2_to);
00943                     triangles_to_create.push_back(Ti2);
00944 
00945                 }
00946                 else
00947                 { 
00948                     if(x_i2 == x_i2_to)
00949                     {
00950                         triangles_to_create.push_back(T1);
00951                         triangles_to_create.push_back(T1_to);
00952                         triangles_to_create.push_back(T2);
00953                         triangles_to_create.push_back(T2_to);
00954                         triangles_to_create.push_back(Ti1);
00955                     }
00956                     else // (x_i1 == x_i2_to) or (x_i2 == x_i1_to)
00957                     {
00958                         if(x_i1 == x_i2_to)
00959                         {
00960                             triangles_to_create.push_back(Tp1);
00961                             triangles_to_create.push_back(T2_13);
00962                             triangles_to_create.push_back(T2_23);
00963                             triangles_to_create.push_back(T2);
00964                             triangles_to_create.push_back(T2_to);
00965                         }
00966                         else // x_i2 == x_i1_to
00967                         {
00968                             triangles_to_create.push_back(Tp2);
00969                             triangles_to_create.push_back(T1_13);
00970                             triangles_to_create.push_back(T1_23);
00971                             triangles_to_create.push_back(T1);
00972                             triangles_to_create.push_back(T1_to);
00973                         }
00974                     }
00975                 }
00976 
00977                 trianglesIndexList.push_back(acc_nb_triangles); 
00978                 trianglesIndexList.push_back(acc_nb_triangles+1); 
00979                 trianglesIndexList.push_back(acc_nb_triangles+2);
00980                 trianglesIndexList.push_back(acc_nb_triangles+3); 
00981                 trianglesIndexList.push_back(acc_nb_triangles+4);
00982                 acc_nb_triangles = acc_nb_triangles + 5;
00983             }
00984 
00985 
00986             // Create all the points registered to be created
00987             m_modifier->addPointsProcess((const unsigned int) acc_nb_points - nb_points);
00988 
00989             // Warn for the creation of all the points registered to be created
00990             m_modifier->addPointsWarning((const unsigned int) acc_nb_points - nb_points, p_ancestors, p_baryCoefs);
00991 
00992             // Create all the triangles registered to be created
00993             m_modifier->addTrianglesProcess((const sofa::helper::vector< Triangle > &) triangles_to_create) ; // WARNING called after the creation process by the method "addTrianglesProcess"
00994 
00995             //cout<<"INFO, number to create = "<< triangles_to_create.size() <<endl;
00996 
00997             // Warn for the creation of all the triangles registered to be created
00998             m_modifier->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList);
00999 
01000             // Propagate the topological changes *** not necessary
01001             //m_modifier->propagateTopologicalChanges();
01002 
01003             // Remove all the triangles registered to be removed
01004             m_modifier->removeTriangles(triangles_to_remove, true, true); // (WARNING then PROPAGATION) called before the removal process by the method "removeTriangles"
01005 
01006             //cout<<"INFO, number to remove = "<< triangles_to_remove.size() <<endl;
01007 
01008             // Propagate the topological changes *** not necessary
01009             //m_modifier->propagateTopologicalChanges();
01010 
01011         }
01012 
01013         return is_intersected && (elem_size>0);
01014     }
01015 
01016     // Removes triangles along the list of points (ind_edge,coord) intersected by the segment from point a to point b and the triangular mesh
01017 
01018     template<class DataTypes>
01019     void TriangleSetTopologyAlgorithms< DataTypes >::RemoveAlongTrianglesList(const Vec<3,double>& a, 
01020                                                                             const Vec<3,double>& b, 
01021                                                                             const unsigned int ind_ta, 
01022                                                                             const unsigned int ind_tb)
01023     {
01024         sofa::helper::vector< unsigned int > triangles_list_init;
01025         sofa::helper::vector< unsigned int > &triangles_list = triangles_list_init;
01026 
01027         sofa::helper::vector< sofa::helper::vector< unsigned int> > indices_list_init;
01028         sofa::helper::vector< sofa::helper::vector< unsigned int> > &indices_list = indices_list_init;
01029 
01030         sofa::helper::vector< double > coords_list_init;
01031         sofa::helper::vector< double >& coords_list=coords_list_init;
01032 
01033         bool is_intersected=false;
01034 
01035         unsigned int ind_tb_final_init;
01036         unsigned int& ind_tb_final=ind_tb_final_init;
01037 
01038         bool is_on_boundary_init=false;
01039         bool &is_on_boundary=is_on_boundary_init;
01040 
01041         ind_tb_final=ind_tb;
01042         is_intersected = m_geometryAlgorithms->computeIntersectedPointsList(a, b, ind_ta, ind_tb_final, triangles_list, indices_list, coords_list, is_on_boundary);
01043 
01044         if(is_intersected)
01045         {
01046             sofa::helper::vector< unsigned int > triangles;
01047 
01048             for (unsigned int i=0; i<triangles_list.size(); ++i)
01049             {
01050                 triangles.push_back(triangles_list[i]);
01051             }
01052             m_modifier->removeTriangles(triangles, true, true);
01053         }
01054     }
01055 
01056 
01057     // Incises along the list of points (ind_edge,coord) intersected by the sequence of input segments (list of input points) and the triangular mesh
01058 
01059     template<class DataTypes>
01060     void TriangleSetTopologyAlgorithms< DataTypes >::InciseAlongLinesList(const sofa::helper::vector< Vec<3,double> >& input_points, 
01061                                                                         const sofa::helper::vector< unsigned int > &input_triangles)
01062     {
01063         // HYP : input_points.size() == input_triangles.size()
01064 
01065         unsigned int points_size = input_points.size();
01066 
01067         // Initialization for INTERSECTION method
01068         sofa::helper::vector< unsigned int > triangles_list_init;
01069         sofa::helper::vector< unsigned int > &triangles_list = triangles_list_init;
01070 
01071         sofa::helper::vector< sofa::helper::vector<unsigned int> > indices_list_init;
01072         sofa::helper::vector< sofa::helper::vector<unsigned int> > &indices_list = indices_list_init;
01073 
01074         sofa::helper::vector< double > coords_list_init;
01075         sofa::helper::vector< double >& coords_list=coords_list_init;
01076 
01077         unsigned int ind_tb_final_init;
01078         unsigned int &ind_tb_final=ind_tb_final_init;
01079 
01080         bool is_on_boundary_init=false;
01081         bool &is_on_boundary=is_on_boundary_init;
01082 
01083         const Vec<3,double> a = input_points[0];
01084         unsigned int ind_ta = input_triangles[0];
01085 
01086         unsigned int j = 0;
01087         bool is_validated=true;
01088         for(j = 0; is_validated && j < points_size - 1; ++j)
01089         {
01090             const Vec<3,double> pa = input_points[j];
01091             const Vec<3,double> pb = input_points[j+1];
01092             unsigned int ind_tpa = input_triangles[j];
01093             unsigned int ind_tpb = input_triangles[j+1];
01094 
01095             bool is_distinct = (pa!=pb && ind_tpa!=ind_tpb);
01096 
01097             if(is_distinct)
01098             {
01099                 // Call the method "computeIntersectedPointsList" to get the list of points (ind_edge,coord) intersected by the segment from point a to point b and the triangular mesh
01100                 ind_tb_final=ind_tpb;
01101                 bool is_intersected = m_geometryAlgorithms->computeIntersectedPointsList(pa, pb, ind_tpa, ind_tb_final, triangles_list, indices_list, coords_list, is_on_boundary);
01102                 is_validated=is_intersected;
01103             }
01104             else
01105             {
01106                 is_validated=false;
01107             }
01108         }
01109 
01110         const Vec<3,double> b = input_points[j];
01111         unsigned int ind_tb = input_triangles[j];
01112 
01113         const Triangle &ta=m_container->getTriangle(ind_ta);
01114         const Triangle &tb=m_container->getTriangle(ind_tb);
01115 
01116         //const typename DataTypes::VecCoord& vect_c = *topology->getDOF()->getX();
01117         unsigned int nb_points =  m_container->getTriangleVertexShellArray().size() - 1; //vect_c.size() -1;
01118 
01119         const sofa::helper::vector<Triangle> &vect_t=m_container->getTriangleArray();
01120         unsigned int nb_triangles =  vect_t.size() -1;
01121 
01122         // Variables to accumulate the number of elements registered to be created (so as to remember their indices)
01123         unsigned int acc_nb_points=nb_points;
01124         unsigned int acc_nb_triangles=nb_triangles;
01125 
01126         // Variables to accumulate the elements registered to be created or to be removed
01127         sofa::helper::vector< sofa::helper::vector< unsigned int > > p_ancestors;
01128         sofa::helper::vector< sofa::helper::vector< double > > p_baryCoefs;
01129         sofa::helper::vector< Triangle > triangles_to_create;
01130         sofa::helper::vector< unsigned int > trianglesIndexList;
01131         sofa::helper::vector< unsigned int > triangles_to_remove;
01132 
01133         unsigned int ta_to_remove;
01134         unsigned int tb_to_remove;
01135 
01136         // Initialization for SNAPPING method
01137 
01138         bool is_snap_a0_init=false; bool is_snap_a1_init=false; bool is_snap_a2_init=false;
01139         bool& is_snap_a0=is_snap_a0_init;
01140         bool& is_snap_a1=is_snap_a1_init;
01141         bool& is_snap_a2=is_snap_a2_init;
01142 
01143         bool is_snap_b0_init=false; bool is_snap_b1_init=false; bool is_snap_b2_init=false;
01144         bool& is_snap_b0=is_snap_b0_init;
01145         bool& is_snap_b1=is_snap_b1_init;
01146         bool& is_snap_b2=is_snap_b2_init;
01147 
01148         double epsilon = 0.2; // INFO : epsilon is a threshold in [0,1] to control the snapping of the extremities to the closest vertex
01149 
01150         sofa::helper::vector< double > a_baryCoefs = m_geometryAlgorithms->computeTriangleBarycoefs((const Vec<3,double> &) a, ind_ta);
01151         snapping_test_triangle(epsilon, a_baryCoefs[0], a_baryCoefs[1], a_baryCoefs[2], 
01152                                 is_snap_a0, is_snap_a1, is_snap_a2);
01153 
01154         double is_snapping_a = is_snap_a0 || is_snap_a1 || is_snap_a2;
01155 
01156         sofa::helper::vector< double > b_baryCoefs = m_geometryAlgorithms->computeTriangleBarycoefs((const Vec<3,double> &) b, ind_tb);
01157         snapping_test_triangle(epsilon, b_baryCoefs[0], b_baryCoefs[1], b_baryCoefs[2], 
01158                                 is_snap_b0, is_snap_b1, is_snap_b2);
01159 
01160         double is_snapping_b = is_snap_b0 || is_snap_b1 || is_snap_b2;
01161 
01162         /*
01163         if(is_snapping_a){
01164         std::cout << "INFO_print : is_snapping_a" <<  std::endl;
01165         }
01166         if(is_snapping_b){
01167         std::cout << "INFO_print : is_snapping_b" <<  std::endl;
01168         }
01169         */
01170 
01171         if(is_validated) // intersection successfull
01172         {
01174             m_container->getTriangleEdgeShellArray();
01176             m_container->getTriangleVertexShellArray();
01177 
01178             // Initialization for the indices of the previous intersected edge
01179             unsigned int p1_prev=0;
01180             unsigned int p2_prev=0;
01181 
01182             unsigned int p1_a=indices_list[0][0];
01183             unsigned int p2_a=indices_list[0][1];
01184             unsigned int p1_b=indices_list[indices_list.size()-1][0];
01185             unsigned int p2_b=indices_list[indices_list.size()-1][1];
01186 
01187             // Plan to remove triangles indexed by ind_ta and ind_tb
01188             triangles_to_remove.push_back(ind_ta); triangles_to_remove.push_back(ind_tb);
01189 
01190             // Treatment of particular case for first extremity a
01191 
01192             sofa::helper::vector< unsigned int > a_first_ancestors;
01193             sofa::helper::vector< double > a_first_baryCoefs;
01194 
01195             if(!is_snapping_a)
01196             {
01198 
01199                 a_first_ancestors.push_back(ta[0]); 
01200                 a_first_ancestors.push_back(ta[1]); 
01201                 a_first_ancestors.push_back(ta[2]);
01202                 p_ancestors.push_back(a_first_ancestors);
01203                 p_baryCoefs.push_back(a_baryCoefs);
01204 
01205                 acc_nb_points=acc_nb_points+1;
01206 
01208 
01209                 unsigned int ind_a =  acc_nb_points; // last point registered to be created
01210 
01211                 sofa::helper::vector< Triangle > a_triangles;
01212                 Triangle t_a01 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_a,
01213                                                                             (unsigned int)ta[0],
01214                                                                             (unsigned int) ta[1])); 
01215                 Triangle t_a12 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_a,
01216                                                                             (unsigned int)ta[1],
01217                                                                             (unsigned int) ta[2]));
01218                 Triangle t_a20 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_a,
01219                                                                             (unsigned int)ta[2],
01220                                                                             (unsigned int) ta[0]));
01221                 triangles_to_create.push_back(t_a01); 
01222                 triangles_to_create.push_back(t_a12); 
01223                 triangles_to_create.push_back(t_a20); 
01224 
01225                 trianglesIndexList.push_back(acc_nb_triangles); 
01226                 trianglesIndexList.push_back(acc_nb_triangles+1); 
01227                 trianglesIndexList.push_back(acc_nb_triangles+2);
01228                 acc_nb_triangles=acc_nb_triangles+3;
01229 
01231 
01232                 if(ta[0]!=p1_a && ta[0]!=p2_a)
01233                 {
01234                     ta_to_remove=acc_nb_triangles-1;
01235                 }
01236                 else
01237                 {
01238                     if(ta[1]!=p1_a && ta[1]!=p2_a)
01239                     {
01240                         ta_to_remove=acc_nb_triangles;
01241                     }
01242                     else // (ta[2]!=p1_a && ta[2]!=p2_a)
01243                     {
01244                         ta_to_remove=acc_nb_triangles-2;
01245                     }
01246                 }
01247                 triangles_to_remove.push_back(ta_to_remove);
01248 
01249                 Triangle t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
01250                                                                             (unsigned int) ind_a,
01251                                                                             (unsigned int) p1_a));
01252                 Triangle t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
01253                                                                             (unsigned int) p2_a, 
01254                                                                             (unsigned int)ind_a));
01255                 triangles_to_create.push_back(t_pa1);
01256                 triangles_to_create.push_back(t_pa2);
01257 
01258                 trianglesIndexList.push_back(acc_nb_triangles); 
01259                 trianglesIndexList.push_back(acc_nb_triangles+1);
01260                 acc_nb_triangles=acc_nb_triangles+2;
01261             }
01262             else // snapping a to the vertex indexed by ind_a, which is the closest to point a
01263             {
01264                 // localize the closest vertex 
01265                 unsigned int ind_a;
01266                 unsigned int p0_a;
01267 
01268                 if(ta[0]!=p1_a && ta[0]!=p2_a)
01269                 {
01270                     p0_a=ta[0];
01271                 }
01272                 else
01273                 {
01274                     if(ta[1]!=p1_a && ta[1]!=p2_a)
01275                     {
01276                         p0_a=ta[1];
01277                     }
01278                     else// ta[2]!=p1_a && ta[2]!=p2_a
01279                     {
01280                         p0_a=ta[2];
01281                     }
01282                 }
01283 
01284                 if(is_snap_a0) // is_snap_a1 == false and is_snap_a2 == false
01285                 {
01287                     ind_a=ta[0];
01288                 }
01289                 else
01290                 {
01291                     if(is_snap_a1) // is_snap_a0 == false and is_snap_a2 == false
01292                     {
01294                         ind_a=ta[1];
01295                     }
01296                     else // is_snap_a2 == true and (is_snap_a0 == false and is_snap_a1 == false)
01297                     {
01299                         ind_a=ta[2];
01300                     }
01301                 }
01302 
01304 
01305                 if(ind_a==p1_a)
01306                 {
01307                     Triangle t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
01308                                                                                 (unsigned int) p0_a,
01309                                                                                 (unsigned int) p1_a));
01310                     Triangle t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
01311                                                                                 (unsigned int) p2_a, 
01312                                                                                 (unsigned int) p0_a));
01313                     triangles_to_create.push_back(t_pa1); 
01314                     triangles_to_create.push_back(t_pa2);
01315                 }
01316                 else
01317                 {
01318                     if(ind_a==p2_a)
01319                     {
01320                         Triangle t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
01321                                                                                     (unsigned int) p0_a,
01322                                                                                     (unsigned int) p1_a));
01323                         Triangle t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
01324                                                                                     (unsigned int) p2_a, 
01325                                                                                     (unsigned int) p0_a));
01326                         triangles_to_create.push_back(t_pa1); 
01327                         triangles_to_create.push_back(t_pa2);
01328                     }
01329                     else
01330                     {
01331                         Triangle t_pa1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 1,
01332                                                                                     (unsigned int) ind_a,
01333                                                                                     (unsigned int) p1_a));
01334                         Triangle t_pa2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points + 2,
01335                                                                                     (unsigned int) p2_a, 
01336                                                                                     (unsigned int)ind_a));
01337                         triangles_to_create.push_back(t_pa1); 
01338                         triangles_to_create.push_back(t_pa2);
01339                     }
01340                 }
01341 
01342                 trianglesIndexList.push_back(acc_nb_triangles); 
01343                 trianglesIndexList.push_back(acc_nb_triangles+1);
01344                 acc_nb_triangles+=2;
01345             }
01346 
01347             // Traverse the loop of interected edges
01348 
01349             for (unsigned int i=0; i<indices_list.size(); ++i)
01350             {
01352                 unsigned int p1 = indices_list[i][0];
01353                 unsigned int p2 = indices_list[i][1];
01354 
01355                 sofa::helper::vector< unsigned int > p_first_ancestors;
01356                 p_first_ancestors.push_back(p1); 
01357                 p_first_ancestors.push_back(p2);
01358                 p_ancestors.push_back(p_first_ancestors); 
01359                 p_ancestors.push_back(p_first_ancestors);
01360 
01361                 sofa::helper::vector< double > p_first_baryCoefs;
01362                 p_first_baryCoefs.push_back(1.0 - coords_list[i]); 
01363                 p_first_baryCoefs.push_back(coords_list[i]);
01364                 p_baryCoefs.push_back(p_first_baryCoefs); 
01365                 p_baryCoefs.push_back(p_first_baryCoefs);
01366 
01367                 acc_nb_points=acc_nb_points+2;
01368 
01369                 if(i>0) // not to treat particular case of first extremitiy
01370                 {
01371                     // SNAPPING TEST
01372 
01373                     double gamma = 0.3;
01374                     bool is_snap_p1;
01375                     bool is_snap_p2;
01376 
01377                     snapping_test_edge(gamma, 1.0 - coords_list[i], coords_list[i], is_snap_p1, is_snap_p2);
01378                     double is_snapping_p = is_snap_p1 || is_snap_p2;
01379 
01380                     unsigned int ind_p;
01381 
01382                     if(is_snapping_p && i<indices_list.size()-1) // not to treat particular case of last extremitiy
01383                     {
01384                         if(is_snap_p1)
01385                         { 
01387                             ind_p=p1;
01388                         }
01389                         else // is_snap_p2 == true
01390                         {
01392                             ind_p=p2;
01393                         }
01394 
01395                         //std::cout << "INFO_print : is_snapping_p, i = " << i << " on vertex " << ind_p <<  std::endl;
01396 
01397                         sofa::helper::vector< unsigned int > triangles_list_1_init;
01398                         sofa::helper::vector< unsigned int > &triangles_list_1 = triangles_list_1_init;
01399 
01400                         sofa::helper::vector< unsigned int > triangles_list_2_init;
01401                         sofa::helper::vector< unsigned int > &triangles_list_2 = triangles_list_2_init;
01402 
01403                         //std::cout << "INFO_print : DO Prepare_VertexDuplication " <<  std::endl;
01404                         m_geometryAlgorithms->Prepare_VertexDuplication(ind_p, triangles_list[i], triangles_list[i+1], indices_list[i-1], coords_list[i-1], indices_list[i+1], coords_list[i+1], triangles_list_1, triangles_list_2);
01405                         //std::cout << "INFO_print : DONE Prepare_VertexDuplication " <<  std::endl;
01406 
01407                         //std::cout << "INFO_print : triangles_list_1.size() = " << triangles_list_1.size() <<  std::endl;
01408                         //for (unsigned int k=0;k<triangles_list_1.size();k++){
01409                         //      std::cout << "INFO_print : triangles_list_1 number " << k << " = " << triangles_list_1[k] <<  std::endl;
01410                         //}
01411 
01412                         //std::cout << "INFO_print : triangles_list_2.size() = " << triangles_list_2.size() <<  std::endl;
01413                         //for (unsigned int k=0;k<triangles_list_2.size();k++){
01414                         //      std::cout << "INFO_print : triangles_list_2 number " << k << " = " << triangles_list_2[k] <<  std::endl;
01415                         //}
01416                     } 
01417 
01419 
01420                     triangles_to_remove.push_back(triangles_list[i]);
01421 
01423 
01424                     unsigned int p1_created=acc_nb_points - 3;
01425                     unsigned int p2_created=acc_nb_points - 2;
01426 
01427                     unsigned int p1_to_create=acc_nb_points - 1;
01428                     unsigned int p2_to_create=acc_nb_points;
01429 
01430                     unsigned int p0_t = m_container->getTriangle(triangles_list[i])[0];
01431                     unsigned int p1_t = m_container->getTriangle(triangles_list[i])[1];
01432                     unsigned int p2_t = m_container->getTriangle(triangles_list[i])[2];
01433 
01434                     Triangle t_p1 = Triangle(helper::make_array<unsigned int>((unsigned int) p1_created,(unsigned int) p1_prev,(unsigned int) p1_to_create));
01435                     Triangle t_p2 = Triangle(helper::make_array<unsigned int>((unsigned int) p2_created,(unsigned int) p2_to_create,(unsigned int) p2_prev));
01436 
01437                     Triangle t_p3;
01438 
01439                     if(p0_t!=p1_prev && p0_t!=p2_prev)
01440                     {
01441                         if(p0_t==p1)
01442                         {
01443                             t_p3=Triangle(helper::make_array<unsigned int>((unsigned int) p0_t,(unsigned int) p1_to_create,(unsigned int) p1_prev));
01444 
01445                         }
01446                         else // p0_t==p2
01447                         {
01448                             t_p3=Triangle(helper::make_array<unsigned int>((unsigned int) p0_t,(unsigned int) p2_prev,(unsigned int) p2_to_create));
01449                         }
01450                     }
01451                     else
01452                     {
01453                         if(p1_t!=p1_prev && p1_t!=p2_prev)
01454                         {
01455                             if(p1_t==p1)
01456                             {
01457                                 t_p3=Triangle(helper::make_array<unsigned int>((unsigned int) p1_t,(unsigned int) p1_to_create,(unsigned int) p1_prev));
01458                             }
01459                             else // p1_t==p2
01460                             {
01461                                 t_p3=Triangle(helper::make_array<unsigned int>((unsigned int) p1_t,(unsigned int) p2_prev,(unsigned int) p2_to_create));
01462                             }
01463                         }
01464                         else // (p2_t!=p1_prev && p2_t!=p2_prev)
01465                         {
01466                             if(p2_t==p1)
01467                             {
01468                                 t_p3=Triangle(helper::make_array<unsigned int>((unsigned int) p2_t,(unsigned int) p1_to_create,(unsigned int) p1_prev));
01469                             }
01470                             else // p2_t==p2
01471                             {
01472                                 t_p3=Triangle(helper::make_array<unsigned int>((unsigned int) p2_t,(unsigned int) p2_prev,(unsigned int) p2_to_create));
01473                             }
01474                         }
01475                     }
01476 
01477                     triangles_to_create.push_back(t_p1); 
01478                     triangles_to_create.push_back(t_p2); 
01479                     triangles_to_create.push_back(t_p3);
01480 
01481                     trianglesIndexList.push_back(acc_nb_triangles); 
01482                     trianglesIndexList.push_back(acc_nb_triangles+1); 
01483                     trianglesIndexList.push_back(acc_nb_triangles+2);
01484                     acc_nb_triangles=acc_nb_triangles+3;
01485                 }
01486 
01487                 // Update the previous "duplicated points" 
01488                 p1_prev=p1;
01489                 p2_prev=p2;
01490             }
01491 
01492             // Treatment of particular case for second extremity b
01493             sofa::helper::vector< unsigned int > b_first_ancestors;
01494             sofa::helper::vector< double > b_first_baryCoefs;
01495 
01496             if(!is_snapping_b)
01497             {
01499 
01500                 b_first_ancestors.push_back(tb[0]); 
01501                 b_first_ancestors.push_back(tb[1]); 
01502                 b_first_ancestors.push_back(tb[2]);
01503                 p_ancestors.push_back(b_first_ancestors);
01504                 p_baryCoefs.push_back(b_baryCoefs);
01505 
01506                 acc_nb_points=acc_nb_points+1;
01507 
01509 
01510                 unsigned int ind_b =  acc_nb_points; // last point registered to be created
01511 
01512                 sofa::helper::vector< Triangle > b_triangles;
01513                 Triangle t_b01 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_b,
01514                                                                             (unsigned int)tb[0],
01515                                                                             (unsigned int) tb[1])); 
01516                 Triangle t_b12 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_b,
01517                                                                             (unsigned int)tb[1],
01518                                                                             (unsigned int) tb[2]));
01519                 Triangle t_b20 = Triangle(helper::make_array<unsigned int>((unsigned int)ind_b,
01520                                                                             (unsigned int)tb[2],
01521                                                                             (unsigned int) tb[0]));
01522                 triangles_to_create.push_back(t_b01); 
01523                 triangles_to_create.push_back(t_b12); 
01524                 triangles_to_create.push_back(t_b20); 
01525 
01526                 trianglesIndexList.push_back(acc_nb_triangles); 
01527                 trianglesIndexList.push_back(acc_nb_triangles+1); 
01528                 trianglesIndexList.push_back(acc_nb_triangles+2);
01529                 acc_nb_triangles=acc_nb_triangles+3;
01530 
01532 
01533                 if(tb[0]!=p1_b && tb[0]!=p2_b)
01534                 {
01535                     tb_to_remove=acc_nb_triangles-1;
01536                 }
01537                 else
01538                 {
01539                     if(tb[1]!=p1_b && tb[1]!=p2_b)
01540                     {
01541                         tb_to_remove=acc_nb_triangles;
01542                     }
01543                     else // (tb[2]!=p1_b && tb[2]!=p2_b)
01544                     {
01545                         tb_to_remove=acc_nb_triangles-2;
01546                     }
01547                 }
01548                 triangles_to_remove.push_back(tb_to_remove);
01549 
01550                 Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 2,
01551                                                                             (unsigned int) p1_b,
01552                                                                             (unsigned int)ind_b));
01553                 Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,
01554                                                                             (unsigned int)ind_b,
01555                                                                             (unsigned int) p2_b));
01556                 triangles_to_create.push_back(t_pb1); 
01557                 triangles_to_create.push_back(t_pb2);
01558 
01559                 trianglesIndexList.push_back(acc_nb_triangles); 
01560                 trianglesIndexList.push_back(acc_nb_triangles+1);
01561                 acc_nb_triangles=acc_nb_triangles+2;
01562 
01563             }
01564             else // snapping b to the vertex indexed by ind_b, which is the closest to point b
01565             {
01566                 // localize the closest vertex 
01567                 unsigned int ind_b;
01568                 unsigned int p0_b;
01569 
01570                 if(tb[0]!=p1_b && tb[0]!=p2_b)
01571                 {
01572                     p0_b=tb[0];
01573                 }
01574                 else
01575                 {
01576                     if(tb[1]!=p1_b && tb[1]!=p2_b)
01577                     {
01578                         p0_b=tb[1];
01579                     }
01580                     else// tb[2]!=p1_b && tb[2]!=p2_b
01581                     {
01582                         p0_b=tb[2];
01583                     }
01584                 }
01585 
01586                 if(is_snap_b0) // is_snap_b1 == false and is_snap_b2 == false
01587                 {
01589                     ind_b=tb[0];
01590                 }
01591                 else
01592                 {
01593                     if(is_snap_b1) // is_snap_b0 == false and is_snap_b2 == false
01594                     {
01596                         ind_b=tb[1];
01597                     }
01598                     else // is_snap_b2 == true and (is_snap_b0 == false and is_snap_b1 == false)
01599                     {
01601                         ind_b=tb[2];
01602                     }
01603                 }
01604 
01606 
01607                 if(ind_b==p1_b)
01608                 {
01609                     Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points,(unsigned int) p1_b,(unsigned int) p0_b));
01610                     Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points,(unsigned int) p0_b, (unsigned int) p2_b));
01611                     triangles_to_create.push_back(t_pb1); 
01612                     triangles_to_create.push_back(t_pb2);
01613 
01614                 }
01615                 else
01616                 {
01617                     if(ind_b==p2_b)
01618                     {
01619                         Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,(unsigned int) p1_b,(unsigned int) p0_b));
01620                         Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,(unsigned int) p0_b, (unsigned int) p2_b));
01621                         triangles_to_create.push_back(t_pb1); 
01622                         triangles_to_create.push_back(t_pb2);
01623                     }
01624                     else
01625                     {
01626                         Triangle t_pb1 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points - 1,(unsigned int) p1_b,(unsigned int) ind_b));
01627                         Triangle t_pb2 = Triangle(helper::make_array<unsigned int>((unsigned int) acc_nb_points,(unsigned int) ind_b, (unsigned int)p2_b));
01628                         triangles_to_create.push_back(t_pb1);
01629                         triangles_to_create.push_back(t_pb2);
01630                     }
01631                 }
01632 
01633                 trianglesIndexList.push_back(acc_nb_triangles);
01634                 trianglesIndexList.push_back(acc_nb_triangles+1);
01635                 acc_nb_triangles+=2;
01636             }
01637 
01638             // Create all the points registered to be created
01639             m_modifier->addPointsProcess((const unsigned int) acc_nb_points - nb_points);
01640 
01641             // Warn for the creation of all the points registered to be created
01642             m_modifier->addPointsWarning((const unsigned int) acc_nb_points - nb_points, p_ancestors, p_baryCoefs);
01643 
01644             // Create all the triangles registered to be created
01645             m_modifier->addTrianglesProcess((const sofa::helper::vector< Triangle > &) triangles_to_create) ; // WARNING called after the creation process by the method "addTrianglesProcess"
01646 
01647             // Warn for the creation of all the triangles registered to be created
01648             m_modifier->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList);
01649 
01650             // Propagate the topological changes *** not necessary
01651             //m_modifier->propagateTopologicalChanges();
01652 
01653             // Remove all the triangles registered to be removed
01654             m_modifier->removeTriangles(triangles_to_remove, true, true); // (WARNING then PROPAGATION) called before the removal process by the method "removeTriangles"
01655 
01656             // Propagate the topological changes *** not necessary
01657             //m_modifier->propagateTopologicalChanges();
01658         }
01659     }
01660 
01661     // Duplicate the given edge. Only works of at least one of its points is adjacent to a border.
01662     template<class DataTypes>
01663     int TriangleSetTopologyAlgorithms<DataTypes>::InciseAlongEdge(unsigned int ind_edge)
01664     {
01665         const Edge & edge0=m_container->getEdge(ind_edge);
01666         unsigned ind_pa = edge0[0];
01667         unsigned ind_pb = edge0[1];
01668 
01669         const helper::vector<unsigned>& triangles0 = m_container->getTriangleEdgeShell(ind_edge);
01670         if (triangles0.size() != 2)
01671         {
01672             std::cerr << "InciseAlongEdge: ERROR edge "<<ind_edge<<" is not attached to 2 triangles." << std::endl;
01673             return -1;
01674         }
01675 
01676         // choose one triangle
01677         unsigned ind_tri0 = triangles0[0];
01678 
01679         unsigned ind_tria = ind_tri0;
01680         unsigned ind_trib = ind_tri0;
01681         unsigned ind_edgea = ind_edge;
01682         unsigned ind_edgeb = ind_edge;
01683 
01684         helper::vector<unsigned> list_tria;
01685         helper::vector<unsigned> list_trib;
01686 
01687         for (;;)
01688         {
01689             const TriangleEdges& te = m_container->getTriangleEdge(ind_tria);
01690 
01691             // find the edge adjacent to a that is not ind_edgea
01692             int j=0;
01693             for (j=0; j<3; ++j)
01694             {
01695                 if (te[j] != ind_edgea && (m_container->getEdge(te[j])[0] == ind_pa || m_container->getEdge(te[j])[1] == ind_pa))
01696                     break;
01697             }
01698             if (j == 3)
01699             {
01700                 std::cerr << "InciseAlongEdge: ERROR in triangle "<<ind_tria<<std::endl;
01701                 return -1;
01702             }
01703 
01704             ind_edgea = te[j];
01705             if (ind_edgea == ind_edge) 
01706                 break; // full loop
01707 
01708             const helper::vector<unsigned>& tes = m_container->getTriangleEdgeShell(ind_edgea);
01709             if(tes.size() < 2) 
01710                 break; // border edge
01711 
01712             if (tes[0] == ind_tria)
01713                 ind_tria = tes[1];
01714             else
01715                 ind_tria = tes[0];
01716             list_tria.push_back(ind_tria);
01717         }
01718 
01719         for (;;)
01720         {
01721             const TriangleEdges& te = m_container->getTriangleEdge(ind_trib);
01722 
01723             // find the edge adjacent to b that is not ind_edgeb
01724             int j=0;
01725             for (j=0; j<3; ++j)
01726             {
01727                 if (te[j] != ind_edgeb && (m_container->getEdge(te[j])[0] == ind_pb || m_container->getEdge(te[j])[1] == ind_pb))
01728                     break;
01729             }
01730             if (j == 3)
01731             {
01732                 std::cerr << "InciseAlongEdge: ERROR in triangle "<<ind_trib<<std::endl;
01733                 return -1;
01734             }
01735 
01736             ind_edgeb = te[j];
01737             if (ind_edgeb == ind_edge) 
01738                 break; // full loop
01739 
01740             const helper::vector<unsigned>& tes = m_container->getTriangleEdgeShell(ind_edgeb);
01741             if(tes.size() < 2) 
01742                 break; // border edge
01743 
01744             if (tes[0] == ind_trib)
01745                 ind_trib = tes[1];
01746             else
01747                 ind_trib = tes[0];
01748             list_trib.push_back(ind_trib);
01749         }
01750 
01751         bool pa_is_on_border = (ind_edgea != ind_edge);
01752         bool pb_is_on_border = (ind_edgeb != ind_edge);
01753 
01754         if (!pa_is_on_border && !pb_is_on_border)
01755         {
01756             std::cerr << "InciseAlongEdge: ERROR edge "<<ind_edge<<" is not on border." << std::endl;
01757             return -1;
01758         }
01759 
01760         // now we can split the edge
01761 
01763         m_container->getTriangleEdgeShellArray();
01765         m_container->getTriangleVertexShellArray();
01766 
01767         //const typename DataTypes::VecCoord& vect_c = *topology->getDOF()->getX();
01768         unsigned int nb_points =  m_container->getTriangleVertexShellArray().size() - 1; //vect_c.size();
01769         const sofa::helper::vector<Triangle> &vect_t=m_container->getTriangleArray();
01770         unsigned int nb_triangles =  vect_t.size() -1;
01771 
01772         // Variables to accumulate the number of elements registered to be created (so as to remember their indices)
01773         unsigned int acc_nb_points=nb_points;
01774         unsigned int acc_nb_triangles=nb_triangles;
01775 
01776         // Variables to accumulate the elements registered to be created or to be removed
01777         sofa::helper::vector< sofa::helper::vector< unsigned int > > p_ancestors;
01778         sofa::helper::vector< sofa::helper::vector< double > > p_baryCoefs;
01779         sofa::helper::vector< Triangle > triangles_to_create;
01780         sofa::helper::vector< unsigned int > trianglesIndexList;
01781         sofa::helper::vector< unsigned int > triangles_to_remove;
01782 
01783         sofa::helper::vector<double> defaultCoefs; defaultCoefs.push_back(1.0);
01784 
01785         unsigned new_pa, new_pb;
01786 
01787         if (pa_is_on_border)
01788         {
01789             sofa::helper::vector<unsigned int> ancestors;
01790             new_pa = acc_nb_points++;
01791             ancestors.push_back(ind_pa);
01792             p_ancestors.push_back(ancestors);
01793             p_baryCoefs.push_back(defaultCoefs);
01794         }
01795         else
01796             new_pa = ind_pa;
01797 
01798         sofa::helper::vector<unsigned int> ancestors(1);
01799 
01800         if (pb_is_on_border)
01801         {
01802             new_pb = acc_nb_points++;
01803             ancestors[0] = ind_pb;
01804             p_ancestors.push_back(ancestors);
01805             p_baryCoefs.push_back(defaultCoefs);
01806         }
01807         else
01808             new_pb = ind_pb;
01809 
01810         // we need to recreate at least tri0
01811         Triangle new_tri0 = m_container->getTriangle(ind_tri0);
01812         for (unsigned i=0; i<3; i++)
01813         {
01814             if (new_tri0[i] == ind_pa) 
01815                 new_tri0[i] = new_pa;
01816             else if (new_tri0[i] == ind_pb) 
01817                 new_tri0[i] = new_pb;
01818         }
01819 
01820         triangles_to_remove.push_back(ind_tri0);
01821         ancestors[0] = ind_tri0;
01822         triangles_to_create.push_back(new_tri0);
01823 
01824         trianglesIndexList.push_back(acc_nb_triangles);
01825         acc_nb_triangles += 1;
01826 
01827         // recreate list_tria iff pa is new
01828         if (new_pa != ind_pa)
01829         {
01830             for (unsigned j=0;j<list_tria.size();j++)
01831             {
01832                 unsigned ind_tri = list_tria[j];
01833                 Triangle new_tri = m_container->getTriangle(ind_tri);
01834                 for (unsigned i=0;i<3;i++)
01835                     if (new_tri[i] == ind_pa) new_tri[i] = new_pa;
01836                 triangles_to_remove.push_back(ind_tri);
01837                 ancestors[0] = ind_tri;
01838                 triangles_to_create.push_back(new_tri);
01839 
01840                 trianglesIndexList.push_back(acc_nb_triangles);
01841                 acc_nb_triangles+=1;
01842             }
01843         }
01844 
01845         // recreate list_trib iff pb is new
01846         if (new_pb != ind_pb)
01847         {
01848             for (unsigned j=0;j<list_trib.size();j++)
01849             {
01850                 unsigned ind_tri = list_trib[j];
01851                 Triangle new_tri = m_container->getTriangle(ind_tri);
01852                 for (unsigned i=0;i<3;i++)
01853                     if (new_tri[i] == ind_pb) new_tri[i] = new_pb;
01854                 triangles_to_remove.push_back(ind_tri);
01855                 ancestors[0] = ind_tri;
01856                 triangles_to_create.push_back(new_tri);
01857 
01858                 trianglesIndexList.push_back(acc_nb_triangles);
01859                 acc_nb_triangles+=1;
01860             }
01861         }
01862 
01863         // Create all the points registered to be created
01864         m_modifier->addPointsProcess((const unsigned int) acc_nb_points - nb_points);
01865 
01866         // Warn for the creation of all the points registered to be created
01867         m_modifier->addPointsWarning((const unsigned int) acc_nb_points - nb_points, p_ancestors, p_baryCoefs);
01868 
01869         // Create all the triangles registered to be created
01870         m_modifier->addTrianglesProcess((const sofa::helper::vector< Triangle > &) triangles_to_create) ; // WARNING called after the creation process by the method "addTrianglesProcess"
01871 
01872         // Warn for the creation of all the triangles registered to be created
01873         m_modifier->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList);
01874 
01875         // Propagate the topological changes *** not necessary
01876         //m_modifier->propagateTopologicalChanges();
01877 
01878         // Remove all the triangles registered to be removed
01879         m_modifier->removeTriangles(triangles_to_remove, true, true); // (WARNING then PROPAGATION) called before the removal process by the method "removeTriangles"
01880 
01881         // Propagate the topological changes *** not necessary
01882         //m_modifier->propagateTopologicalChanges();
01883 
01884         return (pb_is_on_border?1:0)+(pa_is_on_border?1:0); // todo: get new edge indice
01885     }
01886 
01887 } // namespace topology
01888 
01889 } // namespace component
01890 
01891 } // namespace sofa
01892 
01893 #endif // SOFA_COMPONENTS_TriangleSetTOPOLOGY_INL

Generated on Sun Nov 23 03:47:40 2008 for Sofa by  doxygen 1.5.7.1