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.