TransWikia.com

How to convert cuboid to mesh efficiently

Mathematica Asked on May 14, 2021

cuboids = 
Table[Cuboid @@ (pts = RandomReal[100, {2, 3}]), {i, 10000}];

Method1:

AbsoluteTiming[
r = BoundaryDiscretizeGraphics[#, MaxCellMeasure -> [Infinity]] & /@ 
cuboids[[1 ;; 100]];]

Method1, Sometimes, on my macbook pro, costs 5 seconds, this is not a stable method.

A baseline is to convert 10000 random cuboids to a mesh object of 60000 polygons in 10 seconds. Import this file in "MeshRegion" Option costs little time.

like method2:

In[53]:= AbsoluteTiming[Export["test.obj", Graphics3D@cuboids];]

Out[53]= {8.00617, Null}

3 Answers

cuboids = Table[Cuboid @@ (pts = RandomReal[100, {2, 3}]), {i, 10000}];

cuboids /. 
   Cuboid[{x1_, y1_, z1_}, {x2_, y2_, z2_}] :> 
    MeshRegion[{{x1, y1, z1}, {x2, y1, z1}, {x2, y2, z1}, {x1, y2, z1},
      {x1, y1, z2}, {x2, y1, z2}, {x2, y2, z2}, {x1, y2, z2}},
        {Polygon[{{4, 3, 2, 1}, {1, 2, 6, 5}, {2, 3, 7, 6},
          {3, 4, 8, 7}, {4, 1, 5, 8}, {5, 6, 7, 8}}]}]; // AbsoluteTiming

{0.330509, Null}

Replace MeshRegion with BoundaryMeshRegion

{16.3816, Null}

Correct answer by chyanog on May 14, 2021

Getting single MeshRegion using all 10000 cuboids seems to be faster than generating a MeshRegion object for each cuboid:

SeedRandom[1]
pts = RandomReal[100, {10000, 2, 3}];
cuboids = Cuboid @@@ pts;

cuboidsToMeshReg = Module[{indices, 
     faceindices = {{3, 7, 5, 1}, {1, 5, 6, 2}, {5, 7, 8, 6}, {4, 8, 7, 3}, 
       {2, 4, 3, 1}, {2, 6, 8, 4}}, 
     meshcoords = Join @@ (Tuples[Transpose@{##}] & @@@ #)}, 
    indices = Join @@ (faceindices + 8 # & /@ Range[0, Length[#] - 1]); 
    MeshRegion[meshcoords, Polygon @ indices]] &;

mreg = cuboidsToMeshReg @ cuboids; // AbsoluteTiming // First
0.157844
MeshCellCount[mreg, 2]
60000

Answered by kglr on May 14, 2021

You can use the OpenCascadeLink (that ships with Wolfram Language since version 12.1 or from GitHub) for this:

Needs["OpenCascadeLink`"]
cuboids = 
  Table[Cuboid @@ (pts = RandomReal[100, {2, 3}]), {i, 10000}];

AbsoluteTiming[
 r = BoundaryDiscretizeGraphics[#, MaxCellMeasure -> [Infinity]] & /@
     cuboids;]

{36.422, Null}

AbsoluteTiming[
 s = OpenCascadeShape /@ cuboids;
 bmeshs = OpenCascadeShapeSurfaceMeshToBoundaryMesh /@ s;
 ]
{11.1387, Null}

bmeshs // Length
10000

FreeQ[bmeshs, $Failed]
True

#["Wireframe"] & /@ RandomChoice[bmeshs, {10}]

Answered by user21 on May 14, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP