I am trying to visualize a percolation model that is equivalent to a swiss-cheese where the holes are conducting. At some point, the size of the holes gets large enough for them to touch and a percolating network of holes pervades the sample volume. I would like to visualize the percolated network of holes in a transparent body. I can´t seem to make it work so that i have a nicely rendered inner surface that can be seen through the semitransparent body.

I started with this, using a brute force approach to get a volume filled with non-touching spheres (taken from a different thread: Randomly packing spheres of fixed radius within a cube) and then increasing their size:

spheres = {};
cubesize = 1;(*size of the sample volume*)
diameter = 0.15;(*diameter of the small spheres*)
multi = 1.4;(*multiply small diameter with this to get large diameter*)
number = 10; (*number of spheres within the cube*)
spheredistance = 2.; (*distance of the spheres in multiples of the small diameter*)
    While[Length[spheres] < number, 
      s = RandomReal[{diameter, cubesize - diameter}, 3];
      If[And @@ (Norm[# - s] > diameter*spheredistance & /@ spheres), 
       AppendTo[spheres, s]]];
    {Graphics3D[{Opacity[0.4], Specularity[0.4], 
       smallPockets = Ball[#, diameter] & /@ spheres}, 
      PlotRange -> {{cubesize*.05, cubesize*.95}, {cubesize*.05, 
         cubesize*.95}, {cubesize*.05, cubesize*.95}}, Boxed -> True, 
      BoxStyle -> Directive[Black, Thin, Dashed]],
     Graphics3D[{Opacity[0.7], Specularity[0.1], 
       largePockets = Ball[#, diameter*multi] & /@ spheres}, 
      PlotRange -> {{cubesize*.02, cubesize*.98}, {cubesize*.02, 
         cubesize*.98}, {cubesize*.02, cubesize*.98}}, Boxed -> True, 
      BoxStyle -> Directive[Black, Thin, Dashed]]}

giving: enter image description here

My attempt to produce the inverse and make it transparent was the following:

largePocketsRegion = largePockets // Region /@ # &;
cube = Cuboid[{0, 0, 0}, {cubesize, cubesize, cubesize}] // Region;
cheese = Fold[RegionDifference, cube, largePocketsRegion ]

giving something like this:

enter image description here

Now I am unable to make this render nicely and transparent. Is there a way to do that?


2 Answers 2

bmesh = OpenCascadeShape[ToBoundaryMesh[cube]];
balls = OpenCascadeShapeUnion[OpenCascadeShape /@ largePockets];
bm = OpenCascadeShapeSurfaceMeshToBoundaryMesh[
   OpenCascadeShapeDifference[bmesh, balls], 
   "ShapeSurfaceMeshOptions" -> {"AngularDeflection" -> 0.1}];
RegionPlot3D[BoundaryMeshRegion[bm], Boxed -> False, 
 PlotStyle -> Opacity[.2]]

enter image description here

  • Another example

Thanks @user21.

reg = OpenCascadeShape@
   Fold[RegionDifference, Cube[], 
    Ball[#, .1] & /@ RandomPoint[Cube[], 100]];
bm = OpenCascadeShapeSurfaceMeshToBoundaryMesh[reg, 
   "ShapeSurfaceMeshOptions" -> {"AngularDeflection" -> 0.1}];
mg = MeshRegion[bm];
Graphics3D[{EdgeForm[], FaceForm[{Opacity[.2], Yellow}], mg}, 
 Boxed -> False]

enter image description here

  • Although CSGRegion is faster,but upto the 13.0.1 version,it doesn't suport opacity.
reg = CSGRegion[
   "Difference", {Cube[], 
    CSGRegion["Union", Ball[#, .1] & /@ RandomPoint[Cube[], 100]]}, 
   BaseStyle -> Orange];
Graphics3D[{Opacity[.2], reg}, Lighting -> "ThreePoint", 
 Boxed -> False]

enter image description here

  • $\begingroup$ BoundaryMeshRegion->MeshRegion $\endgroup$
    – cvgmt
    Commented May 20, 2022 at 7:51
  • $\begingroup$ (+1). this is the way to go. It is more efficient to give the boolean region to OpenCascade then to give it the meshes. People have been 'educated' in doing that since the Boolean region stuff works better when the regions are discretized, $\endgroup$
    – user21
    Commented May 20, 2022 at 14:19
  • 3
    $\begingroup$ Here is a more efficient version: cube = Cuboid[{0, 0, 0}, {cubesize, cubesize, cubesize}]; cheese = Fold[RegionDifference, cube, largePockets]; shape = OpenCascadeShape[cheese]; bm = OpenCascadeShapeSurfaceMeshToBoundaryMesh[shape, "ShapeSurfaceMeshOptions" -> {"AngularDeflection" -> 0.1}]; RegionPlot3D[BoundaryMeshRegion[bm], Boxed -> False, PlotStyle -> Opacity[.2]] $\endgroup$
    – user21
    Commented May 20, 2022 at 14:20
  • $\begingroup$ @cvgmt: thanks, this produces the best quality! going for MeshRegion rather than BoundaryMeshRegion makes it also work for the 'smallPockets'. $\endgroup$
    – bertwood
    Commented May 23, 2022 at 9:55

One way:

Show[BoundaryDiscretizeRegion[cheese, MaxCellMeasure -> 0.001]] /. 
 FaceForm[Directive[d__]] :> FaceForm[Directive[d, Opacity[0.5]]]

enter image description here

Another way:

 BoundaryDiscretizeRegion[cheese, MaxCellMeasure -> 0.001], 
 PlotStyle -> Opacity[0.5]]

enter image description here

  • $\begingroup$ thanks a lot, this works nicely! i had the feeling that i had already tried something like this and failed but it seems that i have used some wrong objects then. $\endgroup$
    – bertwood
    Commented May 19, 2022 at 14:38
  • $\begingroup$ @bertwood Maybe you tried something like RegionPlot3D[cheese, PlotStyle -> Opacity[0.5]], which fails for some reason. (I don't see why it should, if DiscretizeRegion and BoundaryDiscretizeRegion succeed.) $\endgroup$
    – Michael E2
    Commented May 19, 2022 at 14:54

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.