28 const float slicer_action::EPS = float(1e-13);
32 slicer_none& slicer_none::static_instance() {
37 slicer_boundary::slicer_boundary(
const mesh& m, slicer_action &sA,
38 const mesh_region& cvflst) : A(&sA) {
42 slicer_boundary::slicer_boundary(
const mesh& m, slicer_action &sA) : A(&sA) {
45 build_from(m,cvflist);
48 void slicer_boundary::build_from(
const mesh& m,
const mesh_region& cvflst) {
49 if (m.convex_index().card()==0)
return;
50 convex_faces.resize(m.convex_index().last()+1, slice_node::faces_ct(0L));
51 for (mr_visitor i(cvflst); !i.finished(); ++i)
52 if (i.is_face()) convex_faces[i.cv()][i.f()]=1;
53 else convex_faces[i.cv()].set();
56 for (dal::bv_visitor cv(m.convex_index()); !cv.finished(); ++cv) {
57 for (
short_type f=m.structure_of_convex(cv)->nb_faces(); f < convex_faces[cv].size(); ++f)
58 convex_faces[cv][f]=1;
62 bool slicer_boundary::test_bound(
const slice_simplex& s, slice_node::faces_ct& fmask,
const mesh_slicer::cs_nodes_ct& nodes)
const {
63 slice_node::faces_ct f; f.set();
65 f &= nodes[s.inodes[i]].faces;
71 void slicer_boundary::exec(mesh_slicer& ms) {
73 if (ms.splx_in.card() == 0)
return;
74 slice_node::faces_ct fmask(ms.cv < convex_faces.size() ? convex_faces[ms.cv] : 0);
76 if (!convex_faces[ms.cv].any()) { ms.splx_in.clear();
return; }
78 for (dal::bv_visitor_c cnt(ms.splx_in); !cnt.finished(); ++cnt) {
79 const slice_simplex& s = ms.simplexes[cnt];
80 if (s.dim() < ms.nodes[0].pt.size()) {
81 if (!test_bound(s, fmask, ms.nodes)) ms.splx_in.sup(cnt);
82 }
else if (s.dim() == 2) {
87 static unsigned ord[][2] = {{0,1},{1,2},{2,0}};
88 for (
size_type k=0; k < 2; ++k) { s2.inodes[k] = ms.simplexes[cnt].inodes[ord[j][k]]; }
89 if (test_bound(s2, fmask, ms.nodes)) {
90 ms.add_simplex(s2,
true);
93 }
else if (s.dim() == 3) {
99 static unsigned ord[][3] = {{0,2,1},{1,2,3},{1,3,0},{0,3,2}};
100 for (
size_type k=0; k < 3; ++k) { s2.inodes[k] = ms.simplexes[cnt].inodes[ord[j][k]]; }
103 if (test_bound(s2, fmask, ms.nodes)) {
104 ms.add_simplex(s2,
true);
109 ms.update_nodes_index();
113 void slicer_apply_deformation::exec(mesh_slicer& ms) {
116 bool ref_pts_changed =
false;
117 if (ms.cvr != ms.prev_cvr
118 || defdata->pmf->fem_of_element(ms.cv) != pf) {
119 pf = defdata->pmf->fem_of_element(ms.cv);
121 bgeot::vectors_to_base_matrix
122 (G, defdata->pmf->linked_mesh().points_of_convex(ms.cv));
126 std::vector<base_node> ref_pts2; ref_pts2.reserve(ms.nodes_index.card());
127 for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i) {
128 ref_pts2.push_back(ms.nodes[i].pt_ref);
129 if (ref_pts2.size() > ref_pts.size()
130 || gmm::vect_dist2_sqr(ref_pts2[i],ref_pts[i])>1e-20)
131 ref_pts_changed =
true;
133 if (ref_pts2.size() != ref_pts.size()) ref_pts_changed =
true;
134 if (ref_pts_changed) {
135 ref_pts.swap(ref_pts2);
138 bgeot::pstored_point_tab pspt = store_point_tab(ref_pts);
139 pfem_precomp pfp = fprecomp(pf, pspt);
140 defdata->copy(ms.cv, coeff);
142 base_vector val(ms.m.dim());
144 fem_interpolation_context ctx(ms.pgt, pfp, 0, G, ms.cv,
short_type(-1));
145 for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i, ++cnt) {
146 ms.nodes[i].pt.resize(defdata->pmf->get_qdim());
148 pf->interpolation(ctx, coeff, val, defdata->pmf->get_qdim());
172 scalar_type slicer_volume::trinom(scalar_type a, scalar_type b, scalar_type c) {
173 scalar_type delta = b * b - 4 * a * c;
174 if (delta < 0.)
return 1. / EPS;
176 scalar_type s1 = (-b - delta) / (2 * a);
177 scalar_type s2 = (-b + delta) / (2 * a);
178 if (gmm::abs(s1 - 0.5) < gmm::abs(s2 - 0.5))
197 std::bitset<32> spin, std::bitset<32> spbin) {
198 scalar_type alpha = 0;
size_type iA=0, iB = 0;
199 bool intersection =
false;
200 static int level = 0;
210 for (iA=0; iA < s.dim(); ++iA) {
211 if (spbin[iA])
continue;
212 for (iB=iA+1; iB < s.dim()+1; ++iB) {
213 if (!spbin[iB] && spin[iA] != spin[iB]) {
214 alpha=edge_intersect(s.inodes[iA],s.inodes[iB],ms.nodes);
215 if (alpha >= 1e-8 && alpha <= 1-1e-8) { intersection =
true;
break; }
218 if (intersection)
break;
222 const slice_node& A = ms.nodes[s.inodes[iA]];
223 const slice_node& B = ms.nodes[s.inodes[iB]];
224 slice_node n(A.pt + alpha*(B.pt-A.pt), A.pt_ref + alpha*(B.pt_ref-A.pt_ref));
225 n.faces = A.faces & B.faces;
227 ms.nodes.push_back(n);
228 pt_bin.add(nn); pt_in.add(nn);
230 std::bitset<32> spin2(spin), spbin2(spbin);
231 std::swap(s.inodes[iA],nn);
232 spin2.set(iA); spbin2.set(iA);
233 split_simplex(ms, s, sstart, spin2, spbin2);
235 std::swap(s.inodes[iA],nn); std::swap(s.inodes[iB],nn);
236 spin2 = spin; spbin2 = spbin; spin2.set(iB); spbin2.set(iB);
237 split_simplex(ms, s, sstart, spin2, spbin2);
242 for (
size_type i=0; i < s.dim()+1; ++i)
if (!spin[i]) { all_in =
false;
break; }
246 ms.add_simplex(s,(all_in && orient != VOLBOUND) || orient == VOLSPLIT);
248 slice_simplex face(s.dim());
249 for (
size_type f=0; f < s.dim()+1; ++f) {
253 if (!spbin[p]) { all_in =
false;
break; }
254 else face.inodes[i] = s.inodes[p];
258 std::sort(face.inodes.begin(), face.inodes.end());
259 if (std::find(ms.simplexes.begin()+sstart, ms.simplexes.end(), face) == ms.simplexes.end()) {
260 ms.add_simplex(face,
true);
275 void slicer_volume::exec(mesh_slicer& ms) {
277 if (ms.splx_in.card() == 0)
return;
278 prepare(ms.cv,ms.nodes,ms.nodes_index);
279 for (dal::bv_visitor_c cnt(ms.splx_in); !cnt.finished(); ++cnt) {
280 slice_simplex& s = ms.simplexes[cnt];
287 std::bitset<32> spin, spbin;
288 for (
size_type i=0; i < s.dim()+1; ++i) {
289 if (pt_in.is_in(s.inodes[i])) { ++in_cnt; spin.set(i); }
290 if (pt_bin.is_in(s.inodes[i])) { ++in_bcnt; spbin.set(i); }
294 if (orient != VOLSPLIT) ms.splx_in.sup(cnt);
295 }
else if (in_cnt != s.dim()+1 || orient==VOLBOUND) {
297 split_simplex(ms, s, ms.simplexes.size(), spin, spbin);
303 GMM_ASSERT1(ms.fcnt != dim_type(-1),
304 "too much {faces}/{slices faces} in the convex " << ms.cv
305 <<
" (nbfaces=" << ms.fcnt <<
")");
306 for (dal::bv_visitor cnt(pt_bin); !cnt.finished(); ++cnt) {
307 ms.nodes[cnt].faces.set(ms.fcnt);
311 ms.update_nodes_index();
314 slicer_mesh_with_mesh::slicer_mesh_with_mesh(
const mesh& slm_) : slm(slm_) {
316 for (dal::bv_visitor cv(slm.convex_index()); !cv.finished(); ++cv) {
317 bgeot::bounding_box(min,max,slm.points_of_convex(cv),slm.trans_of_convex(cv));
318 tree.add_box(min, max, cv);
323 void slicer_mesh_with_mesh::exec(mesh_slicer &ms) {
325 base_node min(ms.nodes[0].pt),max(ms.nodes[0].pt);
326 for (
size_type i=1; i < ms.nodes.size(); ++i) {
327 for (
size_type k=0; k < min.size(); ++k) {
328 min[k] = std::min(min[k], ms.nodes[i].pt[k]);
329 max[k] = std::max(max[k], ms.nodes[i].pt[k]);
332 std::vector<size_type> slmcvs;
333 tree.find_intersecting_boxes(min, max, slmcvs);
335 mesh_slicer::cs_simplexes_ct simplexes_final(ms.simplexes);
336 dal::bit_vector splx_in_save(ms.splx_in),
337 simplex_index_save(ms.simplex_index), nodes_index_save(ms.nodes_index);
341 for (
size_type i=0; i < slmcvs.size(); ++i) {
343 dim_type fcnt_save = dim_type(ms.fcnt);
344 ms.simplexes.resize(scnt0);
345 ms.splx_in = splx_in_save; ms.simplex_index = simplex_index_save; ms.nodes_index = nodes_index_save;
354 base_node G = gmm::mean_value(slm.points_of_convex(slmcv).begin(),slm.points_of_convex(slmcv).end());
356 n[0] = A[1]*B[2] - A[2]*B[1];
357 n[1] = A[2]*B[0] - A[0]*B[2];
358 n[2] = A[0]*B[1] - A[1]*B[0];
359 if (gmm::vect_sp(n,G-x0) > 0) n *= -1.;
365 slicer_half_space slf(x0,n,slicer_volume::VOLIN);
367 if (ms.splx_in.card() == 0)
break;
369 if (ms.splx_in.card()) intersection_callback(ms, slmcv);
370 for (dal::bv_visitor is(ms.splx_in); !is.finished(); ++is) {
371 simplexes_final.push_back(ms.simplexes[is]);
375 ms.splx_in.clear(); ms.splx_in.add(scnt0, simplexes_final.size()-scnt0);
376 ms.simplexes.swap(simplexes_final);
377 ms.simplex_index = ms.splx_in;
378 ms.update_nodes_index();
385 void slicer_isovalues::prepare(
size_type cv,
386 const mesh_slicer::cs_nodes_ct& nodes,
387 const dal::bit_vector& nodes_index) {
388 pt_in.clear(); pt_bin.clear();
389 std::vector<base_node> refpts(nodes.size());
390 Uval.resize(nodes.size());
393 pfem pf = mfU->pmf->fem_of_element(cv);
395 fem_precomp_pool fprecomp;
397 bgeot::vectors_to_base_matrix
398 (G,mfU->pmf->linked_mesh().points_of_convex(cv));
399 for (
size_type i=0; i < nodes.size(); ++i) refpts[i] = nodes[i].pt_ref;
400 pfem_precomp pfp = fprecomp(pf, store_point_tab(refpts));
401 mfU->copy(cv, coeff);
404 fem_interpolation_context ctx(mfU->pmf->linked_mesh().trans_of_convex(cv),
406 for (dal::bv_visitor i(nodes_index); !i.finished(); ++i) {
409 pf->interpolation(ctx, coeff, v, mfU->pmf->get_qdim());
412 pt_bin[i] = (gmm::abs(Uval[i] - val) < EPS * val_scaling);
413 pt_in[i] = (Uval[i] - val < 0);
if (
orient>0) pt_in[i] = !pt_in[i];
414 pt_in[i] = pt_in[i] || pt_bin[i];
423 const mesh_slicer::cs_nodes_ct&)
const {
424 assert(iA < Uval.size() && iB < Uval.size());
425 if (((Uval[iA] < val) && (Uval[iB] > val)) ||
426 ((Uval[iA] > val) && (Uval[iB] < val)))
427 return (val-Uval[iA])/(Uval[iB]-Uval[iA]);
433 void slicer_union::exec(mesh_slicer &ms) {
434 dal::bit_vector splx_in_base = ms.splx_in;
436 dim_type fcnt_0 = dim_type(ms.fcnt);
438 dal::bit_vector splx_inA(ms.splx_in);
439 dim_type fcnt_1 = dim_type(ms.fcnt);
441 dal::bit_vector splx_inB = splx_in_base;
442 splx_inB.add(c, ms.simplexes.size()-c);
443 splx_inB.setminus(splx_inA);
444 for (dal::bv_visitor_c i(splx_inB); !i.finished(); ++i) {
445 if (!ms.simplex_index[i]) splx_inB.sup(i);
448 ms.splx_in = splx_inB;
449 B->exec(ms); splx_inB = ms.splx_in;
450 ms.splx_in |= splx_inA;
456 for (
unsigned f=fcnt_0; f < fcnt_1; ++f) {
457 for (dal::bv_visitor i(splx_inB); !i.finished(); ++i) {
458 for (
unsigned j=0; j < ms.simplexes[i].dim()+1; ++j) {
459 bool face_boundA =
true;
460 for (
unsigned k=0; k < ms.simplexes[i].dim()+1; ++k) {
461 if (j != k && !ms.nodes[ms.simplexes[i].inodes[k]].faces[f]) {
462 face_boundA =
false;
break;
470 for (
unsigned k=0; k < ms.simplexes[i].dim()+1; ++k)
471 if (j != k) ms.nodes[ms.simplexes[i].inodes[k]].faces[f] =
false;
476 ms.update_nodes_index();
479 void slicer_intersect::exec(mesh_slicer& ms) {
484 void slicer_complementary::exec(mesh_slicer& ms) {
485 dal::bit_vector splx_inA = ms.splx_in;
487 A->exec(ms); splx_inA.swap(ms.splx_in);
488 ms.splx_in &= ms.simplex_index;
489 dal::bit_vector bv = ms.splx_in; bv.add(sz, ms.simplexes.size()-sz); bv &= ms.simplex_index;
490 for (dal::bv_visitor_c i(bv); !i.finished(); ++i) {
494 ms.splx_in[i] = !splx_inA.is_in(i);
498 void slicer_compute_area::exec(mesh_slicer &ms) {
499 for (dal::bv_visitor is(ms.splx_in); !is.finished(); ++is) {
500 const slice_simplex& s = ms.simplexes[is];
501 base_matrix M(s.dim(),s.dim());
504 M(i,j) = ms.nodes[s.inodes[i+1]].pt[j] - ms.nodes[s.inodes[0]].pt[j];
505 scalar_type v = bgeot::lu_det(&(*(M.begin())), s.dim());
506 for (
size_type d=2; d <= s.dim(); ++d) v /= scalar_type(d);
511 void slicer_build_edges_mesh::exec(mesh_slicer &ms) {
512 for (dal::bv_visitor is(ms.splx_in); !is.finished(); ++is) {
513 const slice_simplex& s = ms.simplexes[is];
515 for (
size_type j=i+1; j <= s.dim(); ++j) {
516 const slice_node& A = ms.nodes[s.inodes[i]];
517 const slice_node& B = ms.nodes[s.inodes[j]];
520 if ((A.faces & B.faces).count() >=
unsigned(ms.cv_dim-1)) {
521 slice_node::faces_ct fmask((1 << ms.cv_nbfaces)-1); fmask.flip();
523 if (pslice_edges && (((A.faces & B.faces) & fmask).any())) pslice_edges->add(e);
530 void slicer_build_mesh::exec(mesh_slicer &ms) {
531 std::vector<size_type> pid(ms.nodes_index.last_true()+1);
532 for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i)
533 pid[i] = m.add_point(ms.nodes[i].pt);
534 for (dal::bv_visitor i(ms.splx_in); !i.finished(); ++i) {
535 for (
unsigned j=0; j < ms.simplexes.at(i).inodes.size(); ++j) {
536 assert(m.points_index().is_in(pid.at(ms.simplexes.at(i).inodes[j])));
538 m.add_convex(bgeot::simplex_geotrans(ms.simplexes[i].dim(),1),
539 gmm::index_ref_iterator(pid.begin(),
540 ms.simplexes[i].inodes.begin()));
544 void slicer_explode::exec(mesh_slicer &ms) {
545 if (ms.nodes_index.card() == 0)
return;
548 if (ms.face < dim_type(-1))
549 G = gmm::mean_value(ms.m.points_of_face_of_convex(ms.cv, ms.face).begin(),
550 ms.m.points_of_face_of_convex(ms.cv, ms.face).end());
552 G = gmm::mean_value(ms.m.points_of_convex(ms.cv).begin(),
553 ms.m.points_of_convex(ms.cv).end());
554 for (dal::bv_visitor i(ms.nodes_index); !i.finished(); ++i)
555 ms.nodes[i].pt = G + coef*(ms.nodes[i].pt - G);
557 for (dal::bv_visitor cnt(ms.splx_in); !cnt.finished(); ++cnt) {
558 const slice_simplex& s = ms.simplexes[cnt];
564 static unsigned ord[][3] = {{0,2,1},{1,2,3},{1,3,0},{0,3,2}};
565 for (
size_type k=0; k < 3; ++k) { s2.inodes[k] = ms.simplexes[cnt].inodes[ord[j][k]]; }
567 slice_node::faces_ct f; f.set();
568 for (
size_type i=0; i < s2.dim()+1; ++i) {
569 f &= ms.nodes[s2.inodes[i]].faces;
572 ms.add_simplex(s2,
true);
582 m(mls_.linked_mesh()), mls(&mls_), pgt(0), cvr(0) {}
584 m(m_), mls(0), pgt(0), cvr(0) {}
586 void mesh_slicer::using_mesh_level_set(
const mesh_level_set &mls_) {
588 GMM_ASSERT1(&m == &mls->
linked_mesh(),
"different meshes");
591 void mesh_slicer::pack() {
592 std::vector<size_type> new_id(nodes.size());
594 for (dal::bv_visitor i(nodes_index); !i.finished(); ++i) {
596 nodes[i].swap(nodes[ncnt]);
602 for (dal::bv_visitor j(simplex_index); !j.finished(); ++j) {
603 if (j != scnt) { simplexes[scnt] = simplexes[j]; }
604 for (std::vector<size_type>::iterator it = simplexes[scnt].inodes.begin();
605 it != simplexes[scnt].inodes.end(); ++it) {
609 simplexes.resize(scnt);
612 void mesh_slicer::update_nodes_index() {
614 for (dal::bv_visitor j(simplex_index); !j.finished(); ++j) {
615 assert(j < simplexes.size());
616 for (std::vector<size_type>::iterator it = simplexes[j].inodes.begin();
617 it != simplexes[j].inodes.end(); ++it) {
618 assert(*it < nodes.size());
619 nodes_index.add(*it);
624 static void flag_points_on_faces(
const bgeot::pconvex_ref& cvr,
625 const std::vector<base_node>& pts,
626 std::vector<slice_node::faces_ct>& faces) {
627 GMM_ASSERT1(cvr->structure()->nb_faces() <= 32,
628 "won't work for convexes with more than 32 faces "
629 "(hardcoded limit)");
630 faces.resize(pts.size());
631 for (
size_type i=0; i < pts.size(); ++i) {
633 for (
short_type f=0; f < cvr->structure()->nb_faces(); ++f)
634 faces[i][f] = (gmm::abs(cvr->is_in_face(f, pts[i])) < 1e-10);
641 pgt = m.trans_of_convex(cv);
642 prev_cvr = cvr; cvr = pgt->convex_ref();
643 cv_dim = cvr->structure()->dim();
644 cv_nbfaces = cvr->structure()->nb_faces();
645 fcnt = cvr->structure()->nb_faces();
646 discont = (mls && mls->is_convex_cut(cv));
649 void mesh_slicer::apply_slicers() {
650 simplex_index.clear(); simplex_index.add(0, simplexes.size());
651 splx_in = simplex_index;
652 nodes_index.clear(); nodes_index.add(0, nodes.size());
653 for (
size_type i=0; i < action.size(); ++i) {
654 action[i]->exec(*
this);
656 assert(simplex_index.contains(splx_in));
660 void mesh_slicer::simplex_orientation(slice_simplex& s) {
665 base_small_vector d = nodes[s.inodes[i]].pt - nodes[s.inodes[0]].pt;
666 gmm::copy_n(d.const_begin(), N, M.begin() + (i-1)*N);
668 scalar_type J = bgeot::lu_det(&(*(M.begin())), N);
671 std::swap(s.inodes[1],s.inodes[0]);
683 exec_(&nrefine[0], 1, cvlst);
688 if (pgt->dim() == m.dim() && m.dim()>=2) {
690 base_matrix G; bgeot::vectors_to_base_matrix(G,m.points_of_convex(cv));
691 base_node g(pgt->dim()); g.fill(.5);
692 base_matrix pc; pgt->poly_vector_grad(g,pc);
693 base_matrix K(pgt->dim(),pgt->dim());
695 scalar_type J = bgeot::lu_det(&(*(K.begin())), pgt->dim());
698 if (J < 0)
return true;
705 void mesh_slicer::exec_(
const short_type *pnrefine,
int nref_stride,
706 const mesh_region& cvlst) {
707 std::vector<base_node> cvm_pts;
708 const bgeot::basic_mesh *cvm = 0;
711 bgeot::pgeotrans_precomp pgp = 0;
712 std::vector<slice_node::faces_ct> points_on_faces;
716 for (mr_visitor it(cvlst); !it.finished(); ++it) {
717 size_type nrefine = pnrefine[it.cv()*nref_stride];
718 update_cv_data(it.cv(),it.f());
719 bool revert_orientation = check_orient(cv, pgt,m);
722 if (prev_cvr != cvr || nrefine != prev_nrefine) {
724 cvm_pts.resize(cvm->points().card());
725 std::copy(cvm->points().begin(), cvm->points().end(), cvm_pts.begin());
726 pgp = gppool(pgt, store_point_tab(cvm_pts));
727 flag_points_on_faces(cvr, cvm_pts, points_on_faces);
728 prev_nrefine = nrefine;
730 if (face < dim_type(-1))
736 std::vector<size_type> ptsid(cvm_pts.size()); std::fill(ptsid.begin(), ptsid.end(),
size_type(-1));
744 if (revert_orientation) std::swap(simplexes[snum].inodes[0],simplexes[snum].inodes[1]);
746 for (std::vector<size_type>::iterator itp = simplexes[snum].inodes.begin();
747 itp != simplexes[snum].inodes.end(); ++itp) {
749 ptsid[*itp] = nodes.size();
750 nodes.push_back(slice_node());
751 nodes.back().pt_ref = cvm_pts[*itp];
752 nodes.back().faces = points_on_faces[*itp];
753 nodes.back().pt.resize(m.dim()); nodes.back().pt.fill(0.);
754 pgp->transform(m.points_of_convex(cv), *itp, nodes.back().pt);
761 cout <<
"check orient cv " << cv <<
", snum=" << snum <<
"/" << cvms->
nb_convex();
763 simplex_orientation(simplexes[snum]);
771 template <
typename CONT>
774 unsigned N = pgt->dim();
775 std::vector<base_node> v; v.reserve(N+1);
776 for (
unsigned i=0; i < pgt->nb_points(); ++i) {
777 const base_node P = pgt->convex_ref()->points()[i];
779 for (
unsigned j=0; j < N; ++j) {
780 s += P[j];
if (P[j] == 1) { v.push_back(pts[i]);
break; }
782 if (s == 0) v.push_back(pts[i]);
784 assert(v.size() == N+1);
785 base_node G = gmm::mean_value(v);
788 m.add_convex_by_points(bgeot::simplex_geotrans(N,1), v.begin());
791 const mesh& mesh_slicer::refined_simplex_mesh_for_convex_cut_by_level_set
792 (
const mesh &cvm,
unsigned nrefine) {
793 mesh mm; mm.copy_from(cvm);
794 while (nrefine > 1) {
795 mm.Bank_refine(mm.convex_index());
799 std::vector<size_type> idx;
802 for (dal::bv_visitor_c ic(mm.convex_index()); !ic.finished(); ++ic) {
803 add_degree1_convex(mm.trans_of_convex(ic), mm.points_of_convex(ic), tmp_mesh);
811 mesh_slicer::refined_simplex_mesh_for_convex_faces_cut_by_level_set
813 mesh &cvm = tmp_mesh;
814 tmp_mesh_struct.
clear();
815 unsigned N = cvm.dim();
817 dal::bit_vector pt_in_face; pt_in_face.sup(0, cvm.points().index().last_true()+1);
818 for (dal::bv_visitor ip(cvm.points().index()); !ip.finished(); ++ip)
819 if (gmm::abs(cvr->is_in_face(
short_type(f), cvm.points()[ip]))) pt_in_face.add(ip);
821 for (dal::bv_visitor_c ic(cvm.convex_index()); !ic.finished(); ++ic) {
822 for (
short_type ff=0; ff < cvm.nb_faces_of_convex(ic); ++ff) {
824 for (
unsigned i=0; i < N; ++i) {
825 if (!pt_in_face.is_in(cvm.ind_points_of_face_of_convex(ic,ff)[i])) {
826 face_ok =
false;
break;
831 cvm.ind_points_of_face_of_convex(ic, ff).begin());
835 return tmp_mesh_struct;
838 void mesh_slicer::exec_(
const short_type *pnrefine,
840 const mesh_region& cvlst) {
841 std::vector<base_node> cvm_pts;
842 const bgeot::basic_mesh *cvm = 0;
845 bgeot::pgeotrans_precomp pgp = 0;
846 std::vector<slice_node::faces_ct> points_on_faces;
847 bool prev_discont =
true;
852 for (mr_visitor it(cvlst); !it.finished(); ++it) {
853 size_type nrefine = pnrefine[it.cv()*nref_stride];
854 update_cv_data(it.cv(),it.f());
855 bool revert_orientation = check_orient(cv, pgt,m);
859 if (prev_cvr != cvr || nrefine != prev_nrefine
860 || discont || prev_discont) {
862 cvm = &refined_simplex_mesh_for_convex_cut_by_level_set
863 (mls->mesh_of_convex(cv),
unsigned(nrefine));
867 cvm_pts.resize(cvm->points().card());
868 std::copy(cvm->points().begin(), cvm->points().end(), cvm_pts.begin());
869 pgp = gppool(pgt, store_point_tab(cvm_pts));
870 flag_points_on_faces(cvr, cvm_pts, points_on_faces);
871 prev_nrefine = nrefine;
873 if (face < dim_type(-1)) {
878 cvms = &refined_simplex_mesh_for_convex_faces_cut_by_level_set(face);
885 std::vector<size_type> ptsid(cvm_pts.size()); std::fill(ptsid.begin(), ptsid.end(),
size_type(-1));
895 if (revert_orientation) std::swap(simplexes[snum].inodes[0],simplexes[snum].inodes[1]);
898 G.resize(m.dim()); G.fill(0.);
899 for (std::vector<size_type>::iterator itp =
900 simplexes[snum].inodes.begin();
901 itp != simplexes[snum].inodes.end(); ++itp) {
904 G /= scalar_type(simplexes[snum].inodes.size());
907 for (std::vector<size_type>::iterator itp =
908 simplexes[snum].inodes.begin();
909 itp != simplexes[snum].inodes.end(); ++itp) {
910 if (discont || ptsid[*itp] ==
size_type(-1)) {
911 ptsid[*itp] = nodes.size();
912 nodes.push_back(slice_node());
914 nodes.back().pt_ref = cvm_pts[*itp];
920 nodes.back().pt_ref = cvm_pts[*itp] + 0.01*(G - cvm_pts[*itp]);
922 nodes.back().faces = points_on_faces[*itp];
923 nodes.back().pt.resize(m.dim()); nodes.back().pt.fill(0.);
924 pgp->transform(m.points_of_convex(cv), *itp, nodes.back().pt);
935 prev_discont = discont;
941 exec(nrefine,mesh_region(m.convex_index()));
946 GMM_ASSERT1(&sl.
linked_mesh() == &m,
"wrong mesh");
947 for (stored_mesh_slice::cvlst_ct::const_iterator it = sl.cvlst.begin(); it != sl.cvlst.end(); ++it) {
948 update_cv_data((*it).cv_num);
950 simplexes = (*it).simplexes;
961 for (dal::bv_visitor ic(m.convex_index()); !ic.finished(); ++ic) {
965 nodes.resize(0); simplexes.resize(0);
969 nodes.push_back(slice_node(pts[itab[i]],ptab[i])); nodes.back().faces=0;
970 slice_simplex s(1); s.inodes[0] = nodes.size()-1;
971 simplexes.push_back(s);
978 slicer_half_space::test_point(
const base_node& P,
bool& in,
bool& bound)
const {
979 scalar_type s = gmm::vect_sp(P - x0, n);
980 in = (s <= 0); bound = (s * s <= EPS);
987 const mesh_slicer::cs_nodes_ct& nodes)
const {
988 const base_node& A = nodes[iA].pt;
989 const base_node& B = nodes[iB].pt;
990 scalar_type s1 = 0., s2 = 0.;
991 for (
unsigned i = 0; i < A.size(); ++i) {
992 s1 += (A[i] - B[i]) * n[i]; s2 += (A[i] - x0[i]) * n[i];
994 if (gmm::abs(s1) < EPS)
1001 slicer_sphere::test_point(
const base_node& P,
bool& in,
bool& bound)
const {
1003 bound = (R2 >= (1-EPS)*R*R && R2 <= (1+EPS)*R*R);
1009 const mesh_slicer::cs_nodes_ct& nodes)
const {
1010 const base_node& A=nodes[iA].pt;
1011 const base_node& B=nodes[iB].pt;
1015 return pt_bin.is_in(iA) ? 0. : 1./EPS;
1022 slicer_cylinder::test_point(
const base_node& P,
bool& in,
bool& bound)
const {
1029 bound = gmm::abs(dist2-R*R) < EPS;
1035 const mesh_slicer::cs_nodes_ct& nodes)
const {
1036 base_node F=nodes[iA].pt;
1037 base_node D=nodes[iB].pt-nodes[iA].pt;
1038 if (2 == F.size()) {
1047 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.