5
$\begingroup$

Given a surface region (MesgRegion netz2D), for example

bild = RegionPlot3D[x^2 + y^2 + z^2 <= 1, {x, 0, 1}, {y, 0, 1}, {z, 0, 1}, Mesh -> All];
netz2D = DiscretizeGraphics [bild]  (* mesh region*)
RegionDimension[netz2D] (*2*)

enter image description here

Question: How to mesh the volume defined by the meshregion netz2D? Thanks!

$\endgroup$

3 Answers 3

6
$\begingroup$

I expect the following to work only in a few cases. It works here.

Extract the polygons and re-make them into a BoundaryMeshRegion:

bm = BoundaryMeshRegion[MeshCoordinates[netz2D], MeshCells[netz2D, 2]]

Then you can triangulate the interior:

TriangulateMesh[bm]

A better way to achieve the same would have been:

BoundaryDiscretizeRegion@ImplicitRegion[x^2 + y^2 + z^2 <= 1, {{x, 0, 1}, {y, 0, 1}, {z, 0, 1}}]

The important thing is to keep surface meshes as BoundaryMeshRegions, not as MeshRegions. This way we maintain information about the interior.

$\endgroup$
9
  • $\begingroup$ Thank you for your answer, I'll test it. Does BoundaryMeshRegion always create a closed surface? $\endgroup$ Commented Feb 16, 2019 at 10:40
  • $\begingroup$ @UlrichNeumann Yes, I believe that is the point. For this to work, all the polygons must be oriented the same way, and they should share vertices and edges. Otherwise the construction will fail. $\endgroup$
    – Szabolcs
    Commented Feb 16, 2019 at 10:47
  • $\begingroup$ @ Szabolcs I tried to reproduce your suggestions but didn't succeed. MMA 11.0.1 cann't evaluate Volume[bm] and RegionEmbeddingDimension[bm] . Any idea? Thanks! $\endgroup$ Commented Feb 17, 2019 at 14:23
  • $\begingroup$ Seems to work here ... i.sstatic.net/iklAs.png ... what did you try exactly? Also work with the bm obtained using the first code line in my post. $\endgroup$
    – Szabolcs
    Commented Feb 17, 2019 at 14:36
  • $\begingroup$ Thanks for the quick answer. I tried the first two code lines of your answer (based on netz2D) $\endgroup$ Commented Feb 17, 2019 at 14:38
4
$\begingroup$
bild2 = DiscretizeRegion[ImplicitRegion[x^2 + y^2 + z^2 <= 1, 
  {{x, 0, 1}, {y, 0, 1}, {z, 0, 1}}], 
  MeshCellStyle -> {{2, All} -> Opacity[.5]}]

enter image description here

RegionDimension[bild2]

3

$\endgroup$
4
$\begingroup$

Depending a bit on what you want to do you could use the FEM mesh, that can be made more accurate than a DiscretizeRegion approach.

Needs["NDSolve`FEM`"]
reg = ImplicitRegion[
   x^2 + y^2 + z^2 <= 1, {{x, 0, 1}, {y, 0, 1}, {z, 0, 1}}];
bild2 = ToElementMesh[reg, "ImproveBoundaryPosition" -> True];
vol = \[Pi]/6;
vol - Total[bild2["MeshElementMeasure"], 2]
6.633774715880669`*^-6
vol - RegionMeasure[DiscretizeRegion[reg]]
0.0004287579660063878`

For 3D the Automatic setting for "ImproveBoundaryPosition" is False (for 2D it is True) and with this improved boundary you get a much more accurate representation of the region. This is useful if you want to numerically solve PDEs or integrate over the region.

Also note that the workflow for ElementMesh is more intuitive as the boundary mesh can be made to a full mesh:

bmesh = ToBoundaryMesh[reg];
ToElementMesh[bmesh];

If you want the same accuracy as above you'd use ToNumericalRegion to connect the region and the boundary mesh.

You can think of a BoundaryMeshRegion as a sparse representation of a full region. A boundary element mesh is different; it is a representation of the boundary of the region. As a consequence you can do this:

bmesh = ToBoundaryMesh[Circle[{0, 0}, 1, {Pi/6, 3 Pi/4}]];

NIntegrate[1, Element[{x, y}, bmesh]]
1.8323249230952223`

But not this:

ToElementMesh[bmesh]
$Failed

Note that if the boundary is closed

bmesh = ToBoundaryMesh[Circle[{0, 0}, 1]];

Then ToElementMesh will generate a full mesh.

Head[ToElementMesh[bmesh]]
ElementMesh

To get to your question, that's why this works:

ToElementMesh[RegionBoundary[netz2D]]

bild2 = ToElementMesh[
   ImplicitRegion[
    x^2 + y^2 + z^2 <= 1, {{x, 0, 1}, {y, 0, 1}, {z, 0, 1}}]];

Look at the wire frame of the surface elements:

bild2["Wireframe"]

enter image description here

Look at the wire frame of the full mesh:

bild2["Wireframe"["MeshElement" -> "MeshElements"]]

enter image description here Or if you want a MeshRegion:

MeshRegion[ToElementMesh[RegionBoundary[netz2D], "MeshOrder" -> 1]]
$\endgroup$
5
  • $\begingroup$ @ user21 :Thank you very much for your detailed answer. In my special problem I tried to create a "volumemesh" from the surfacepoints which I got from RegionPlot3D. Just one question: bild2seems to be a 3D-mesh, but bild2["Wireframe"] only shows surface elements? $\endgroup$ Commented Feb 20, 2019 at 10:02
  • $\begingroup$ @UlrichNeumann, added an example that show how to get the full wire frame mesh. $\endgroup$
    – user21
    Commented Feb 20, 2019 at 10:10
  • $\begingroup$ @ user21 Tricky, where did you find the options "Wireframe"["MeshElement" -> "MeshElements"] of "Wireframe"? $\endgroup$ Commented Feb 20, 2019 at 10:33
  • 1
    $\begingroup$ @UlrichNeumann, you can find such information in the ElementMesh visualization tutorial $\endgroup$
    – user21
    Commented Feb 20, 2019 at 10:44
  • $\begingroup$ Thanks for your support! $\endgroup$ Commented Feb 20, 2019 at 10:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.