29   const float slicer_action::EPS = float(1e-13);
 
   33   slicer_none& slicer_none::static_instance() {
 
   38   slicer_boundary::slicer_boundary(
const mesh& m, slicer_action &sA, 
 
   39                                    const mesh_region& cvflst) : A(&sA) {
 
   43   slicer_boundary::slicer_boundary(
const mesh& m, slicer_action &sA) : A(&sA) {
 
   46     build_from(m,cvflist);
 
   49   void slicer_boundary::build_from(
const mesh& m, 
const mesh_region& cvflst) {
 
   50     if (m.convex_index().card()==0) 
return;
 
   51     convex_faces.resize(m.convex_index().last()+1, slice_node::faces_ct(0L));
 
   52     for (mr_visitor i(cvflst); !i.finished(); ++i) 
 
   53       if (i.is_face()) convex_faces[i.cv()][i.f()]=1;
 
   54       else convex_faces[i.cv()].set();
 
   57     for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
 
   58       for (
short_type f=m.structure_of_convex(cv)->nb_faces(); f < convex_faces[cv].size(); ++f)
 
   59         convex_faces[cv][f]=1;
 
   63   bool slicer_boundary::test_bound(
const slice_simplex& s, slice_node::faces_ct& fmask, 
const mesh_slicer::cs_nodes_ct& nodes)
 const {
 
   64     slice_node::faces_ct f; f.set();
 
   66       f &= nodes[s.inodes[i]].faces;
 
   72   void slicer_boundary::exec(mesh_slicer& ms) {
 
   74     if (ms.splx_in.card() == 0) 
return;
 
   75     slice_node::faces_ct fmask(ms.cv < convex_faces.size() ? convex_faces[ms.cv] : 0);
 
   77     if (!convex_faces[ms.cv].any()) { ms.splx_in.clear(); 
return; }
 
   79     for (dal::bv_visitor_c cnt(ms.splx_in); !cnt.finished(); ++cnt) {
 
   80       const slice_simplex& s = ms.simplexes[cnt];
 
   81       if (s.dim() < ms.nodes[0].pt.size()) {
 
   82         if (!test_bound(s, fmask, ms.nodes)) ms.splx_in.sup(cnt);
 
   83       } 
else if (s.dim() == 2) {
 
   88           static unsigned ord[][2] = {{0,1},{1,2},{2,0}}; 
 
   89           for (
size_type k=0; k < 2; ++k) { s2.inodes[k] = ms.simplexes[cnt].inodes[ord[j][k]]; }
 
   90           if (test_bound(s2, fmask, ms.nodes)) {
 
   91             ms.add_simplex(s2, 
true);
 
   94       } 
else if (s.dim() == 3) {
 
  100           static unsigned ord[][3] = {{0,2,1},{1,2,3},{1,3,0},{0,3,2}}; 
 
  101           for (
size_type k=0; k < 3; ++k) { s2.inodes[k] = ms.simplexes[cnt].inodes[ord[j][k]]; } 
 
  104           if (test_bound(s2, fmask, ms.nodes)) {
 
  105             ms.add_simplex(s2, 
true);
 
  110     ms.update_nodes_index();
 
  114   void slicer_apply_deformation::exec(mesh_slicer& ms) {
 
  117     bool ref_pts_changed = 
false;
 
  118     if (ms.cvr != ms.prev_cvr
 
  119         || defdata->pmf->fem_of_element(ms.cv) != pf) {
 
  120       pf = defdata->pmf->fem_of_element(ms.cv);
 
  122         bgeot::vectors_to_base_matrix
 
  123           (G, defdata->pmf->linked_mesh().points_of_convex(ms.cv));
 
  127     std::vector<base_node> ref_pts2; ref_pts2.reserve(ms.nodes_index.card());
 
  128     for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i) {
 
  129       ref_pts2.push_back(ms.nodes[i].pt_ref);
 
  130       if (ref_pts2.size() > ref_pts.size()
 
  131           || gmm::vect_dist2_sqr(ref_pts2[i],ref_pts[i])>1e-20) 
 
  132         ref_pts_changed = 
true;
 
  134     if (ref_pts2.size() != ref_pts.size()) ref_pts_changed = 
true;
 
  135     if (ref_pts_changed) {
 
  136       ref_pts.swap(ref_pts2);
 
  139     bgeot::pstored_point_tab pspt = store_point_tab(ref_pts);
 
  140     pfem_precomp pfp = fprecomp(pf, pspt);
 
  141     defdata->copy(ms.cv, coeff);
 
  143     base_vector val(ms.m.dim());
 
  145     fem_interpolation_context ctx(ms.pgt, pfp, 0, G, ms.cv, 
short_type(-1));
 
  146     for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i, ++cnt) {
 
  147       ms.nodes[i].pt.resize(defdata->pmf->get_qdim());
 
  149       pf->interpolation(ctx, coeff, val, defdata->pmf->get_qdim());
 
  173   scalar_type slicer_volume::trinom(scalar_type a, scalar_type b, scalar_type c) {
 
  174     scalar_type delta = b * b - 4 * a * c;
 
  175     if (delta < 0.) 
return 1. / EPS;
 
  177     scalar_type s1 = (-b - delta) / (2 * a);
 
  178     scalar_type s2 = (-b + delta) / (2 * a);
 
  179     if (gmm::abs(s1 - 0.5) < gmm::abs(s2 - 0.5))
 
  198                                     std::bitset<32> spin, std::bitset<32> spbin) {
 
  199     scalar_type alpha = 0; 
size_type iA=0, iB = 0;
 
  200     bool intersection = 
false;
 
  201     static int level = 0;
 
  211     for (iA=0; iA < s.dim(); ++iA) {
 
  212       if (spbin[iA]) 
continue;
 
  213       for (iB=iA+1; iB < s.dim()+1; ++iB) {
 
  214         if (!spbin[iB] && spin[iA] != spin[iB]) {
 
  215           alpha=edge_intersect(s.inodes[iA],s.inodes[iB],ms.nodes);
 
  216           if (alpha >= 1e-8 && alpha <= 1-1e-8) { intersection = 
true; 
break; }
 
  219       if (intersection) 
break;
 
  223       const slice_node& A = ms.nodes[s.inodes[iA]]; 
 
  224       const slice_node& B = ms.nodes[s.inodes[iB]]; 
 
  225       slice_node n(A.pt + alpha*(B.pt-A.pt), A.pt_ref + alpha*(B.pt_ref-A.pt_ref));
 
  226       n.faces = A.faces & B.faces;
 
  228       ms.nodes.push_back(n); 
 
  229       pt_bin.add(nn); pt_in.add(nn);
 
  231       std::bitset<32> spin2(spin), spbin2(spbin); 
 
  232       std::swap(s.inodes[iA],nn);
 
  233       spin2.set(iA); spbin2.set(iA);
 
  234       split_simplex(ms, s, sstart, spin2, spbin2);
 
  236       std::swap(s.inodes[iA],nn); std::swap(s.inodes[iB],nn);
 
  237       spin2 = spin; spbin2 = spbin; spin2.set(iB); spbin2.set(iB);
 
  238       split_simplex(ms, s, sstart, spin2, spbin2);
 
  243       for (
size_type i=0; i < s.dim()+1; ++i) 
if (!spin[i]) { all_in = 
false; 
break; }
 
  247       ms.add_simplex(s,(all_in && orient != VOLBOUND) || orient == VOLSPLIT); 
 
  249         slice_simplex face(s.dim());
 
  250         for (
size_type f=0; f < s.dim()+1; ++f) {
 
  254             if (!spbin[p]) { all_in = 
false; 
break; }
 
  255             else face.inodes[i] = s.inodes[p];
 
  259             std::sort(face.inodes.begin(), face.inodes.end());
 
  260             if (std::find(ms.simplexes.begin()+sstart, ms.simplexes.end(), face) == ms.simplexes.end()) {
 
  261               ms.add_simplex(face,
true);
 
  276   void slicer_volume::exec(mesh_slicer& ms) {
 
  278     if (ms.splx_in.card() == 0) 
return;
 
  279     prepare(ms.cv,ms.nodes,ms.nodes_index);
 
  280     for (dal::bv_visitor_c cnt(ms.splx_in); !cnt.finished(); ++cnt) {
 
  281       slice_simplex& s = ms.simplexes[cnt];
 
  288       std::bitset<32> spin, spbin;
 
  289       for (
size_type i=0; i < s.dim()+1; ++i) {
 
  290         if (pt_in.is_in(s.inodes[i])) { ++in_cnt; spin.set(i); }
 
  291         if (pt_bin.is_in(s.inodes[i])) { ++in_bcnt; spbin.set(i); }
 
  295         if (orient != VOLSPLIT) ms.splx_in.sup(cnt);
 
  296       } 
else if (in_cnt != s.dim()+1 || orient==VOLBOUND) {           
 
  298         split_simplex(ms, s, ms.simplexes.size(), spin, spbin);
 
  304       GMM_ASSERT1(ms.fcnt != dim_type(-1), 
 
  305                   "too much {faces}/{slices faces} in the convex " << ms.cv 
 
  306                   << 
" (nbfaces=" << ms.fcnt << 
")");
 
  307       for (dal::bv_visitor cnt(pt_bin); !cnt.finished(); ++cnt) {
 
  308         ms.nodes[cnt].faces.set(ms.fcnt);
 
  312     ms.update_nodes_index();
 
  315   slicer_mesh_with_mesh::slicer_mesh_with_mesh(
const mesh& slm_) :  slm(slm_) { 
 
  317     for (dal::bv_visitor cv(slm.convex_index()); !cv.finished(); ++cv) {
 
  318       bgeot::bounding_box(min,max,slm.points_of_convex(cv),slm.trans_of_convex(cv));
 
  319       tree.add_box(min, max, cv);
 
  324   void slicer_mesh_with_mesh::exec(mesh_slicer &ms) {
 
  326     base_node min(ms.nodes[0].pt),max(ms.nodes[0].pt);
 
  327     for (
size_type i=1; i < ms.nodes.size(); ++i) {
 
  328       for (
size_type k=0; k < min.size(); ++k) {
 
  329         min[k] = std::min(min[k], ms.nodes[i].pt[k]);
 
  330         max[k] = std::max(max[k], ms.nodes[i].pt[k]);
 
  333     std::vector<size_type> slmcvs;
 
  334     tree.find_intersecting_boxes(min, max, slmcvs);
 
  336     mesh_slicer::cs_simplexes_ct simplexes_final(ms.simplexes); 
 
  337     dal::bit_vector splx_in_save(ms.splx_in), 
 
  338       simplex_index_save(ms.simplex_index), nodes_index_save(ms.nodes_index); 
 
  342     for (
size_type i=0; i < slmcvs.size(); ++i) {
 
  344       dim_type fcnt_save = dim_type(ms.fcnt);
 
  345       ms.simplexes.resize(scnt0); 
 
  346       ms.splx_in = splx_in_save; ms.simplex_index = simplex_index_save; ms.nodes_index = nodes_index_save;
 
  355           base_node G = gmm::mean_value(slm.points_of_convex(slmcv).begin(),slm.points_of_convex(slmcv).end());
 
  357           n[0] = A[1]*B[2] - A[2]*B[1];
 
  358           n[1] = A[2]*B[0] - A[0]*B[2];
 
  359           n[2] = A[0]*B[1] - A[1]*B[0];
 
  360           if (gmm::vect_sp(n,G-x0) > 0) n *= -1.;
 
  366         slicer_half_space slf(x0,n,slicer_volume::VOLIN);
 
  368         if (ms.splx_in.card() == 0) 
break;
 
  370       if (ms.splx_in.card()) intersection_callback(ms, slmcv);
 
  371       for (dal::bv_visitor is(ms.splx_in); !is.finished(); ++is) {
 
  372         simplexes_final.push_back(ms.simplexes[is]);
 
  376     ms.splx_in.clear(); ms.splx_in.add(scnt0, simplexes_final.size()-scnt0); 
 
  377     ms.simplexes.swap(simplexes_final);
 
  378     ms.simplex_index = ms.splx_in;
 
  379     ms.update_nodes_index();
 
  386   void slicer_isovalues::prepare(
size_type cv,
 
  387                                  const mesh_slicer::cs_nodes_ct& nodes, 
 
  388                                  const dal::bit_vector& nodes_index) {
 
  389     pt_in.clear(); pt_bin.clear();
 
  390     std::vector<base_node> refpts(nodes.size());
 
  391     Uval.resize(nodes.size());
 
  394     pfem pf = mfU->pmf->fem_of_element(cv);
 
  396     fem_precomp_pool fprecomp;
 
  398       bgeot::vectors_to_base_matrix
 
  399         (G,mfU->pmf->linked_mesh().points_of_convex(cv));
 
  400     for (
size_type i=0; i < nodes.size(); ++i) refpts[i] = nodes[i].pt_ref;
 
  401     pfem_precomp pfp = fprecomp(pf, store_point_tab(refpts));
 
  402     mfU->copy(cv, coeff);
 
  405     fem_interpolation_context ctx(mfU->pmf->linked_mesh().trans_of_convex(cv),
 
  407     for (dal::bv_visitor i(nodes_index); !i.finished(); ++i) {
 
  410       pf->interpolation(ctx, coeff, v, mfU->pmf->get_qdim());
 
  413       pt_bin[i] = (gmm::abs(Uval[i] - val) < EPS * val_scaling);
 
  414       pt_in[i] = (Uval[i] - val < 0); 
if (
orient>0) pt_in[i] = !pt_in[i]; 
 
  415       pt_in[i] = pt_in[i] || pt_bin[i];
 
  424                                    const mesh_slicer::cs_nodes_ct&)
 const {
 
  425     assert(iA < Uval.size() && iB < Uval.size());
 
  426     if (((Uval[iA] < val) && (Uval[iB] > val)) ||
 
  427         ((Uval[iA] > val) && (Uval[iB] < val)))
 
  428       return (val-Uval[iA])/(Uval[iB]-Uval[iA]);
 
  434   void slicer_union::exec(mesh_slicer &ms) {
 
  435     dal::bit_vector splx_in_base = ms.splx_in;
 
  437     dim_type fcnt_0 = dim_type(ms.fcnt);
 
  439     dal::bit_vector splx_inA(ms.splx_in);
 
  440     dim_type fcnt_1 = dim_type(ms.fcnt);
 
  442     dal::bit_vector splx_inB = splx_in_base;
 
  443     splx_inB.add(c, ms.simplexes.size()-c);
 
  444     splx_inB.setminus(splx_inA);
 
  445     for (dal::bv_visitor_c i(splx_inB); !i.finished(); ++i) {
 
  446       if (!ms.simplex_index[i]) splx_inB.sup(i);
 
  449     ms.splx_in = splx_inB;
 
  450     B->exec(ms); splx_inB = ms.splx_in;
 
  451     ms.splx_in |= splx_inA;
 
  457     for (
unsigned f=fcnt_0; f < fcnt_1; ++f) {
 
  458       for (dal::bv_visitor i(splx_inB); !i.finished(); ++i) {
 
  459         for (
unsigned j=0; j < ms.simplexes[i].dim()+1; ++j) {
 
  460           bool face_boundA = 
true;
 
  461           for (
unsigned k=0; k < ms.simplexes[i].dim()+1; ++k) {
 
  462             if (j != k && !ms.nodes[ms.simplexes[i].inodes[k]].faces[f]) {
 
  463               face_boundA = 
false; 
break;
 
  471             for (
unsigned k=0; k < ms.simplexes[i].dim()+1; ++k)
 
  472               if (j != k) ms.nodes[ms.simplexes[i].inodes[k]].faces[f] = 
false;            
 
  477     ms.update_nodes_index();
 
  480   void slicer_intersect::exec(mesh_slicer& ms) {
 
  485   void slicer_complementary::exec(mesh_slicer& ms) {
 
  486     dal::bit_vector splx_inA = ms.splx_in;
 
  488     A->exec(ms); splx_inA.swap(ms.splx_in);
 
  489     ms.splx_in &= ms.simplex_index;
 
  490     dal::bit_vector bv = ms.splx_in; bv.add(sz, ms.simplexes.size()-sz); bv &= ms.simplex_index;
 
  491     for (dal::bv_visitor_c i(bv); !i.finished(); ++i) {
 
  495       ms.splx_in[i] = !splx_inA.is_in(i);
 
  499   void slicer_compute_area::exec(mesh_slicer &ms) {
 
  500     for (dal::bv_visitor is(ms.splx_in); !is.finished(); ++is) {
 
  501       const slice_simplex& s = ms.simplexes[is];
 
  502         base_matrix M(s.dim(),s.dim());
 
  505           M(i,j) = ms.nodes[s.inodes[i+1]].pt[j] - ms.nodes[s.inodes[0]].pt[j];
 
  506       scalar_type v = bgeot::lu_det(&(*(M.begin())), s.dim());
 
  507       for (
size_type d=2; d <= s.dim(); ++d) v /= scalar_type(d);
 
  512   void slicer_build_edges_mesh::exec(mesh_slicer &ms) {
 
  513     for (dal::bv_visitor is(ms.splx_in); !is.finished(); ++is) {
 
  514       const slice_simplex& s = ms.simplexes[is];
 
  516         for (
size_type j=i+1; j <= s.dim(); ++j) {
 
  517           const slice_node& A = ms.nodes[s.inodes[i]];
 
  518           const slice_node& B = ms.nodes[s.inodes[j]];
 
  521           if ((A.faces & B.faces).count() >= 
unsigned(ms.cv_dim-1)) {
 
  522             slice_node::faces_ct fmask((1 << ms.cv_nbfaces)-1); fmask.flip();
 
  524             if (pslice_edges && (((A.faces & B.faces) & fmask).any())) pslice_edges->add(e);
 
  531   void slicer_build_mesh::exec(mesh_slicer &ms) {
 
  532     std::vector<size_type> pid(ms.nodes_index.last_true()+1);
 
  533     for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i)
 
  534       pid[i] = m.add_point(ms.nodes[i].pt);
 
  535     for (dal::bv_visitor i(ms.splx_in); !i.finished(); ++i) {
 
  536       for (
unsigned j=0; j < ms.simplexes.at(i).inodes.size(); ++j) {
 
  537         assert(m.points_index().is_in(pid.at(ms.simplexes.at(i).inodes[j])));
 
  539       m.add_convex(bgeot::simplex_geotrans(ms.simplexes[i].dim(),1),
 
  540                    gmm::index_ref_iterator(pid.begin(),
 
  541                                            ms.simplexes[i].inodes.begin()));
 
  545   void slicer_explode::exec(mesh_slicer &ms) {
 
  546     if (ms.nodes_index.card() == 0) 
return;    
 
  549     if (ms.face < dim_type(-1))
 
  550       G = gmm::mean_value(ms.m.points_of_face_of_convex(ms.cv, ms.face).begin(), 
 
  551                           ms.m.points_of_face_of_convex(ms.cv, ms.face).end());
 
  553       G = gmm::mean_value(ms.m.points_of_convex(ms.cv).begin(), 
 
  554                           ms.m.points_of_convex(ms.cv).end());    
 
  555     for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i)
 
  556       ms.nodes[i].pt = G + coef*(ms.nodes[i].pt - G);
 
  558     for (dal::bv_visitor cnt(ms.splx_in); !cnt.finished(); ++cnt) {
 
  559       const slice_simplex& s = ms.simplexes[cnt];
 
  565           static unsigned ord[][3] = {{0,2,1},{1,2,3},{1,3,0},{0,3,2}}; 
 
  566           for (
size_type k=0; k < 3; ++k) { s2.inodes[k] = ms.simplexes[cnt].inodes[ord[j][k]]; } 
 
  568           slice_node::faces_ct f; f.set();
 
  569           for (
size_type i=0; i < s2.dim()+1; ++i) {
 
  570             f &= ms.nodes[s2.inodes[i]].faces;
 
  573             ms.add_simplex(s2, 
true);
 
  583     m(mls_.linked_mesh()), mls(&mls_), pgt(0), cvr(0) {}
 
  585     m(m_), mls(0), pgt(0), cvr(0) {}
 
  587   void mesh_slicer::using_mesh_level_set(
const mesh_level_set &mls_) { 
 
  589     GMM_ASSERT1(&m == &mls->
linked_mesh(), 
"different meshes");
 
  592   void mesh_slicer::pack() {
 
  593     std::vector<size_type> new_id(nodes.size());
 
  595     for (dal::bv_visitor i(nodes_index); !i.finished(); ++i) {
 
  597         nodes[i].swap(nodes[ncnt]);
 
  603     for (dal::bv_visitor j(simplex_index); !j.finished(); ++j) {
 
  604       if (j != scnt) { simplexes[scnt] = simplexes[j]; }
 
  605       for (std::vector<size_type>::iterator it = simplexes[scnt].inodes.begin(); 
 
  606            it != simplexes[scnt].inodes.end(); ++it) {
 
  610     simplexes.resize(scnt);
 
  613   void mesh_slicer::update_nodes_index() {
 
  615     for (dal::bv_visitor j(simplex_index); !j.finished(); ++j) {
 
  616       assert(j < simplexes.size());
 
  617       for (std::vector<size_type>::iterator it = simplexes[j].inodes.begin(); 
 
  618            it != simplexes[j].inodes.end(); ++it) {
 
  619         assert(*it < nodes.size());
 
  620         nodes_index.add(*it);
 
  625   static void flag_points_on_faces(
const bgeot::pconvex_ref& cvr, 
 
  626                                    const std::vector<base_node>& pts, 
 
  627                                    std::vector<slice_node::faces_ct>& faces) {
 
  628     GMM_ASSERT1(cvr->structure()->nb_faces() <= 32,
 
  629                 "won't work for convexes with more than 32 faces " 
  630                 "(hardcoded limit)");
 
  631     faces.resize(pts.size());
 
  632     for (
size_type i=0; i < pts.size(); ++i) {
 
  634       for (
short_type f=0; f < cvr->structure()->nb_faces(); ++f)
 
  635         faces[i][f] = (gmm::abs(cvr->is_in_face(f, pts[i])) < 1e-10);
 
  642     pgt = m.trans_of_convex(cv);
 
  643     prev_cvr = cvr; cvr = pgt->convex_ref();      
 
  644     cv_dim = cvr->structure()->dim();
 
  645     cv_nbfaces = cvr->structure()->nb_faces();
 
  646     fcnt = cvr->structure()->nb_faces();
 
  647     discont = (mls && mls->is_convex_cut(cv));
 
  650   void mesh_slicer::apply_slicers() {
 
  651     simplex_index.clear(); simplex_index.add(0, simplexes.size());
 
  652     splx_in = simplex_index;
 
  653     nodes_index.clear(); nodes_index.add(0, nodes.size());      
 
  654     for (
size_type i=0; i < action.size(); ++i) {
 
  655       action[i]->exec(*
this);
 
  657       assert(simplex_index.contains(splx_in));
 
  661   void mesh_slicer::simplex_orientation(slice_simplex& s) {
 
  666         base_small_vector d = nodes[s.inodes[i]].pt - nodes[s.inodes[0]].pt;
 
  667         gmm::copy_n(d.const_begin(), N, M.begin() + (i-1)*N);
 
  669       scalar_type J = bgeot::lu_det(&(*(M.begin())), N);
 
  672         std::swap(s.inodes[1],s.inodes[0]);
 
  684     exec_(&nrefine[0], 1, cvlst);
 
  689     if (pgt->dim() == m.dim() && m.dim()>=2) { 
 
  691       base_matrix G; bgeot::vectors_to_base_matrix(G,m.points_of_convex(cv));
 
  692       base_node g(pgt->dim()); g.fill(.5); 
 
  693       base_matrix pc; pgt->poly_vector_grad(g,pc);
 
  694       base_matrix K(pgt->dim(),pgt->dim());
 
  696       scalar_type J = bgeot::lu_det(&(*(K.begin())), pgt->dim());
 
  699       if (J < 0) 
return true;
 
  706   void mesh_slicer::exec_(
const short_type *pnrefine, 
int nref_stride,
 
  707                           const mesh_region& cvlst) {
 
  708     std::vector<base_node> cvm_pts;
 
  709     const bgeot::basic_mesh *cvm = 0;
 
  712     bgeot::pgeotrans_precomp pgp = 0;
 
  713     std::vector<slice_node::faces_ct> points_on_faces;
 
  717     for (mr_visitor it(cvlst); !it.finished(); ++it) {
 
  718       size_type nrefine = pnrefine[it.cv()*nref_stride];
 
  719       update_cv_data(it.cv(),it.f());      
 
  720       bool revert_orientation = check_orient(cv, pgt,m);
 
  723       if (prev_cvr != cvr || nrefine != prev_nrefine) {
 
  725         cvm_pts.resize(cvm->points().card());
 
  726         std::copy(cvm->points().begin(), cvm->points().end(), cvm_pts.begin());
 
  727         pgp = gppool(pgt, store_point_tab(cvm_pts));
 
  728         flag_points_on_faces(cvr, cvm_pts, points_on_faces);
 
  729         prev_nrefine = nrefine;
 
  731       if (face < dim_type(-1))
 
  737       std::vector<size_type> ptsid(cvm_pts.size()); std::fill(ptsid.begin(), ptsid.end(), 
size_type(-1));
 
  745         if (revert_orientation) std::swap(simplexes[snum].inodes[0],simplexes[snum].inodes[1]);
 
  747         for (std::vector<size_type>::iterator itp = simplexes[snum].inodes.begin();
 
  748              itp != simplexes[snum].inodes.end(); ++itp) {
 
  750             ptsid[*itp] = nodes.size();
 
  751             nodes.push_back(slice_node());
 
  752             nodes.back().pt_ref = cvm_pts[*itp];
 
  753             nodes.back().faces = points_on_faces[*itp];
 
  754             nodes.back().pt.resize(m.dim()); nodes.back().pt.fill(0.);
 
  755             pgp->transform(m.points_of_convex(cv), *itp, nodes.back().pt);
 
  762             cout << 
"check orient cv " << cv << 
", snum=" << snum << 
"/" << cvms->
nb_convex();
 
  764           simplex_orientation(simplexes[snum]);
 
  772   template <
typename CONT> 
 
  775     unsigned N = pgt->dim();
 
  776     std::vector<base_node> v; v.reserve(N+1);
 
  777     for (
unsigned i=0; i < pgt->nb_points(); ++i) {
 
  778       const base_node P = pgt->convex_ref()->points()[i];
 
  780       for (
unsigned j=0; j < N; ++j) { 
 
  781         s += P[j]; 
if (P[j] == 1) { v.push_back(pts[i]); 
break; }
 
  783       if (s == 0) v.push_back(pts[i]);
 
  785     assert(v.size() == N+1);
 
  786     base_node G = gmm::mean_value(v);
 
  789     m.add_convex_by_points(bgeot::simplex_geotrans(N,1), v.begin());
 
  792   const mesh& mesh_slicer::refined_simplex_mesh_for_convex_cut_by_level_set
 
  793   (
const mesh &cvm, 
unsigned nrefine) {
 
  794     mesh mm; mm.copy_from(cvm);
 
  795     while (nrefine > 1) { 
 
  796       mm.Bank_refine(mm.convex_index());
 
  800     std::vector<size_type> idx;
 
  803     for (dal::bv_visitor_c ic(mm.convex_index()); !ic.finished(); ++ic) {
 
  804       add_degree1_convex(mm.trans_of_convex(ic), mm.points_of_convex(ic), tmp_mesh);
 
  812   mesh_slicer::refined_simplex_mesh_for_convex_faces_cut_by_level_set
 
  814     mesh &cvm = tmp_mesh;
 
  815     tmp_mesh_struct.
clear();
 
  816     unsigned N = cvm.dim();
 
  818     dal::bit_vector pt_in_face; pt_in_face.sup(0, cvm.points().index().last_true()+1);
 
  819     for (dal::bv_visitor ip(cvm.points().index()); !ip.finished(); ++ip)
 
  820       if (gmm::abs(cvr->is_in_face(
short_type(f), cvm.points()[ip]))) pt_in_face.add(ip);
 
  822     for (dal::bv_visitor_c ic(cvm.convex_index()); !ic.finished(); ++ic) {
 
  823       for (
short_type ff=0; ff < cvm.nb_faces_of_convex(ic); ++ff) {
 
  825         for (
unsigned i=0; i < N; ++i) {
 
  826           if (!pt_in_face.is_in(cvm.ind_points_of_face_of_convex(ic,ff)[i])) {
 
  827             face_ok = 
false; 
break;
 
  832                                      cvm.ind_points_of_face_of_convex(ic, ff).begin());
 
  836     return tmp_mesh_struct;
 
  839   void mesh_slicer::exec_(
const short_type *pnrefine, 
 
  841                           const mesh_region& cvlst) {
 
  842     std::vector<base_node> cvm_pts;
 
  843     const bgeot::basic_mesh *cvm = 0;
 
  846     bgeot::pgeotrans_precomp pgp = 0;
 
  847     std::vector<slice_node::faces_ct> points_on_faces;
 
  848     bool prev_discont = 
true;
 
  853     for (mr_visitor it(cvlst); !it.finished(); ++it) {
 
  854       size_type nrefine = pnrefine[it.cv()*nref_stride];
 
  855       update_cv_data(it.cv(),it.f());
 
  856       bool revert_orientation = check_orient(cv, pgt,m);
 
  860       if (prev_cvr != cvr || nrefine != prev_nrefine
 
  861           || discont || prev_discont) {
 
  863           cvm = &refined_simplex_mesh_for_convex_cut_by_level_set
 
  864             (mls->mesh_of_convex(cv), 
unsigned(nrefine));
 
  868         cvm_pts.resize(cvm->points().card());
 
  869         std::copy(cvm->points().begin(), cvm->points().end(), cvm_pts.begin());
 
  870         pgp = gppool(pgt, store_point_tab(cvm_pts));
 
  871         flag_points_on_faces(cvr, cvm_pts, points_on_faces);
 
  872         prev_nrefine = nrefine;
 
  874       if (face < dim_type(-1)) {
 
  879           cvms = &refined_simplex_mesh_for_convex_faces_cut_by_level_set(face);
 
  886       std::vector<size_type> ptsid(cvm_pts.size()); std::fill(ptsid.begin(), ptsid.end(), 
size_type(-1));
 
  896         if (revert_orientation) std::swap(simplexes[snum].inodes[0],simplexes[snum].inodes[1]);
 
  899           G.resize(m.dim()); G.fill(0.);
 
  900           for (std::vector<size_type>::iterator itp = 
 
  901                  simplexes[snum].inodes.begin();
 
  902                itp != simplexes[snum].inodes.end(); ++itp) {
 
  905           G /= scalar_type(simplexes[snum].inodes.size());
 
  908         for (std::vector<size_type>::iterator itp = 
 
  909                simplexes[snum].inodes.begin();
 
  910              itp != simplexes[snum].inodes.end(); ++itp) {
 
  911           if (discont || ptsid[*itp] == 
size_type(-1)) {
 
  912             ptsid[*itp] = nodes.size();
 
  913             nodes.push_back(slice_node());
 
  915               nodes.back().pt_ref = cvm_pts[*itp];
 
  921               nodes.back().pt_ref = cvm_pts[*itp] + 0.01*(G - cvm_pts[*itp]);
 
  923             nodes.back().faces = points_on_faces[*itp];
 
  924             nodes.back().pt.resize(m.dim()); nodes.back().pt.fill(0.);
 
  925             pgp->transform(m.points_of_convex(cv), *itp, nodes.back().pt);
 
  936       prev_discont = discont;
 
  942     exec(nrefine,mesh_region(m.convex_index()));
 
  947     GMM_ASSERT1(&sl.
linked_mesh() == &m, 
"wrong mesh");
 
  948     for (stored_mesh_slice::cvlst_ct::const_iterator it = sl.cvlst.begin(); it != sl.cvlst.end(); ++it) {
 
  949       update_cv_data((*it).cv_num);
 
  951       simplexes = (*it).simplexes;
 
  962     for (dal::bv_visitor ic(m.convex_index()); !ic.finished(); ++ic) {
 
  966       nodes.resize(0); simplexes.resize(0);
 
  970         nodes.push_back(slice_node(pts[itab[i]],ptab[i])); nodes.back().faces=0;
 
  971         slice_simplex s(1); s.inodes[0] = nodes.size()-1;
 
  972         simplexes.push_back(s);
 
  979   slicer_half_space::test_point(
const base_node& P, 
bool& in, 
bool& bound)
 const {
 
  980     scalar_type s = gmm::vect_sp(P - x0, n);
 
  981     in = (s <= 0); bound = (s * s <= EPS); 
 
  988                                     const mesh_slicer::cs_nodes_ct& nodes)
 const {
 
  989     const base_node& A = nodes[iA].pt;
 
  990     const base_node& B = nodes[iB].pt;
 
  991     scalar_type s1 = 0., s2 = 0.;
 
  992     for (
unsigned i = 0; i < A.size(); ++i) {
 
  993       s1 += (A[i] - B[i]) * n[i]; s2 += (A[i] - x0[i]) * n[i];
 
  995     if (gmm::abs(s1) < EPS)
 
 1002   slicer_sphere::test_point(
const base_node& P, 
bool& in, 
bool& bound)
 const {
 
 1004     bound = (R2 >= (1-EPS)*R*R && R2 <= (1+EPS)*R*R);
 
 1010                                 const mesh_slicer::cs_nodes_ct& nodes)
 const {
 
 1011     const base_node& A=nodes[iA].pt;
 
 1012     const base_node& B=nodes[iB].pt;
 
 1016       return pt_bin.is_in(iA) ? 0. : 1./EPS;
 
 1023   slicer_cylinder::test_point(
const base_node& P, 
bool& in, 
bool& bound)
 const {
 
 1030     bound = gmm::abs(dist2-R*R) < EPS;
 
 1036                                   const mesh_slicer::cs_nodes_ct& nodes)
 const {
 
 1037     base_node F=nodes[iA].pt;
 
 1038     base_node D=nodes[iB].pt-nodes[iA].pt;
 
 1039     if (2 == F.size()) {
 
 1048       return pt_bin.is_in(iA) ? 0. : 1./EPS;
 
Inversion of geometric transformations.
 
handles the geometric inversion for a given (supposedly quite large) set of points
 
void add_points(const CONT &c)
Add the points contained in c to the list of points.
 
size_type points_in_convex(const convex< base_node, TAB > &cv, pgeometric_trans pgt, CONT1 &pftab, CONT2 &itab, bool bruteforce=false)
Search all the points in the convex cv, which is the transformation of the convex cref via the geomet...
 
The object geotrans_precomp_pool Allow to allocate a certain number of geotrans_precomp and automatic...
 
Mesh structure definition.
 
short_type nb_points_of_convex(size_type ic) const
Return the number of points of convex ic.
 
void clear()
erase the mesh
 
size_type nb_convex() const
The total number of convexes in the mesh.
 
size_type add_convex(pconvex_structure cs, ITER ipts, bool *present=0)
Insert a new convex in the mesh_structure.
 
pconvex_structure structure_of_convex(size_type ic) const
Return the pconvex_structure of the convex ic.
 
const ind_set & ind_points_of_convex(size_type ic) const
Return a container to the list of points attached to convex ic.
 
static T & instance()
Instance from the current thread.
 
Keep informations about a mesh crossed by level-sets.
 
mesh & linked_mesh(void) const
Gives a reference to the linked mesh of type mesh.
 
structure used to hold a set of convexes and/or convex faces.
 
Apply a serie a slicing operations to a mesh.
 
void exec(size_type nrefine, const mesh_region &cvlst)
build a new mesh_slice.
 
mesh_slicer(const mesh &m_)
mesh_slicer constructor.
 
Describe a mesh (collection of convexes (elements) and points).
 
ref_mesh_face_pt_ct points_of_face_of_convex(size_type ic, short_type f) const
Return a (pseudo)container of points of face of a given convex.
 
base_small_vector normal_of_face_of_convex(size_type ic, short_type f, const base_node &pt) const
Return the normal of the given convex face, evaluated at the point pt.
 
void clear()
Erase the mesh.
 
size_type add_segment_by_points(const base_node &pt1, const base_node &pt2)
Add a segment to the mesh, given the coordinates of its vertices.
 
int orient
orient defines the kind of slicing : VOLIN -> keep the inside of the volume, VOLBOUND -> its boundary...
 
static scalar_type trinom(scalar_type a, scalar_type b, scalar_type c)
Utility function.
 
The output of a getfem::mesh_slicer which has been recorded.
 
const mesh & linked_mesh() const
return a pointer to the original mesh
 
A simple singleton implementation.
 
Keep informations about a mesh crossed by level-sets.
 
Define the class getfem::stored_mesh_slice.
 
Define various mesh slicers.
 
number_traits< typename linalg_traits< V1 >::value_type >::magnitude_type vect_dist2_sqr(const V1 &v1, const V2 &v2)
squared Euclidean distance between two vectors
 
number_traits< typename linalg_traits< V >::value_type >::magnitude_type vect_norm2_sqr(const V &v)
squared Euclidean norm of a vector.
 
strongest_value_type< V1, V2 >::value_type vect_sp(const V1 &v1, const V2 &v2)
*/
 
void add(const L1 &l1, L2 &l2)
*/
 
void APIDECL outer_faces_of_mesh(const mesh &m, const dal::bit_vector &cvlst, convex_face_ct &flist)
returns a list of "exterior" faces of a mesh (i.e.
 
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
 
gmm::uint16_type short_type
used as the common short type integer in the library
 
const basic_mesh * refined_simplex_mesh_for_convex(pconvex_ref cvr, short_type k)
simplexify a convex_ref.
 
const std::vector< std::unique_ptr< mesh_structure > > & refined_simplex_mesh_for_convex_faces(pconvex_ref cvr, short_type k)
simplexify the faces of a convex_ref
 
pconvex_structure simplex_structure(dim_type nc)
Give a pointer on the structures of a simplex of dimension d.
 
size_t size_type
used as the common size type in the library
 
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
 
GEneric Tool for Finite Element Methods.