00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
00062 m_geometryAlgorithms->closestIndexPair(ind_ta, ind_tb, ind1, ind2);
00063
00064
00065
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
00087
00088
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;
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
00141 }
00142 else
00143 {
00144
00145 if(ind_ta_new == ind_ta_test)
00146 {
00147
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
00161 }
00162 else
00163 {
00164
00165 if(ind_tb_new==ind_tb_test)
00166 {
00167
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
00182 unsigned int nb_points = m_container->getTriangleVertexShellArray().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
00188 unsigned int acc_nb_points = nb_points;
00189 unsigned int acc_nb_triangles = nb_triangles;
00190
00191
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
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
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);
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
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)
00305 {
00307 m_container->getTriangleEdgeShellArray();
00309 m_container->getTriangleVertexShellArray();
00310
00311
00312 unsigned int p1_prev = 0;
00313 unsigned int p2_prev = 0;
00314
00315
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
00323 if(is_first_cut)
00324 {
00325 triangles_to_remove.push_back(ind_ta_new);
00326 }
00327
00328
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
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;
00362
00363 a_last=ind_a;
00364
00365 a_p12_last.clear();
00366 a_p12_last.push_back(acc_nb_points+2);
00367 a_p12_last.push_back(acc_nb_points+1);
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);
00392 a_i123_last.push_back(p1_a);
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]);
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]);
00406 }
00407 else
00408 {
00409 ta_to_remove=acc_nb_triangles-2;
00410 a_i123_last.push_back(ta[2]);
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 {
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
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
00454 {
00455 p0_a=ta[2];
00456 }
00457 }
00458
00459 if(is_snap_a0)
00460 {
00462 ind_a=ta[0];
00463 }
00464 else
00465 {
00466 if(is_snap_a1)
00467 {
00469 ind_a=ta[1];
00470 }
00471 else
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
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)
00552 {
00553
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)
00565 {
00566 if(is_snap_p1)
00567 {
00569 ind_p=p1;
00570 }
00571 else
00572 {
00574 ind_p=p2;
00575 }
00576
00577
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
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
00588
00589
00590
00591
00592
00593
00594
00595
00596
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
00635 {
00636 ind_quad=p2_t;
00637 }
00638 }
00639
00640 if(ind_quad==p1)
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
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
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);
00691 b_p12_last.push_back(acc_nb_points);
00692
00693
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);
00702 b_i123_last.push_back(p2_b);
00703
00704
00705 triangles_to_remove.push_back(ind_tb_new);
00706
00707
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
00729
00730 sofa::helper::vector< unsigned int > b_first_ancestors;
00731 sofa::helper::vector< double > b_first_baryCoefs;
00732
00733 is_snapping_b = false;
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;
00750
00751 b_last=ind_b;
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]);
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]);
00785 }
00786 else
00787 {
00788 tb_to_remove=acc_nb_triangles-2;
00789 b_i123_last.push_back(tb[2]);
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
00808 {
00809
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]);
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]);
00824 }
00825 else
00826 {
00827 p0_b=tb[2];
00828 b_i123_last.push_back(tb[2]);
00829 }
00830 }
00831
00832 if(is_snap_b0)
00833 {
00835 ind_b=tb[0];
00836 }
00837 else
00838 {
00839 if(is_snap_b1)
00840 {
00842 ind_b=tb[1];
00843 }
00844 else
00845 {
00847 ind_b=tb[2];
00848 }
00849 }
00850
00851 b_last=ind_b;
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
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
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
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
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
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
00987 m_modifier->addPointsProcess((const unsigned int) acc_nb_points - nb_points);
00988
00989
00990 m_modifier->addPointsWarning((const unsigned int) acc_nb_points - nb_points, p_ancestors, p_baryCoefs);
00991
00992
00993 m_modifier->addTrianglesProcess((const sofa::helper::vector< Triangle > &) triangles_to_create) ;
00994
00995
00996
00997
00998 m_modifier->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList);
00999
01000
01001
01002
01003
01004 m_modifier->removeTriangles(triangles_to_remove, true, true);
01005
01006
01007
01008
01009
01010
01011 }
01012
01013 return is_intersected && (elem_size>0);
01014 }
01015
01016
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
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
01064
01065 unsigned int points_size = input_points.size();
01066
01067
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
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
01117 unsigned int nb_points = m_container->getTriangleVertexShellArray().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
01123 unsigned int acc_nb_points=nb_points;
01124 unsigned int acc_nb_triangles=nb_triangles;
01125
01126
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
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;
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
01164
01165
01166
01167
01168
01169
01170
01171 if(is_validated)
01172 {
01174 m_container->getTriangleEdgeShellArray();
01176 m_container->getTriangleVertexShellArray();
01177
01178
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
01188 triangles_to_remove.push_back(ind_ta); triangles_to_remove.push_back(ind_tb);
01189
01190
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;
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
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
01263 {
01264
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
01279 {
01280 p0_a=ta[2];
01281 }
01282 }
01283
01284 if(is_snap_a0)
01285 {
01287 ind_a=ta[0];
01288 }
01289 else
01290 {
01291 if(is_snap_a1)
01292 {
01294 ind_a=ta[1];
01295 }
01296 else
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
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)
01370 {
01371
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)
01383 {
01384 if(is_snap_p1)
01385 {
01387 ind_p=p1;
01388 }
01389 else
01390 {
01392 ind_p=p2;
01393 }
01394
01395
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
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
01406
01407
01408
01409
01410
01411
01412
01413
01414
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
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
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
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
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
01488 p1_prev=p1;
01489 p2_prev=p2;
01490 }
01491
01492
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;
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
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
01565 {
01566
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
01581 {
01582 p0_b=tb[2];
01583 }
01584 }
01585
01586 if(is_snap_b0)
01587 {
01589 ind_b=tb[0];
01590 }
01591 else
01592 {
01593 if(is_snap_b1)
01594 {
01596 ind_b=tb[1];
01597 }
01598 else
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
01639 m_modifier->addPointsProcess((const unsigned int) acc_nb_points - nb_points);
01640
01641
01642 m_modifier->addPointsWarning((const unsigned int) acc_nb_points - nb_points, p_ancestors, p_baryCoefs);
01643
01644
01645 m_modifier->addTrianglesProcess((const sofa::helper::vector< Triangle > &) triangles_to_create) ;
01646
01647
01648 m_modifier->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList);
01649
01650
01651
01652
01653
01654 m_modifier->removeTriangles(triangles_to_remove, true, true);
01655
01656
01657
01658 }
01659 }
01660
01661
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
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
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;
01707
01708 const helper::vector<unsigned>& tes = m_container->getTriangleEdgeShell(ind_edgea);
01709 if(tes.size() < 2)
01710 break;
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
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;
01739
01740 const helper::vector<unsigned>& tes = m_container->getTriangleEdgeShell(ind_edgeb);
01741 if(tes.size() < 2)
01742 break;
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
01761
01763 m_container->getTriangleEdgeShellArray();
01765 m_container->getTriangleVertexShellArray();
01766
01767
01768 unsigned int nb_points = m_container->getTriangleVertexShellArray().size() - 1;
01769 const sofa::helper::vector<Triangle> &vect_t=m_container->getTriangleArray();
01770 unsigned int nb_triangles = vect_t.size() -1;
01771
01772
01773 unsigned int acc_nb_points=nb_points;
01774 unsigned int acc_nb_triangles=nb_triangles;
01775
01776
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
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
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
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
01864 m_modifier->addPointsProcess((const unsigned int) acc_nb_points - nb_points);
01865
01866
01867 m_modifier->addPointsWarning((const unsigned int) acc_nb_points - nb_points, p_ancestors, p_baryCoefs);
01868
01869
01870 m_modifier->addTrianglesProcess((const sofa::helper::vector< Triangle > &) triangles_to_create) ;
01871
01872
01873 m_modifier->addTrianglesWarning(triangles_to_create.size(), triangles_to_create, trianglesIndexList);
01874
01875
01876
01877
01878
01879 m_modifier->removeTriangles(triangles_to_remove, true, true);
01880
01881
01882
01883
01884 return (pb_is_on_border?1:0)+(pa_is_on_border?1:0);
01885 }
01886
01887 }
01888
01889 }
01890
01891 }
01892
01893 #endif // SOFA_COMPONENTS_TriangleSetTOPOLOGY_INL