I want to try computationally modeling the surface of indented tinwork items (after taking a class with Cleo Romero at MAKE Santa Fe). The physically based rendering provided by MaterialShading should do the heavy lifting of rendering objects created by constructive solid geometry, but there are some tricks to make this work….

The Setup

Begin by defining the work plane and some positive and negative indentations (viewed from the top), and combine them using CSGRegion:

positive = CSGRegion@
    Table[Ball[{RandomReal[{-5, 5}], RandomReal[{-5, 5}], 0}, 0.2], 10];
negative = CSGRegion@ 
    Table[Ball[{RandomReal[{-5, 5}], RandomReal[{-5, 5}], 0}, 0.2], 10];
plane = Cuboid[{-5, -5, -0.2}, {5, 5, 0.0}]; 
 
g = CSGRegion["Difference", {#, negative}]&@ CSGRegion["Union", {positive, plane}]

1k1761popjmb7

The Problem: CSGRegions do not render

Except, there is a problem: The resulting CSGRegion does not accept MaterialShading:

Graphics3D[{MaterialShading["Gold"], g}]

0gug38dcblv28

There is also another problem with the CSGRegion….it does not export to an STL file! If we round trip this, we only get the flat sheet:

Export["~/Downloads/foo.stl", g]
Import[%]

(*"~/Downloads/foo.stl"*)

15y71xfh798z5

How shall we fix this problem?

OpenCascadeLink help us in exporting this, but even then there are some tricks to consider. Conveniently, OpenCascadeShape accepts any CSGRegion as input, which is convenient:

Needs["OpenCascadeLink`"]

oc = OpenCascadeShape[g]
OpenCascadeShapeSurfaceMeshToBoundaryMesh[oc]["Wireframe"] (* visualize *)

01dirq9w6crn6

We are not out of the woods yet, as it does not export these expressions!

Export["~/Downloads/foo1.stl", oc]

18fu8yhaevwbw

(*$Failed*)

However, the OpenCascadeLink Import/Export documentation describes a workaround, which involves converting a shape into a a MeshRegion for export to fix problematic boundary normals:

mr = MeshRegion@ OpenCascadeShapeSurfaceMeshToBoundaryMesh[oc];
Export["~/Downloads/foo2.stl", mr]

(*"~/Downloads/foo2.stl"*)

We can then Import the STL back in (where it will get converted to a Graphics3D item) and see that it renders nicely:

Graphics3D[
  {MaterialShading["Gold"], 
   Import["Downloads/foo2.stl"]}, 
  Lighting -> "Neutral"]

16hbf057vy6sz

Our desired pattern is more silvery; there are a few options but Iron is reasonable:

Graphics3D[
  {MaterialShading["Iron"], 
   Import["Downloads/foo2.stl"]}, 
  Lighting -> "Neutral"]

0w7hc5jn4sb1f

Ideas to explore: Rendering complex patterns

ToJekyll["Rendering Metal Surfaces", "mathematica santafe art opencascade"]