How to Interpolate a 3D MeshRegion?

A very simple method is by interpolating the signed distance function (SignedRegionDistance) of a BoundaryMeshRegion. Therefore, I use BoundaryDiscretizeGraphics instead of DiscretizeGraphics to produce a BoundaryMeshRegion called S. Afterwards, I sample SignedRegionDistance on a regular grid surrounding S and apply Interpolation. This uses bi-cubic splines per default. Of course any other interpolation/approximation technique can be used, for example, trigonometric polynomials, radial basis functions etc.

S = BoundaryDiscretizeGraphics@
   RegionPlot3D[R, 
    PlotRange -> {{-1.5, 1.5}, {-1.5, 1.5}, {-1.6, 1.6}}, 
    PlotPoints -> 50, Boxed -> False];

box = List @@ BoundingRegion[S];
center = Mean[box];
scale = 1.5;
B = Cuboid @@ ({center, center} + scale (box - {center, center}));
n = 20;
nodes = Tuples[Subdivide[#[[1]], #[[2]], n] & /@ Transpose[List @@ B]];
df = SignedRegionDistance[S];
f = Interpolation[Transpose[{nodes, df[nodes]}]];

Show[
 S,
 SliceContourPlot3D[f[x, y, z], "CenterPlanes", {x, y, z} \[Element] B]
 ]

enter image description here

And here is a contourplot of the interpolated signed distance function:

ContourPlot3D[
 f[x, y, z] == 0, 
 {x, B[[1, 1]], B[[2, 1]]}, {y, B[[1, 2]], B[[2, 2]]}, {z, B[[1, 3]], B[[2, 3]]}
 ]

enter image description here

A rediscretized region looks like this:

R1 = ImplicitRegion[
   f[x, y, z] <= 0, 
   {{x, B[[1, 1]], B[[2, 1]]}, {y, B[[1, 2]], B[[2, 2]]}, {z, B[[1, 3]], B[[2, 3]]}}
   ];
S1 = BoundaryDiscretizeRegion[R1, MaxCellMeasure -> {1 -> 0.1}];
GraphicsRow[{Show[S], Show[S1]}]

enter image description here

(left: original region; right: rediscretized region)


In my attempt I try to realize a very simple signed distance function which only needs information about the meshregion r(assumption: triangle mesh in space)

points = MeshCoordinates[ r]  ;
elements = MeshCells[r, 2]  ; (* all triangle elements *) 
triangles = elements /. Polygon -> List // Flatten[#, 1] &;(* node indices*)

Furthermore I use/presume a function, which detects the nearest element of a given point.

mnc = Region`Mesh`MeshNearestCellIndex[r ] 
(*mnc[x,y,z] evaluates the index of nearest element*)

The following interpolation idea doesn't need an embedding grid, uses only the given nodes and calculates the signed distance in normal element direction. Because it only considers the nearest element it's some kind of one dimensional interpolation

fUN[x_?NumericQ, y_?NumericQ, z_?NumericQ] := Block[{n\[CapitalDelta], no, p1, p2,p3},
n\[CapitalDelta] = mnc[{x, y, z}][[2]];  (*nearest triangle element *)
{p1, p2, p3} = punkte[[dreiecke[[n\[CapitalDelta] ]]]];(* triangle points*)
no = Cross[p2 - p1, p3 - p1 ];(* normal vector triangle *)
no.({x, y, z} - p1)(* normal distance*)

]

If fUN returns zero the point x,y,z is element of the triangle plane.

RUN = ImplicitRegion[fUN[x, y, z] == 0, {{x, -1.5, 1.5}, {y, -1.5, 1.5}, {z, -1.6,1.6}}] (* interpolated region R*)

DiscretizeRegion[RUN]

enter image description here

The program seems to work quite well (no idea where the sliver comes from...)

Function fUN might be improved checking x,y,z inside triangle and using compile!