24 #if defined(HAVE_MESH)
35 for(
auto gf :
l_faces) gf->delRegion(
this);
48 for(std::size_t i = 0; i <
prisms.size(); i++)
delete prisms[i];
87 for(std::size_t i = 0; i <
polyhedra.size(); i++)
112 if(
prisms.empty())
return nullptr;
115 if(
pyramids.empty())
return nullptr;
118 if(
trihedra.empty())
return nullptr;
152 const std::size_t index)
const
184 res += gf->bounds(fast);
198 std::vector<GFace *> b_faces =
faces();
199 for(
auto b_face = b_faces.begin(); b_face != b_faces.end(); b_face++) {
200 if((*b_face)->getNumMeshVertices() > 0) {
201 int N = (*b_face)->getNumMeshVertices();
202 for(
int i = 0; i < N; i++) {
203 MVertex *mv = (*b_face)->getMeshVertex(i);
206 std::vector<GEdge *> eds = (*b_face)->edges();
207 for(
auto ed = eds.begin(); ed != eds.end(); ed++) {
208 int N2 = (*ed)->getNumMeshVertices();
209 for(
int i = 0; i < N2; i++) {
210 MVertex *mv = (*ed)->getMeshVertex(i);
214 if((*ed)->getBeginVertex()) {
215 SPoint3 pt1((*ed)->getBeginVertex()->x(),
216 (*ed)->getBeginVertex()->y(),
217 (*ed)->getBeginVertex()->z());
220 if((*ed)->getEndVertex()) {
221 SPoint3 pt2((*ed)->getEndVertex()->x(), (*ed)->getEndVertex()->y(),
222 (*ed)->getEndVertex()->z());
227 else if((*b_face)->buildSTLTriangulation()) {
228 vertices = (*b_face)->stl_vertices_xyz;
232 std::vector<GEdge *> b_edges = (*b_face)->edges();
233 for(
auto b_edge = b_edges.begin(); b_edge != b_edges.end(); b_edge++) {
235 for(
int j = 0; j < N; j++) {
237 tr.
low() + (double)j / (
double)(N - 1) * (tr.
high() - tr.
low());
238 GPoint p = (*b_edge)->point(t);
254 for(
auto f :
l_faces)
f->setVisibility(val, recursive);
265 for(
auto f :
l_faces)
f->setColor(val, recursive);
274 const auto found = std::find(
l_faces.begin(),
l_faces.end(), face);
280 if(
l_dirs.empty()) {
return 0; }
282 if(
l_dirs.size() <
static_cast<std::size_t
>(pos)) {
287 const auto orientation =
l_dirs.at(pos);
296 for(
auto it = tagFaces.begin(); it != tagFaces.end(); ++it) {
311 const std::vector<int> &signFaces)
313 if(tagFaces.size() != signFaces.size()) {
314 Msg::Error(
"Wrong number of surface signs in volume %d",
tag());
316 tags.insert(tagFaces.begin(), tagFaces.end());
319 for(std::size_t i = 0; i != tagFaces.size(); i++) {
325 l_dirs.push_back(signFaces[i]);
329 Msg::Error(
"Unknown surface %d in volume %d", tagFaces[i],
tag());
336 std::ostringstream sstream;
338 sstream <<
"Boundary surfaces: ";
340 if(it !=
l_faces.begin()) sstream <<
", ";
341 sstream << (*it)->tag();
349 sstream <<
"Embedded surfaces: ";
352 sstream << (*it)->tag();
360 sstream <<
"Embedded curves: ";
363 sstream << (*it)->tag();
371 sstream <<
"Embedded points: ";
375 sstream << (*it)->tag();
385 sstream <<
"Mesh attributes:";
388 sstream <<
" extruded";
391 std::string str = sstream.str();
392 if(str.size() && (str[str.size() - 1] ==
'\n' || str[str.size() - 1] ==
' '))
393 str.resize(str.size() - 1);
402 fprintf(fp,
"Surface Loop(%d) = ",
tag());
405 fprintf(fp,
", %d", (*it)->tag());
407 fprintf(fp,
"{%d", (*it)->tag());
410 fprintf(fp,
"Volume(%d) = {%d};\n",
tag(),
tag());
414 fprintf(fp,
"Surface {%d} In Volume {%d};\n", (*it)->tag(),
tag());
417 fprintf(fp,
"Line {%d} In Volume {%d};\n", (*it)->tag(),
tag());
420 fprintf(fp,
"Point {%d} In Volume {%d};\n", (*it)->tag(),
tag());
423 fprintf(fp,
"Transfinite Volume {%d}",
tag());
427 if(i) fprintf(fp,
",");
435 fprintf(fp,
"TransfQuadTri {%d};\n",
tag());
449 fprintf(fp,
"gmsh.model.%s.addSurfaceLoop([", factory);
451 if(it !=
l_faces.begin()) fprintf(fp,
", ");
452 fprintf(fp,
"%d", (*it)->tag());
454 fprintf(fp,
"], %d)\n",
tag());
455 fprintf(fp,
"gmsh.model.%s.addVolume(%d, %d)\n", factory,
tag(),
tag());
461 static std::vector<GEdge *> e;
464 for(
auto *
const face :
l_faces) {
465 for(
auto *
const edge : face->edges()) {
466 if(std::find(e.begin(), e.end(), edge) == e.end()) { e.push_back(edge); }
474 std::vector<GEdge *> e =
edges(), e2 = r->
edges();
477 while(it != e.end()) {
478 if(std::find(e2.begin(), e2.end(), *it) != e2.end())
return true;
485 std::vector<double> inertia)
488 auto itdir =
l_dirs.begin();
493 cg[0] = cg[1] = cg[2] = 0.0;
494 for(; it !=
l_faces.end(); ++it, ++itdir) {
495 for(std::size_t i = 0; i < (*it)->triangles.size(); ++i) {
501 for(
int j = 0; j < npt; j++) {
504 e->
pnt(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], pt);
508 e->
getJacobian(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], jac);
509 SVector3 n(jac[2][0], jac[2][1], jac[2][2]);
512 surface += detJ * pts[j].
weight;
513 volumex += detJ * n.
x() * pt.x() * pts[j].
weight;
514 volumey += detJ * n.
y() * pt.y() * pts[j].
weight;
515 volumez += detJ * n.
z() * pt.z() * pts[j].
weight;
516 cg[0] += detJ * n.
x() * (pt.x() * pt.x()) * pts[j].weight * 0.5;
517 cg[1] += detJ * n.
y() * (pt.y() * pt.y()) * pts[j].weight * 0.5;
518 cg[2] += detJ * n.
z() * (pt.z() * pt.z()) * pts[j].weight * 0.5;
523 printf(
"%g -- %g %g %g\n", surface, volumex, volumey, volumez);
525 double volume = volumex;
533 inertia[0] = inertia[1] = inertia[2] = inertia[3] = inertia[4] = inertia[5] =
536 for(; it !=
l_faces.end(); ++it, ++itdir) {
537 for(std::size_t i = 0; i < (*it)->getNumMeshElements(); ++i) {
538 MElement *e = (*it)->getMeshElement(i);
543 for(
int j = 0; j < npt; j++) {
546 e->
pnt(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], pt);
550 e->
getJacobian(pts[j].pt[0], pts[j].pt[1], pts[j].pt[2], jac);
551 SVector3 n(jac[2][0], jac[2][1], jac[2][2]);
553 inertia[0] += pts[j].
weight * detJ * n.
x() * (pt.x() - cg[0]) *
554 (pt.x() - cg[0]) * (pt.x() - cg[0]) / 3.0;
555 inertia[1] += pts[j].
weight * detJ * n.
y() * (pt.y() - cg[1]) *
556 (pt.y() - cg[1]) * (pt.y() - cg[1]) / 3.0;
557 inertia[2] += pts[j].
weight * detJ * n.
z() * (pt.z() - cg[2]) *
558 (pt.z() - cg[2]) * (pt.z() - cg[2]) / 3.0;
559 inertia[3] += pts[j].
weight * detJ * n.
x() * (pt.y() - cg[1]) *
560 (pt.x() - cg[0]) * (pt.x() - cg[0]) / 3.0;
561 inertia[4] += pts[j].
weight * detJ * n.
x() * (pt.z() - cg[2]) *
562 (pt.x() - cg[0]) * (pt.x() - cg[0]) / 3.0;
563 inertia[5] += pts[j].
weight * detJ * n.
y() * (pt.z() - cg[2]) *
564 (pt.y() - cg[1]) * (pt.y() - cg[1]) / 3.0;
573 std::set<MVertex *> tmp;
575 tmp.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
576 std::vector<GEdge *> ed = (*it)->edges();
577 for(
auto it2 = ed.begin(); it2 != ed.end(); it2++) {
578 tmp.insert((*it2)->mesh_vertices.begin(), (*it2)->mesh_vertices.end());
579 if((*it2)->getBeginVertex())
580 tmp.insert((*it2)->getBeginVertex()->mesh_vertices.begin(),
581 (*it2)->getBeginVertex()->mesh_vertices.end());
582 if((*it2)->getEndVertex())
583 tmp.insert((*it2)->getEndVertex()->mesh_vertices.begin(),
584 (*it2)->getEndVertex()->mesh_vertices.end());
588 tmp.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
589 if((*it)->getBeginVertex())
590 tmp.insert((*it)->getBeginVertex()->mesh_vertices.begin(),
591 (*it)->getBeginVertex()->mesh_vertices.end());
592 if((*it)->getEndVertex())
593 tmp.insert((*it)->getEndVertex()->mesh_vertices.begin(),
594 (*it)->getEndVertex()->mesh_vertices.end());
598 tmp.insert((*it)->mesh_vertices.begin(), (*it)->mesh_vertices.end());
600 return std::vector<MVertex *>(tmp.begin(), tmp.end());
605 std::set<GVertex *, GEntityPtrLessThan> v;
607 std::vector<GVertex *>
const &vs = gf->vertices();
608 v.insert(vs.begin(), vs.end());
610 return std::vector<GVertex *>(v.begin(), v.end());
623 Msg::Error(
"Trying to add unsupported element in volume %d",
tag());
661 Msg::Error(
"Trying to remove unsupported element in volume %d",
tag());
675 Msg::Error(
"Trying to remove unsupported elements in volume %d",
tag());
680 const std::vector<std::size_t> &ordering)
683 if(
tetrahedra.front()->getTypeForMSH() == elementType) {
684 if(ordering.size() !=
tetrahedra.size())
return false;
686 for(
auto it = ordering.begin(); it != ordering.end(); ++it) {
690 std::vector<MTetrahedron *> newTetrahedraOrder(
tetrahedra.size());
691 for(std::size_t i = 0; i < ordering.size(); i++) {
692 newTetrahedraOrder[i] =
tetrahedra[ordering[i]];
700 if(
hexahedra.front()->getTypeForMSH() == elementType) {
701 if(ordering.size() !=
hexahedra.size())
return false;
703 for(
auto it = ordering.begin(); it != ordering.end(); ++it) {
704 if(*it >=
hexahedra.size())
return false;
707 std::vector<MHexahedron *> newHexahedraOrder(
hexahedra.size());
708 for(std::size_t i = 0; i < ordering.size(); i++) {
709 newHexahedraOrder[i] =
hexahedra[ordering[i]];
711 hexahedra = std::move(newHexahedraOrder);
717 if(
prisms.front()->getTypeForMSH() == elementType) {
718 if(ordering.size() !=
prisms.size())
return false;
720 for(
auto it = ordering.begin(); it != ordering.end(); ++it) {
721 if(*it >=
prisms.size())
return false;
724 std::vector<MPrism *> newPrismsOrder(
prisms.size());
725 for(std::size_t i = 0; i < ordering.size(); i++) {
726 newPrismsOrder[i] =
prisms[ordering[i]];
728 prisms = std::move(newPrismsOrder);
734 if(
pyramids.front()->getTypeForMSH() == elementType) {
735 if(ordering.size() !=
pyramids.size())
return false;
737 for(
auto it = ordering.begin(); it != ordering.end(); ++it) {
738 if(*it >=
pyramids.size())
return false;
741 std::vector<MPyramid *> newPyramidsOrder(
pyramids.size());
742 for(std::size_t i = 0; i < ordering.size(); i++) {
743 newPyramidsOrder[i] =
pyramids[ordering[i]];
745 pyramids = std::move(newPyramidsOrder);
751 if(
polyhedra.front()->getTypeForMSH() == elementType) {
752 if(ordering.size() !=
polyhedra.size())
return false;
754 for(
auto it = ordering.begin(); it != ordering.end(); ++it) {
755 if(*it >=
polyhedra.size())
return false;
758 std::vector<MPolyhedron *> newPolyhedraOrder(
polyhedra.size());
759 for(std::size_t i = 0; i < ordering.size(); i++) {
760 newPolyhedraOrder[i] =
polyhedra[ordering[i]];
762 polyhedra = std::move(newPolyhedraOrder);
768 if(
trihedra.front()->getTypeForMSH() == elementType) {
769 if(ordering.size() !=
trihedra.size())
return false;
771 for(
auto it = ordering.begin(); it != ordering.end(); ++it) {
772 if(*it >=
trihedra.size())
return false;
775 std::vector<MTrihedron *> newTrihedraOrder(
trihedra.size());
776 for(std::size_t i = 0; i < ordering.size(); i++) {
777 newTrihedraOrder[i] =
trihedra[ordering[i]];
779 trihedra = std::move(newTrihedraOrder);
789 for(
int i = 0; i < 6; i++)
790 r[i] = 0.0001 * ((
double)rand() / (
double)RAND_MAX);
798 double P[3],
double N[3],
799 const double eps_prec)
801 double mat[3][3], det;
804 mat[0][0] = X[1] - X[0];
805 mat[0][1] = X[2] - X[0];
808 mat[1][0] = Y[1] - Y[0];
809 mat[1][1] = Y[2] - Y[0];
812 mat[2][0] = Z[1] - Z[0];
813 mat[2][1] = Z[2] - Z[0];
821 if(res[0] >= eps_prec && res[0] <= 1.0 - eps_prec && res[1] >= eps_prec &&
822 res[1] <= 1.0 - eps_prec && 1 - res[0] - res[1] >= eps_prec &&
823 1 - res[0] - res[1] <= 1.0 - eps_prec) {
825 return (res[2] > 0) ? 1 : 0;
827 else if(res[0] < -eps_prec || res[0] > 1.0 + eps_prec || res[1] < -eps_prec ||
828 res[1] > 1.0 + eps_prec || 1 - res[0] - res[1] < -eps_prec ||
829 1 - res[0] - res[1] > 1.0 + eps_prec) {
845 Msg::Warning(
"Bad scaling in GRegion::setOutwardOrientationMeshConstraint");
851 std::vector<GFace *>
f =
faces();
853 while(it !=
f.end()) {
857 Msg::Warning(
"No valid STL triangulation found for surface %d - skipping "
858 "outward orientation constraint for volume %d",
862 int nb_intersect = 0;
863 for(std::size_t i = 0; i < gf->
stl_triangles.size(); i += 3) {
867 double X[3] = {p1.
x(), p2.
x(), p3.
x()};
868 double Y[3] = {p1.
y(), p2.
y(), p3.
y()};
869 double Z[3] = {p1.
z(), p2.
z(), p3.
z()};
870 for(
int j = 0; j < 3; j++) {
875 double P[3] = {(X[0] + X[1] + X[2]) / 3., (Y[0] + Y[1] + Y[2]) / 3.,
876 (Z[0] + Z[1] + Z[2]) / 3.};
877 double v1[3] = {X[0] - X[1], Y[0] - Y[1], Z[0] - Z[1]};
878 double v2[3] = {X[2] - X[1], Y[2] - Y[1], Z[2] - Z[1]};
884 N[0] += rrr[0] * v1[0] + rrr[1] * v2[0];
885 N[1] += rrr[2] * v1[1] + rrr[3] * v2[1];
886 N[2] += rrr[4] * v1[2] + rrr[5] * v2[2];
888 auto it_b =
f.begin();
889 while(it_b !=
f.end()) {
890 GFace *gf_b = (*it_b);
893 for(std::size_t i_b = 0; i_b < gf_b->
stl_triangles.size(); i_b += 3) {
897 double X_b[3] = {p1.
x(), p2.
x(), p3.
x()};
898 double Y_b[3] = {p1.
y(), p2.
y(), p3.
y()};
899 double Z_b[3] = {p1.
z(), p2.
z(), p3.
z()};
900 for(
int j = 0; j < 3; j++) {
905 if(!(std::abs(X[0] - X_b[0]) < 1e-12 &&
906 std::abs(X[1] - X_b[1]) < 1e-12 &&
907 std::abs(X[2] - X_b[2]) < 1e-12 &&
908 std::abs(Y[0] - Y_b[0]) < 1e-12 &&
909 std::abs(Y[1] - Y_b[1]) < 1e-12 &&
910 std::abs(Y[2] - Y_b[2]) < 1e-12 &&
911 std::abs(Z[0] - Z_b[0]) < 1e-12 &&
912 std::abs(Z[1] - Z_b[1]) < 1e-12 &&
913 std::abs(Z[2] - Z_b[2]) < 1e-12)) {
915 nb_intersect += inters;
922 if(nb_intersect >= 0)
926 if(nb_intersect < 0) {
setRand(rrr); }
928 if(nb_intersect % 2 == 1) {
931 Msg::Info(
"Setting reverse mesh attribute on surface %d", gf->
tag());
936 #if defined(HAVE_MESH)
952 std::vector<GFace *>
f =
faces();
953 for(std::size_t i = 0; i <
f.size(); i++) {
956 if(
df &&
df->haveParametrization())
return false;
958 std::vector<GEdge *> e =
edges();
959 for(std::size_t i = 0; i < e.size(); i++) {
962 if(de && de->haveParametrization())
return false;