joshcol9232/tiling

Replace Gmsh with a custom mesh generator

joshcol9232 opened this issue · 2 comments

Whilst Gmsh is a great multipurpose mesh library, it's slow for large structures, and there are sometimes gaps where rods meet at vertices. Cylinders in particular can be inefficient, as there are nodes along the length of the cylinder when all that is needed in our case is nodes at the ends. Also since the structures are orderly it may be possible to make a faster method. Plan:

  • Make a Python prototype
  • Implement in C++
  • Make a Python interface so it can be used in the application

Tested the latest PR with (also uncommented old utils code):

import dualgrid as dg
import networkx as nx
import numpy as np
import time

basis = dg.utils.n_dimensional_cubic_basis(3) # 4D cubic structure

print("OFFSETS:", basis.offsets)
G = None
k_range = 2

cells = dg.dualgrid_method(basis, k_range)
print("Generating graph...")
G = dg.utils.graph_from_cells(cells)
print("Done.")

print("SAVING TO STL: graph_out.stl ...")
# Specify path, and rod radius
start = time.time()
dg.utils.export_graph_to_stl(G, "graph_out.stl", 0.1)
duration_new = time.time() - start
print("DONE :)")

print("Saving to STL, old method...")
start = time.time()
m = dg.utils.generate_wire_mesh_stl(G)
m.write("graph_out_old.stl")
duration_old = time.time() - start
print("Done.")

print("Old:", duration_old)
print("New:", duration_new)

Gave an output of:

OFFSETS: [0.92650313 0.42954717 0.68067806]
Generating graph...
Done.
SAVING TO STL: graph_out.stl ...
DONE :)
Saving to STL, old method...
VERTEX RAD: 0.1
CELL COUNT: 8
CELL COUNT: 8
Warning: STL can only write triangle cells. Discarding line, vertex, tetra.
Done.
Old: 33.37196922302246
New: 3.1044750213623047

The new method is 10x faster. The quality of the new STL output is also considerably better (in my opinion - please see pictures below).
The file sizes are:

  • Old: 30.5 MiB
  • New: 31.2 MiB

Here are the two STL outputs shown in Blender:

  • Old:
    old

  • New:
    new

Had a thought - could potentially just generate a single rod, and then instance it - like in computer graphics. i.e store the vertices for a single cylinder at (0,0), then store a list of transforms describing the positions of every cylinder in the final mesh. Then generate from that?
More memory efficient, potentially less computationally efficient.