minesweeper

A minewseeper implementation to play around with Hare and Raylib
git clone https://git.tronto.net/minesweeper
Download | Log | Files | Refs | README | LICENSE

par_shapes.h (72865B)


      1 // SHAPES :: https://github.com/prideout/par
      2 // Simple C library for creation and manipulation of triangle meshes.
      3 //
      4 // The API is divided into three sections:
      5 //
      6 //   - Generators.  Create parametric surfaces, platonic solids, etc.
      7 //   - Queries.     Ask a mesh for its axis-aligned bounding box, etc.
      8 //   - Transforms.  Rotate a mesh, merge it with another, add normals, etc.
      9 //
     10 // In addition to the comment block above each function declaration, the API
     11 // has informal documentation here:
     12 //
     13 //     https://prideout.net/shapes
     14 //
     15 // For our purposes, a "mesh" is a list of points and a list of triangles; the
     16 // former is a flattened list of three-tuples (32-bit floats) and the latter is
     17 // also a flattened list of three-tuples (16-bit uints).  Triangles are always
     18 // oriented such that their front face winds counter-clockwise.
     19 //
     20 // Optionally, meshes can contain 3D normals (one per vertex), and 2D texture
     21 // coordinates (one per vertex).  That's it!  If you need something fancier,
     22 // look elsewhere.
     23 //
     24 // Distributed under the MIT License, see bottom of file.
     25 
     26 #ifndef PAR_SHAPES_H
     27 #define PAR_SHAPES_H
     28 
     29 #ifdef __cplusplus
     30 extern "C" {
     31 #endif
     32 
     33 #include <stdint.h>
     34 // Ray (@raysan5): Commented to avoid conflict with raylib bool
     35 /*
     36 #if !defined(_MSC_VER)
     37 # include <stdbool.h>
     38 #else // MSVC
     39 # if _MSC_VER >= 1800
     40 #  include <stdbool.h>
     41 # else // stdbool.h missing prior to MSVC++ 12.0 (VS2013)
     42 #  define bool int
     43 #  define true 1
     44 #  define false 0
     45 # endif
     46 #endif
     47 */
     48 
     49 #ifndef PAR_SHAPES_T
     50 #define PAR_SHAPES_T uint16_t
     51 #endif
     52 
     53 typedef struct par_shapes_mesh_s {
     54     float* points;           // Flat list of 3-tuples (X Y Z X Y Z...)
     55     int npoints;             // Number of points
     56     PAR_SHAPES_T* triangles; // Flat list of 3-tuples (I J K I J K...)
     57     int ntriangles;          // Number of triangles
     58     float* normals;          // Optional list of 3-tuples (X Y Z X Y Z...)
     59     float* tcoords;          // Optional list of 2-tuples (U V U V U V...)
     60 } par_shapes_mesh;
     61 
     62 void par_shapes_free_mesh(par_shapes_mesh*);
     63 
     64 // Generators ------------------------------------------------------------------
     65 
     66 // Instance a cylinder that sits on the Z=0 plane using the given tessellation
     67 // levels across the UV domain.  Think of "slices" like a number of pizza
     68 // slices, and "stacks" like a number of stacked rings.  Height and radius are
     69 // both 1.0, but they can easily be changed with par_shapes_scale.
     70 par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks);
     71 
     72 // Cone is similar to cylinder but the radius diminishes to zero as Z increases.
     73 // Again, height and radius are 1.0, but can be changed with par_shapes_scale.
     74 par_shapes_mesh* par_shapes_create_cone(int slices, int stacks);
     75 
     76 // Create a disk of radius 1.0 with texture coordinates and normals by squashing
     77 // a cone flat on the Z=0 plane.
     78 par_shapes_mesh* par_shapes_create_parametric_disk(int slices, int stacks);
     79 
     80 // Create a donut that sits on the Z=0 plane with the specified inner radius.
     81 // The outer radius can be controlled with par_shapes_scale.
     82 par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius);
     83 
     84 // Create a sphere with texture coordinates and small triangles near the poles.
     85 par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks);
     86 
     87 // Approximate a sphere with a subdivided icosahedron, which produces a nice
     88 // distribution of triangles, but no texture coordinates.  Each subdivision
     89 // level scales the number of triangles by four, so use a very low number.
     90 par_shapes_mesh* par_shapes_create_subdivided_sphere(int nsubdivisions);
     91 
     92 // More parametric surfaces.
     93 par_shapes_mesh* par_shapes_create_klein_bottle(int slices, int stacks);
     94 par_shapes_mesh* par_shapes_create_trefoil_knot(int slices, int stacks,
     95     float radius);
     96 par_shapes_mesh* par_shapes_create_hemisphere(int slices, int stacks);
     97 par_shapes_mesh* par_shapes_create_plane(int slices, int stacks);
     98 
     99 // Create a parametric surface from a callback function that consumes a 2D
    100 // point in [0,1] and produces a 3D point.
    101 typedef void (*par_shapes_fn)(float const*, float*, void*);
    102 par_shapes_mesh* par_shapes_create_parametric(par_shapes_fn, int slices,
    103     int stacks, void* userdata);
    104 
    105 // Generate points for a 20-sided polyhedron that fits in the unit sphere.
    106 // Texture coordinates and normals are not generated.
    107 par_shapes_mesh* par_shapes_create_icosahedron();
    108 
    109 // Generate points for a 12-sided polyhedron that fits in the unit sphere.
    110 // Again, texture coordinates and normals are not generated.
    111 par_shapes_mesh* par_shapes_create_dodecahedron();
    112 
    113 // More platonic solids.
    114 par_shapes_mesh* par_shapes_create_octahedron();
    115 par_shapes_mesh* par_shapes_create_tetrahedron();
    116 par_shapes_mesh* par_shapes_create_cube();
    117 
    118 // Generate an orientable disk shape in 3-space.  Does not include normals or
    119 // texture coordinates.
    120 par_shapes_mesh* par_shapes_create_disk(float radius, int slices,
    121     float const* center, float const* normal);
    122 
    123 // Create an empty shape.  Useful for building scenes with merge_and_free.
    124 par_shapes_mesh* par_shapes_create_empty();
    125 
    126 // Generate a rock shape that sits on the Y=0 plane, and sinks into it a bit.
    127 // This includes smooth normals but no texture coordinates.  Each subdivision
    128 // level scales the number of triangles by four, so use a very low number.
    129 par_shapes_mesh* par_shapes_create_rock(int seed, int nsubdivisions);
    130 
    131 // Create trees or vegetation by executing a recursive turtle graphics program.
    132 // The program is a list of command-argument pairs.  See the unit test for
    133 // an example.  Texture coordinates and normals are not generated.
    134 par_shapes_mesh* par_shapes_create_lsystem(char const* program, int slices,
    135     int maxdepth);
    136 
    137 // Queries ---------------------------------------------------------------------
    138 
    139 // Dump out a text file conforming to the venerable OBJ format.
    140 void par_shapes_export(par_shapes_mesh const*, char const* objfile);
    141 
    142 // Take a pointer to 6 floats and set them to min xyz, max xyz.
    143 void par_shapes_compute_aabb(par_shapes_mesh const* mesh, float* aabb);
    144 
    145 // Make a deep copy of a mesh.  To make a brand new copy, pass null to "target".
    146 // To avoid memory churn, pass an existing mesh to "target".
    147 par_shapes_mesh* par_shapes_clone(par_shapes_mesh const* mesh,
    148     par_shapes_mesh* target);
    149 
    150 // Transformations -------------------------------------------------------------
    151 
    152 void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src);
    153 void par_shapes_translate(par_shapes_mesh*, float x, float y, float z);
    154 void par_shapes_rotate(par_shapes_mesh*, float radians, float const* axis);
    155 void par_shapes_scale(par_shapes_mesh*, float x, float y, float z);
    156 void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src);
    157 
    158 // Reverse the winding of a run of faces.  Useful when drawing the inside of
    159 // a Cornell Box.  Pass 0 for nfaces to reverse every face in the mesh.
    160 void par_shapes_invert(par_shapes_mesh*, int startface, int nfaces);
    161 
    162 // Remove all triangles whose area is less than minarea.
    163 void par_shapes_remove_degenerate(par_shapes_mesh*, float minarea);
    164 
    165 // Dereference the entire index buffer and replace the point list.
    166 // This creates an inefficient structure, but is useful for drawing facets.
    167 // If create_indices is true, a trivial "0 1 2 3..." index buffer is generated.
    168 void par_shapes_unweld(par_shapes_mesh* mesh, bool create_indices);
    169 
    170 // Merge colocated verts, build a new index buffer, and return the
    171 // optimized mesh.  Epsilon is the maximum distance to consider when
    172 // welding vertices. The mapping argument can be null, or a pointer to
    173 // npoints integers, which gets filled with the mapping from old vertex
    174 // indices to new indices.
    175 par_shapes_mesh* par_shapes_weld(par_shapes_mesh const*, float epsilon,
    176     PAR_SHAPES_T* mapping);
    177 
    178 // Compute smooth normals by averaging adjacent facet normals.
    179 void par_shapes_compute_normals(par_shapes_mesh* m);
    180 
    181 // Global Config ---------------------------------------------------------------
    182 
    183 void par_shapes_set_epsilon_welded_normals(float epsilon);
    184 void par_shapes_set_epsilon_degenerate_sphere(float epsilon);
    185 
    186 // Advanced --------------------------------------------------------------------
    187 
    188 void par_shapes__compute_welded_normals(par_shapes_mesh* m);
    189 void par_shapes__connect(par_shapes_mesh* scene, par_shapes_mesh* cylinder,
    190     int slices);
    191 
    192 #ifndef PAR_PI
    193 #define PAR_PI (3.14159265359)
    194 #define PAR_MIN(a, b) (a > b ? b : a)
    195 #define PAR_MAX(a, b) (a > b ? a : b)
    196 #define PAR_CLAMP(v, lo, hi) PAR_MAX(lo, PAR_MIN(hi, v))
    197 #define PAR_SWAP(T, A, B) { T tmp = B; B = A; A = tmp; }
    198 #define PAR_SQR(a) ((a) * (a))
    199 #endif
    200 
    201 #ifndef PAR_MALLOC
    202 #define PAR_MALLOC(T, N) ((T*) malloc(N * sizeof(T)))
    203 #define PAR_CALLOC(T, N) ((T*) calloc(N * sizeof(T), 1))
    204 #define PAR_REALLOC(T, BUF, N) ((T*) realloc(BUF, sizeof(T) * (N)))
    205 #define PAR_FREE(BUF) free(BUF)
    206 #endif
    207 
    208 #ifdef __cplusplus
    209 }
    210 #endif
    211 
    212 // -----------------------------------------------------------------------------
    213 // END PUBLIC API
    214 // -----------------------------------------------------------------------------
    215 
    216 #ifdef PAR_SHAPES_IMPLEMENTATION
    217 #include <stdlib.h>
    218 #include <stdio.h>
    219 #include <assert.h>
    220 #include <float.h>
    221 #include <string.h>
    222 #include <math.h>
    223 #include <errno.h>
    224 
    225 static float par_shapes__epsilon_welded_normals = 0.001;
    226 static float par_shapes__epsilon_degenerate_sphere = 0.0001;
    227 
    228 static void par_shapes__sphere(float const* uv, float* xyz, void*);
    229 static void par_shapes__hemisphere(float const* uv, float* xyz, void*);
    230 static void par_shapes__plane(float const* uv, float* xyz, void*);
    231 static void par_shapes__klein(float const* uv, float* xyz, void*);
    232 static void par_shapes__cylinder(float const* uv, float* xyz, void*);
    233 static void par_shapes__cone(float const* uv, float* xyz, void*);
    234 static void par_shapes__torus(float const* uv, float* xyz, void*);
    235 static void par_shapes__trefoil(float const* uv, float* xyz, void*);
    236 
    237 struct osn_context;
    238 static int par__simplex_noise(int64_t seed, struct osn_context** ctx);
    239 static void par__simplex_noise_free(struct osn_context* ctx);
    240 static double par__simplex_noise2(struct osn_context* ctx, double x, double y);
    241 
    242 static void par_shapes__copy3(float* result, float const* a)
    243 {
    244     result[0] = a[0];
    245     result[1] = a[1];
    246     result[2] = a[2];
    247 }
    248 
    249 static float par_shapes__dot3(float const* a, float const* b)
    250 {
    251     return b[0] * a[0] + b[1] * a[1] + b[2] * a[2];
    252 }
    253 
    254 static void par_shapes__transform3(float* p, float const* x, float const* y,
    255     float const* z)
    256 {
    257     float px = par_shapes__dot3(p, x);
    258     float py = par_shapes__dot3(p, y);
    259     float pz = par_shapes__dot3(p, z);
    260     p[0] = px;
    261     p[1] = py;
    262     p[2] = pz;
    263 }
    264 
    265 static void par_shapes__cross3(float* result, float const* a, float const* b)
    266 {
    267     float x = (a[1] * b[2]) - (a[2] * b[1]);
    268     float y = (a[2] * b[0]) - (a[0] * b[2]);
    269     float z = (a[0] * b[1]) - (a[1] * b[0]);
    270     result[0] = x;
    271     result[1] = y;
    272     result[2] = z;
    273 }
    274 
    275 static void par_shapes__mix3(float* d, float const* a, float const* b, float t)
    276 {
    277     float x = b[0] * t + a[0] * (1 - t);
    278     float y = b[1] * t + a[1] * (1 - t);
    279     float z = b[2] * t + a[2] * (1 - t);
    280     d[0] = x;
    281     d[1] = y;
    282     d[2] = z;
    283 }
    284 
    285 static void par_shapes__scale3(float* result, float a)
    286 {
    287     result[0] *= a;
    288     result[1] *= a;
    289     result[2] *= a;
    290 }
    291 
    292 static void par_shapes__normalize3(float* v)
    293 {
    294     float lsqr = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
    295     if (lsqr > 0) {
    296         par_shapes__scale3(v, 1.0f / lsqr);
    297     }
    298 }
    299 
    300 static void par_shapes__subtract3(float* result, float const* a)
    301 {
    302     result[0] -= a[0];
    303     result[1] -= a[1];
    304     result[2] -= a[2];
    305 }
    306 
    307 static void par_shapes__add3(float* result, float const* a)
    308 {
    309     result[0] += a[0];
    310     result[1] += a[1];
    311     result[2] += a[2];
    312 }
    313 
    314 static float par_shapes__sqrdist3(float const* a, float const* b)
    315 {
    316     float dx = a[0] - b[0];
    317     float dy = a[1] - b[1];
    318     float dz = a[2] - b[2];
    319     return dx * dx + dy * dy + dz * dz;
    320 }
    321 
    322 void par_shapes__compute_welded_normals(par_shapes_mesh* m)
    323 {
    324     const float epsilon = par_shapes__epsilon_welded_normals;
    325     m->normals = PAR_MALLOC(float, m->npoints * 3);
    326     PAR_SHAPES_T* weldmap = PAR_MALLOC(PAR_SHAPES_T, m->npoints);
    327     par_shapes_mesh* welded = par_shapes_weld(m, epsilon, weldmap);
    328     par_shapes_compute_normals(welded);
    329     float* pdst = m->normals;
    330     for (int i = 0; i < m->npoints; i++, pdst += 3) {
    331         int d = weldmap[i];
    332         float const* pnormal = welded->normals + d * 3;
    333         pdst[0] = pnormal[0];
    334         pdst[1] = pnormal[1];
    335         pdst[2] = pnormal[2];
    336     }
    337     PAR_FREE(weldmap);
    338     par_shapes_free_mesh(welded);
    339 }
    340 
    341 par_shapes_mesh* par_shapes_create_cylinder(int slices, int stacks)
    342 {
    343     if (slices < 3 || stacks < 1) {
    344         return 0;
    345     }
    346     return par_shapes_create_parametric(par_shapes__cylinder, slices,
    347         stacks, 0);
    348 }
    349 
    350 par_shapes_mesh* par_shapes_create_cone(int slices, int stacks)
    351 {
    352     if (slices < 3 || stacks < 1) {
    353         return 0;
    354     }
    355     return par_shapes_create_parametric(par_shapes__cone, slices,
    356         stacks, 0);
    357 }
    358 
    359 par_shapes_mesh* par_shapes_create_parametric_disk(int slices, int stacks)
    360 {
    361     par_shapes_mesh* m = par_shapes_create_cone(slices, stacks);
    362     if (m) {
    363         par_shapes_scale(m, 1.0f, 1.0f, 0.0f);
    364     }
    365     return m;
    366 }
    367 
    368 par_shapes_mesh* par_shapes_create_parametric_sphere(int slices, int stacks)
    369 {
    370     if (slices < 3 || stacks < 3) {
    371         return 0;
    372     }
    373     par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__sphere,
    374         slices, stacks, 0);
    375     par_shapes_remove_degenerate(m, par_shapes__epsilon_degenerate_sphere);
    376     return m;
    377 }
    378 
    379 par_shapes_mesh* par_shapes_create_hemisphere(int slices, int stacks)
    380 {
    381     if (slices < 3 || stacks < 3) {
    382         return 0;
    383     }
    384     par_shapes_mesh* m = par_shapes_create_parametric(par_shapes__hemisphere,
    385         slices, stacks, 0);
    386     par_shapes_remove_degenerate(m, par_shapes__epsilon_degenerate_sphere);
    387     return m;
    388 }
    389 
    390 par_shapes_mesh* par_shapes_create_torus(int slices, int stacks, float radius)
    391 {
    392     if (slices < 3 || stacks < 3) {
    393         return 0;
    394     }
    395     assert(radius <= 1.0 && "Use smaller radius to avoid self-intersection.");
    396     assert(radius >= 0.1 && "Use larger radius to avoid self-intersection.");
    397     void* userdata = (void*) &radius;
    398     return par_shapes_create_parametric(par_shapes__torus, slices,
    399         stacks, userdata);
    400 }
    401 
    402 par_shapes_mesh* par_shapes_create_klein_bottle(int slices, int stacks)
    403 {
    404     if (slices < 3 || stacks < 3) {
    405         return 0;
    406     }
    407     par_shapes_mesh* mesh = par_shapes_create_parametric(
    408         par_shapes__klein, slices, stacks, 0);
    409     int face = 0;
    410     for (int stack = 0; stack < stacks; stack++) {
    411         for (int slice = 0; slice < slices; slice++, face += 2) {
    412             if (stack < 27 * stacks / 32) {
    413                 par_shapes_invert(mesh, face, 2);
    414             }
    415         }
    416     }
    417     par_shapes__compute_welded_normals(mesh);
    418     return mesh;
    419 }
    420 
    421 par_shapes_mesh* par_shapes_create_trefoil_knot(int slices, int stacks,
    422     float radius)
    423 {
    424     if (slices < 3 || stacks < 3) {
    425         return 0;
    426     }
    427     assert(radius <= 3.0 && "Use smaller radius to avoid self-intersection.");
    428     assert(radius >= 0.5 && "Use larger radius to avoid self-intersection.");
    429     void* userdata = (void*) &radius;
    430     return par_shapes_create_parametric(par_shapes__trefoil, slices,
    431         stacks, userdata);
    432 }
    433 
    434 par_shapes_mesh* par_shapes_create_plane(int slices, int stacks)
    435 {
    436     if (slices < 1 || stacks < 1) {
    437         return 0;
    438     }
    439     return par_shapes_create_parametric(par_shapes__plane, slices,
    440         stacks, 0);
    441 }
    442 
    443 par_shapes_mesh* par_shapes_create_parametric(par_shapes_fn fn,
    444     int slices, int stacks, void* userdata)
    445 {
    446     par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
    447 
    448     // Generate verts.
    449     mesh->npoints = (slices + 1) * (stacks + 1);
    450     mesh->points = PAR_CALLOC(float, 3 * mesh->npoints);
    451     float uv[2];
    452     float xyz[3];
    453     float* points = mesh->points;
    454     for (int stack = 0; stack < stacks + 1; stack++) {
    455         uv[0] = (float) stack / stacks;
    456         for (int slice = 0; slice < slices + 1; slice++) {
    457             uv[1] = (float) slice / slices;
    458             fn(uv, xyz, userdata);
    459             *points++ = xyz[0];
    460             *points++ = xyz[1];
    461             *points++ = xyz[2];
    462         }
    463     }
    464 
    465     // Generate texture coordinates.
    466     mesh->tcoords = PAR_CALLOC(float, 2 * mesh->npoints);
    467     float* uvs = mesh->tcoords;
    468     for (int stack = 0; stack < stacks + 1; stack++) {
    469         uv[0] = (float) stack / stacks;
    470         for (int slice = 0; slice < slices + 1; slice++) {
    471             uv[1] = (float) slice / slices;
    472             *uvs++ = uv[0];
    473             *uvs++ = uv[1];
    474         }
    475     }
    476 
    477     // Generate faces.
    478     mesh->ntriangles = 2 * slices * stacks;
    479     mesh->triangles = PAR_CALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
    480     int v = 0;
    481     PAR_SHAPES_T* face = mesh->triangles;
    482     for (int stack = 0; stack < stacks; stack++) {
    483         for (int slice = 0; slice < slices; slice++) {
    484             int next = slice + 1;
    485             *face++ = v + slice + slices + 1;
    486             *face++ = v + next;
    487             *face++ = v + slice;
    488             *face++ = v + slice + slices + 1;
    489             *face++ = v + next + slices + 1;
    490             *face++ = v + next;
    491         }
    492         v += slices + 1;
    493     }
    494 
    495     par_shapes__compute_welded_normals(mesh);
    496     return mesh;
    497 }
    498 
    499 void par_shapes_free_mesh(par_shapes_mesh* mesh)
    500 {
    501     PAR_FREE(mesh->points);
    502     PAR_FREE(mesh->triangles);
    503     PAR_FREE(mesh->normals);
    504     PAR_FREE(mesh->tcoords);
    505     PAR_FREE(mesh);
    506 }
    507 
    508 void par_shapes_export(par_shapes_mesh const* mesh, char const* filename)
    509 {
    510     FILE* objfile = fopen(filename, "wt");
    511     float const* points = mesh->points;
    512     float const* tcoords = mesh->tcoords;
    513     float const* norms = mesh->normals;
    514     PAR_SHAPES_T const* indices = mesh->triangles;
    515     if (tcoords && norms) {
    516         for (int nvert = 0; nvert < mesh->npoints; nvert++) {
    517             fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
    518             fprintf(objfile, "vt %f %f\n", tcoords[0], tcoords[1]);
    519             fprintf(objfile, "vn %f %f %f\n", norms[0], norms[1], norms[2]);
    520             points += 3;
    521             norms += 3;
    522             tcoords += 2;
    523         }
    524         for (int nface = 0; nface < mesh->ntriangles; nface++) {
    525             int a = 1 + *indices++;
    526             int b = 1 + *indices++;
    527             int c = 1 + *indices++;
    528             fprintf(objfile, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
    529                 a, a, a, b, b, b, c, c, c);
    530         }
    531     } else if (norms) {
    532         for (int nvert = 0; nvert < mesh->npoints; nvert++) {
    533             fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
    534             fprintf(objfile, "vn %f %f %f\n", norms[0], norms[1], norms[2]);
    535             points += 3;
    536             norms += 3;
    537         }
    538         for (int nface = 0; nface < mesh->ntriangles; nface++) {
    539             int a = 1 + *indices++;
    540             int b = 1 + *indices++;
    541             int c = 1 + *indices++;
    542             fprintf(objfile, "f %d//%d %d//%d %d//%d\n", a, a, b, b, c, c);
    543         }
    544     } else if (tcoords) {
    545         for (int nvert = 0; nvert < mesh->npoints; nvert++) {
    546             fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
    547             fprintf(objfile, "vt %f %f\n", tcoords[0], tcoords[1]);
    548             points += 3;
    549             tcoords += 2;
    550         }
    551         for (int nface = 0; nface < mesh->ntriangles; nface++) {
    552             int a = 1 + *indices++;
    553             int b = 1 + *indices++;
    554             int c = 1 + *indices++;
    555             fprintf(objfile, "f %d/%d %d/%d %d/%d\n", a, a, b, b, c, c);
    556         }
    557     } else {
    558         for (int nvert = 0; nvert < mesh->npoints; nvert++) {
    559             fprintf(objfile, "v %f %f %f\n", points[0], points[1], points[2]);
    560             points += 3;
    561         }
    562         for (int nface = 0; nface < mesh->ntriangles; nface++) {
    563             int a = 1 + *indices++;
    564             int b = 1 + *indices++;
    565             int c = 1 + *indices++;
    566             fprintf(objfile, "f %d %d %d\n", a, b, c);
    567         }
    568     }
    569     fclose(objfile);
    570 }
    571 
    572 static void par_shapes__sphere(float const* uv, float* xyz, void* userdata)
    573 {
    574     float phi = uv[0] * PAR_PI;
    575     float theta = uv[1] * 2 * PAR_PI;
    576     xyz[0] = cosf(theta) * sinf(phi);
    577     xyz[1] = sinf(theta) * sinf(phi);
    578     xyz[2] = cosf(phi);
    579 }
    580 
    581 static void par_shapes__hemisphere(float const* uv, float* xyz, void* userdata)
    582 {
    583     float phi = uv[0] * PAR_PI;
    584     float theta = uv[1] * PAR_PI;
    585     xyz[0] = cosf(theta) * sinf(phi);
    586     xyz[1] = sinf(theta) * sinf(phi);
    587     xyz[2] = cosf(phi);
    588 }
    589 
    590 static void par_shapes__plane(float const* uv, float* xyz, void* userdata)
    591 {
    592     xyz[0] = uv[0];
    593     xyz[1] = uv[1];
    594     xyz[2] = 0;
    595 }
    596 
    597 static void par_shapes__klein(float const* uv, float* xyz, void* userdata)
    598 {
    599     float u = uv[0] * PAR_PI;
    600     float v = uv[1] * 2 * PAR_PI;
    601     u = u * 2;
    602     if (u < PAR_PI) {
    603         xyz[0] = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) *
    604             cosf(u) * cosf(v);
    605         xyz[2] = -8 * sinf(u) - 2 * (1 - cosf(u) / 2) * sinf(u) * cosf(v);
    606     } else {
    607         xyz[0] = 3 * cosf(u) * (1 + sinf(u)) + (2 * (1 - cosf(u) / 2)) *
    608             cosf(v + PAR_PI);
    609         xyz[2] = -8 * sinf(u);
    610     }
    611     xyz[1] = -2 * (1 - cosf(u) / 2) * sinf(v);
    612 }
    613 
    614 static void par_shapes__cylinder(float const* uv, float* xyz, void* userdata)
    615 {
    616     float theta = uv[1] * 2 * PAR_PI;
    617     xyz[0] = sinf(theta);
    618     xyz[1] = cosf(theta);
    619     xyz[2] = uv[0];
    620 }
    621 
    622 static void par_shapes__cone(float const* uv, float* xyz, void* userdata)
    623 {
    624     float r = 1.0f - uv[0];
    625     float theta = uv[1] * 2 * PAR_PI;
    626     xyz[0] = r * sinf(theta);
    627     xyz[1] = r * cosf(theta);
    628     xyz[2] = uv[0];
    629 }
    630 
    631 static void par_shapes__torus(float const* uv, float* xyz, void* userdata)
    632 {
    633     float major = 1;
    634     float minor = *((float*) userdata);
    635     float theta = uv[0] * 2 * PAR_PI;
    636     float phi = uv[1] * 2 * PAR_PI;
    637     float beta = major + minor * cosf(phi);
    638     xyz[0] = cosf(theta) * beta;
    639     xyz[1] = sinf(theta) * beta;
    640     xyz[2] = sinf(phi) * minor;
    641 }
    642 
    643 static void par_shapes__trefoil(float const* uv, float* xyz, void* userdata)
    644 {
    645     float minor = *((float*) userdata);
    646     const float a = 0.5f;
    647     const float b = 0.3f;
    648     const float c = 0.5f;
    649     const float d = minor * 0.1f;
    650     const float u = (1 - uv[0]) * 4 * PAR_PI;
    651     const float v = uv[1] * 2 * PAR_PI;
    652     const float r = a + b * cos(1.5f * u);
    653     const float x = r * cos(u);
    654     const float y = r * sin(u);
    655     const float z = c * sin(1.5f * u);
    656     float q[3];
    657     q[0] =
    658         -1.5f * b * sin(1.5f * u) * cos(u) - (a + b * cos(1.5f * u)) * sin(u);
    659     q[1] =
    660         -1.5f * b * sin(1.5f * u) * sin(u) + (a + b * cos(1.5f * u)) * cos(u);
    661     q[2] = 1.5f * c * cos(1.5f * u);
    662     par_shapes__normalize3(q);
    663     float qvn[3] = {q[1], -q[0], 0};
    664     par_shapes__normalize3(qvn);
    665     float ww[3];
    666     par_shapes__cross3(ww, q, qvn);
    667     xyz[0] = x + d * (qvn[0] * cos(v) + ww[0] * sin(v));
    668     xyz[1] = y + d * (qvn[1] * cos(v) + ww[1] * sin(v));
    669     xyz[2] = z + d * ww[2] * sin(v);
    670 }
    671 
    672 void par_shapes_set_epsilon_welded_normals(float epsilon) {
    673     par_shapes__epsilon_welded_normals = epsilon;
    674 }
    675 
    676 void par_shapes_set_epsilon_degenerate_sphere(float epsilon) {
    677     par_shapes__epsilon_degenerate_sphere = epsilon;
    678 }
    679 
    680 void par_shapes_merge(par_shapes_mesh* dst, par_shapes_mesh const* src)
    681 {
    682     PAR_SHAPES_T offset = dst->npoints;
    683     int npoints = dst->npoints + src->npoints;
    684     int vecsize = sizeof(float) * 3;
    685     dst->points = PAR_REALLOC(float, dst->points, 3 * npoints);
    686     memcpy(dst->points + 3 * dst->npoints, src->points, vecsize * src->npoints);
    687     dst->npoints = npoints;
    688     if (src->normals || dst->normals) {
    689         dst->normals = PAR_REALLOC(float, dst->normals, 3 * npoints);
    690         if (src->normals) {
    691             memcpy(dst->normals + 3 * offset, src->normals,
    692                 vecsize * src->npoints);
    693         }
    694     }
    695     if (src->tcoords || dst->tcoords) {
    696         int uvsize = sizeof(float) * 2;
    697         dst->tcoords = PAR_REALLOC(float, dst->tcoords, 2 * npoints);
    698         if (src->tcoords) {
    699             memcpy(dst->tcoords + 2 * offset, src->tcoords,
    700                 uvsize * src->npoints);
    701         }
    702     }
    703     int ntriangles = dst->ntriangles + src->ntriangles;
    704     dst->triangles = PAR_REALLOC(PAR_SHAPES_T, dst->triangles, 3 * ntriangles);
    705     PAR_SHAPES_T* ptriangles = dst->triangles + 3 * dst->ntriangles;
    706     PAR_SHAPES_T const* striangles = src->triangles;
    707     for (int i = 0; i < src->ntriangles; i++) {
    708         *ptriangles++ = offset + *striangles++;
    709         *ptriangles++ = offset + *striangles++;
    710         *ptriangles++ = offset + *striangles++;
    711     }
    712     dst->ntriangles = ntriangles;
    713 }
    714 
    715 par_shapes_mesh* par_shapes_create_disk(float radius, int slices,
    716     float const* center, float const* normal)
    717 {
    718     par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
    719     mesh->npoints = slices + 1;
    720     mesh->points = PAR_MALLOC(float, 3 * mesh->npoints);
    721     float* points = mesh->points;
    722     *points++ = 0;
    723     *points++ = 0;
    724     *points++ = 0;
    725     for (int i = 0; i < slices; i++) {
    726         float theta = i * PAR_PI * 2 / slices;
    727         *points++ = radius * cos(theta);
    728         *points++ = radius * sin(theta);
    729         *points++ = 0;
    730     }
    731     float nnormal[3] = {normal[0], normal[1], normal[2]};
    732     par_shapes__normalize3(nnormal);
    733     mesh->normals = PAR_MALLOC(float, 3 * mesh->npoints);
    734     float* norms = mesh->normals;
    735     for (int i = 0; i < mesh->npoints; i++) {
    736         *norms++ = nnormal[0];
    737         *norms++ = nnormal[1];
    738         *norms++ = nnormal[2];
    739     }
    740     mesh->ntriangles = slices;
    741     mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
    742     PAR_SHAPES_T* triangles = mesh->triangles;
    743     for (int i = 0; i < slices; i++) {
    744         *triangles++ = 0;
    745         *triangles++ = 1 + i;
    746         *triangles++ = 1 + (i + 1) % slices;
    747     }
    748     float k[3] = {0, 0, -1};
    749     float axis[3];
    750     par_shapes__cross3(axis, nnormal, k);
    751     par_shapes__normalize3(axis);
    752     par_shapes_rotate(mesh, acos(nnormal[2]), axis);
    753     par_shapes_translate(mesh, center[0], center[1], center[2]);
    754     return mesh;
    755 }
    756 
    757 par_shapes_mesh* par_shapes_create_empty()
    758 {
    759     return PAR_CALLOC(par_shapes_mesh, 1);
    760 }
    761 
    762 void par_shapes_translate(par_shapes_mesh* m, float x, float y, float z)
    763 {
    764     float* points = m->points;
    765     for (int i = 0; i < m->npoints; i++) {
    766         *points++ += x;
    767         *points++ += y;
    768         *points++ += z;
    769     }
    770 }
    771 
    772 void par_shapes_rotate(par_shapes_mesh* mesh, float radians, float const* axis)
    773 {
    774     float s = sinf(radians);
    775     float c = cosf(radians);
    776     float x = axis[0];
    777     float y = axis[1];
    778     float z = axis[2];
    779     float xy = x * y;
    780     float yz = y * z;
    781     float zx = z * x;
    782     float oneMinusC = 1.0f - c;
    783     float col0[3] = {
    784         (((x * x) * oneMinusC) + c),
    785         ((xy * oneMinusC) + (z * s)), ((zx * oneMinusC) - (y * s))
    786     };
    787     float col1[3] = {
    788         ((xy * oneMinusC) - (z * s)),
    789         (((y * y) * oneMinusC) + c), ((yz * oneMinusC) + (x * s))
    790     };
    791     float col2[3] = {
    792         ((zx * oneMinusC) + (y * s)),
    793         ((yz * oneMinusC) - (x * s)), (((z * z) * oneMinusC) + c)
    794     };
    795     float* p = mesh->points;
    796     for (int i = 0; i < mesh->npoints; i++, p += 3) {
    797         float x = col0[0] * p[0] + col1[0] * p[1] + col2[0] * p[2];
    798         float y = col0[1] * p[0] + col1[1] * p[1] + col2[1] * p[2];
    799         float z = col0[2] * p[0] + col1[2] * p[1] + col2[2] * p[2];
    800         p[0] = x;
    801         p[1] = y;
    802         p[2] = z;
    803     }
    804     float* n = mesh->normals;
    805     if (n) {
    806         for (int i = 0; i < mesh->npoints; i++, n += 3) {
    807             float x = col0[0] * n[0] + col1[0] * n[1] + col2[0] * n[2];
    808             float y = col0[1] * n[0] + col1[1] * n[1] + col2[1] * n[2];
    809             float z = col0[2] * n[0] + col1[2] * n[1] + col2[2] * n[2];
    810             n[0] = x;
    811             n[1] = y;
    812             n[2] = z;
    813         }
    814     }
    815 }
    816 
    817 void par_shapes_scale(par_shapes_mesh* m, float x, float y, float z)
    818 {
    819     float* points = m->points;
    820     for (int i = 0; i < m->npoints; i++) {
    821         *points++ *= x;
    822         *points++ *= y;
    823         *points++ *= z;
    824     }
    825     float* n = m->normals;
    826     if (n && !(x == y && y == z)) {
    827         bool x_zero = x == 0;
    828         bool y_zero = y == 0;
    829         bool z_zero = z == 0;
    830         if (!x_zero && !y_zero && !z_zero) {
    831             x = 1.0f / x;
    832             y = 1.0f / y;
    833             z = 1.0f / z;
    834         } else {
    835             x = x_zero && !y_zero && !z_zero;
    836             y = y_zero && !x_zero && !z_zero;
    837             z = z_zero && !x_zero && !y_zero;
    838         }
    839         for (int i = 0; i < m->npoints; i++, n += 3) {
    840             n[0] *= x;
    841             n[1] *= y;
    842             n[2] *= z;
    843             par_shapes__normalize3(n);
    844         }
    845     }
    846 }
    847 
    848 void par_shapes_merge_and_free(par_shapes_mesh* dst, par_shapes_mesh* src)
    849 {
    850     par_shapes_merge(dst, src);
    851     par_shapes_free_mesh(src);
    852 }
    853 
    854 void par_shapes_compute_aabb(par_shapes_mesh const* m, float* aabb)
    855 {
    856     float* points = m->points;
    857     aabb[0] = aabb[3] = points[0];
    858     aabb[1] = aabb[4] = points[1];
    859     aabb[2] = aabb[5] = points[2];
    860     points += 3;
    861     for (int i = 1; i < m->npoints; i++, points += 3) {
    862         aabb[0] = PAR_MIN(points[0], aabb[0]);
    863         aabb[1] = PAR_MIN(points[1], aabb[1]);
    864         aabb[2] = PAR_MIN(points[2], aabb[2]);
    865         aabb[3] = PAR_MAX(points[0], aabb[3]);
    866         aabb[4] = PAR_MAX(points[1], aabb[4]);
    867         aabb[5] = PAR_MAX(points[2], aabb[5]);
    868     }
    869 }
    870 
    871 void par_shapes_invert(par_shapes_mesh* m, int face, int nfaces)
    872 {
    873     nfaces = nfaces ? nfaces : m->ntriangles;
    874     PAR_SHAPES_T* tri = m->triangles + face * 3;
    875     for (int i = 0; i < nfaces; i++) {
    876         PAR_SWAP(PAR_SHAPES_T, tri[0], tri[2]);
    877         tri += 3;
    878     }
    879 }
    880 
    881 par_shapes_mesh* par_shapes_create_icosahedron()
    882 {
    883     static float verts[] = {
    884         0.000,  0.000,  1.000,
    885         0.894,  0.000,  0.447,
    886         0.276,  0.851,  0.447,
    887         -0.724,  0.526,  0.447,
    888         -0.724, -0.526,  0.447,
    889         0.276, -0.851,  0.447,
    890         0.724,  0.526, -0.447,
    891         -0.276,  0.851, -0.447,
    892         -0.894,  0.000, -0.447,
    893         -0.276, -0.851, -0.447,
    894         0.724, -0.526, -0.447,
    895         0.000,  0.000, -1.000
    896     };
    897     static PAR_SHAPES_T faces[] = {
    898         0,1,2,
    899         0,2,3,
    900         0,3,4,
    901         0,4,5,
    902         0,5,1,
    903         7,6,11,
    904         8,7,11,
    905         9,8,11,
    906         10,9,11,
    907         6,10,11,
    908         6,2,1,
    909         7,3,2,
    910         8,4,3,
    911         9,5,4,
    912         10,1,5,
    913         6,7,2,
    914         7,8,3,
    915         8,9,4,
    916         9,10,5,
    917         10,6,1
    918     };
    919     par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
    920     mesh->npoints = sizeof(verts) / sizeof(verts[0]) / 3;
    921     mesh->points = PAR_MALLOC(float, sizeof(verts) / 4);
    922     memcpy(mesh->points, verts, sizeof(verts));
    923     mesh->ntriangles = sizeof(faces) / sizeof(faces[0]) / 3;
    924     mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, sizeof(faces) / 2);
    925     memcpy(mesh->triangles, faces, sizeof(faces));
    926     return mesh;
    927 }
    928 
    929 par_shapes_mesh* par_shapes_create_dodecahedron()
    930 {
    931     static float verts[20 * 3] = {
    932         0.607, 0.000, 0.795,
    933         0.188, 0.577, 0.795,
    934         -0.491, 0.357, 0.795,
    935         -0.491, -0.357, 0.795,
    936         0.188, -0.577, 0.795,
    937         0.982, 0.000, 0.188,
    938         0.304, 0.934, 0.188,
    939         -0.795, 0.577, 0.188,
    940         -0.795, -0.577, 0.188,
    941         0.304, -0.934, 0.188,
    942         0.795, 0.577, -0.188,
    943         -0.304, 0.934, -0.188,
    944         -0.982, 0.000, -0.188,
    945         -0.304, -0.934, -0.188,
    946         0.795, -0.577, -0.188,
    947         0.491, 0.357, -0.795,
    948         -0.188, 0.577, -0.795,
    949         -0.607, 0.000, -0.795,
    950         -0.188, -0.577, -0.795,
    951         0.491, -0.357, -0.795,
    952     };
    953     static PAR_SHAPES_T pentagons[12 * 5] = {
    954         0,1,2,3,4,
    955         5,10,6,1,0,
    956         6,11,7,2,1,
    957         7,12,8,3,2,
    958         8,13,9,4,3,
    959         9,14,5,0,4,
    960         15,16,11,6,10,
    961         16,17,12,7,11,
    962         17,18,13,8,12,
    963         18,19,14,9,13,
    964         19,15,10,5,14,
    965         19,18,17,16,15
    966     };
    967     int npentagons = sizeof(pentagons) / sizeof(pentagons[0]) / 5;
    968     par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
    969     int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
    970     mesh->npoints = ncorners;
    971     mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
    972     memcpy(mesh->points, verts, sizeof(verts));
    973     PAR_SHAPES_T const* pentagon = pentagons;
    974     mesh->ntriangles = npentagons * 3;
    975     mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
    976     PAR_SHAPES_T* tris = mesh->triangles;
    977     for (int p = 0; p < npentagons; p++, pentagon += 5) {
    978         *tris++ = pentagon[0];
    979         *tris++ = pentagon[1];
    980         *tris++ = pentagon[2];
    981         *tris++ = pentagon[0];
    982         *tris++ = pentagon[2];
    983         *tris++ = pentagon[3];
    984         *tris++ = pentagon[0];
    985         *tris++ = pentagon[3];
    986         *tris++ = pentagon[4];
    987     }
    988     return mesh;
    989 }
    990 
    991 par_shapes_mesh* par_shapes_create_octahedron()
    992 {
    993     static float verts[6 * 3] = {
    994         0.000, 0.000, 1.000,
    995         1.000, 0.000, 0.000,
    996         0.000, 1.000, 0.000,
    997         -1.000, 0.000, 0.000,
    998         0.000, -1.000, 0.000,
    999         0.000, 0.000, -1.000
   1000     };
   1001     static PAR_SHAPES_T triangles[8 * 3] = {
   1002         0,1,2,
   1003         0,2,3,
   1004         0,3,4,
   1005         0,4,1,
   1006         2,1,5,
   1007         3,2,5,
   1008         4,3,5,
   1009         1,4,5,
   1010     };
   1011     int ntris = sizeof(triangles) / sizeof(triangles[0]) / 3;
   1012     par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
   1013     int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
   1014     mesh->npoints = ncorners;
   1015     mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
   1016     memcpy(mesh->points, verts, sizeof(verts));
   1017     PAR_SHAPES_T const* triangle = triangles;
   1018     mesh->ntriangles = ntris;
   1019     mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
   1020     PAR_SHAPES_T* tris = mesh->triangles;
   1021     for (int p = 0; p < ntris; p++) {
   1022         *tris++ = *triangle++;
   1023         *tris++ = *triangle++;
   1024         *tris++ = *triangle++;
   1025     }
   1026     return mesh;
   1027 }
   1028 
   1029 par_shapes_mesh* par_shapes_create_tetrahedron()
   1030 {
   1031     static float verts[4 * 3] = {
   1032         0.000, 1.333, 0,
   1033         0.943, 0, 0,
   1034         -0.471, 0, 0.816,
   1035         -0.471, 0, -0.816,
   1036     };
   1037     static PAR_SHAPES_T triangles[4 * 3] = {
   1038         2,1,0,
   1039         3,2,0,
   1040         1,3,0,
   1041         1,2,3,
   1042     };
   1043     int ntris = sizeof(triangles) / sizeof(triangles[0]) / 3;
   1044     par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
   1045     int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
   1046     mesh->npoints = ncorners;
   1047     mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
   1048     memcpy(mesh->points, verts, sizeof(verts));
   1049     PAR_SHAPES_T const* triangle = triangles;
   1050     mesh->ntriangles = ntris;
   1051     mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
   1052     PAR_SHAPES_T* tris = mesh->triangles;
   1053     for (int p = 0; p < ntris; p++) {
   1054         *tris++ = *triangle++;
   1055         *tris++ = *triangle++;
   1056         *tris++ = *triangle++;
   1057     }
   1058     return mesh;
   1059 }
   1060 
   1061 par_shapes_mesh* par_shapes_create_cube()
   1062 {
   1063     static float verts[8 * 3] = {
   1064         0, 0, 0, // 0
   1065         0, 1, 0, // 1
   1066         1, 1, 0, // 2
   1067         1, 0, 0, // 3
   1068         0, 0, 1, // 4
   1069         0, 1, 1, // 5
   1070         1, 1, 1, // 6
   1071         1, 0, 1, // 7
   1072     };
   1073     static PAR_SHAPES_T quads[6 * 4] = {
   1074         7,6,5,4, // front
   1075         0,1,2,3, // back
   1076         6,7,3,2, // right
   1077         5,6,2,1, // top
   1078         4,5,1,0, // left
   1079         7,4,0,3, // bottom
   1080     };
   1081     int nquads = sizeof(quads) / sizeof(quads[0]) / 4;
   1082     par_shapes_mesh* mesh = PAR_CALLOC(par_shapes_mesh, 1);
   1083     int ncorners = sizeof(verts) / sizeof(verts[0]) / 3;
   1084     mesh->npoints = ncorners;
   1085     mesh->points = PAR_MALLOC(float, mesh->npoints * 3);
   1086     memcpy(mesh->points, verts, sizeof(verts));
   1087     PAR_SHAPES_T const* quad = quads;
   1088     mesh->ntriangles = nquads * 2;
   1089     mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
   1090     PAR_SHAPES_T* tris = mesh->triangles;
   1091     for (int p = 0; p < nquads; p++, quad += 4) {
   1092         *tris++ = quad[0];
   1093         *tris++ = quad[1];
   1094         *tris++ = quad[2];
   1095         *tris++ = quad[2];
   1096         *tris++ = quad[3];
   1097         *tris++ = quad[0];
   1098     }
   1099     return mesh;
   1100 }
   1101 
   1102 typedef struct {
   1103     char* cmd;
   1104     char* arg;
   1105 } par_shapes__command;
   1106 
   1107 typedef struct {
   1108     char const* name;
   1109     int weight;
   1110     int ncommands;
   1111     par_shapes__command* commands;
   1112 } par_shapes__rule;
   1113 
   1114 typedef struct {
   1115     int pc;
   1116     float position[3];
   1117     float scale[3];
   1118     par_shapes_mesh* orientation;
   1119     par_shapes__rule* rule;
   1120 } par_shapes__stackframe;
   1121 
   1122 static par_shapes__rule* par_shapes__pick_rule(const char* name,
   1123     par_shapes__rule* rules, int nrules)
   1124 {
   1125     par_shapes__rule* rule = 0;
   1126     int total = 0;
   1127     for (int i = 0; i < nrules; i++) {
   1128         rule = rules + i;
   1129         if (!strcmp(rule->name, name)) {
   1130             total += rule->weight;
   1131         }
   1132     }
   1133     float r = (float) rand() / (float) RAND_MAX;
   1134     float t = 0;
   1135     for (int i = 0; i < nrules; i++) {
   1136         rule = rules + i;
   1137         if (!strcmp(rule->name, name)) {
   1138             t += (float) rule->weight / total;
   1139             if (t >= r) {
   1140                 return rule;
   1141             }
   1142         }
   1143     }
   1144     return rule;
   1145 }
   1146 
   1147 static par_shapes_mesh* par_shapes__create_turtle()
   1148 {
   1149     const float xaxis[] = {1, 0, 0};
   1150     const float yaxis[] = {0, 1, 0};
   1151     const float zaxis[] = {0, 0, 1};
   1152     par_shapes_mesh* turtle = PAR_CALLOC(par_shapes_mesh, 1);
   1153     turtle->npoints = 3;
   1154     turtle->points = PAR_CALLOC(float, turtle->npoints * 3);
   1155     par_shapes__copy3(turtle->points + 0, xaxis);
   1156     par_shapes__copy3(turtle->points + 3, yaxis);
   1157     par_shapes__copy3(turtle->points + 6, zaxis);
   1158     return turtle;
   1159 }
   1160 
   1161 static par_shapes_mesh* par_shapes__apply_turtle(par_shapes_mesh* mesh,
   1162     par_shapes_mesh* turtle, float const* pos, float const* scale)
   1163 {
   1164     par_shapes_mesh* m = par_shapes_clone(mesh, 0);
   1165     for (int p = 0; p < m->npoints; p++) {
   1166         float* pt = m->points + p * 3;
   1167         pt[0] *= scale[0];
   1168         pt[1] *= scale[1];
   1169         pt[2] *= scale[2];
   1170         par_shapes__transform3(pt,
   1171             turtle->points + 0, turtle->points + 3, turtle->points + 6);
   1172         pt[0] += pos[0];
   1173         pt[1] += pos[1];
   1174         pt[2] += pos[2];
   1175     }
   1176     return m;
   1177 }
   1178 
   1179 void par_shapes__connect(par_shapes_mesh* scene, par_shapes_mesh* cylinder,
   1180     int slices)
   1181 {
   1182     int stacks = 1;
   1183     int npoints = (slices + 1) * (stacks + 1);
   1184     assert(scene->npoints >= npoints && "Cannot connect to empty scene.");
   1185 
   1186     // Create the new point list.
   1187     npoints = scene->npoints + (slices + 1);
   1188     float* points = PAR_MALLOC(float, npoints * 3);
   1189     memcpy(points, scene->points, sizeof(float) * scene->npoints * 3);
   1190     float* newpts = points + scene->npoints * 3;
   1191     memcpy(newpts, cylinder->points + (slices + 1) * 3,
   1192         sizeof(float) * (slices + 1) * 3);
   1193     PAR_FREE(scene->points);
   1194     scene->points = points;
   1195 
   1196     // Create the new triangle list.
   1197     int ntriangles = scene->ntriangles + 2 * slices * stacks;
   1198     PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, ntriangles * 3);
   1199     memcpy(triangles, scene->triangles,
   1200         sizeof(PAR_SHAPES_T) * scene->ntriangles * 3);
   1201     int v = scene->npoints - (slices + 1);
   1202     PAR_SHAPES_T* face = triangles + scene->ntriangles * 3;
   1203     for (int stack = 0; stack < stacks; stack++) {
   1204         for (int slice = 0; slice < slices; slice++) {
   1205             int next = slice + 1;
   1206             *face++ = v + slice + slices + 1;
   1207             *face++ = v + next;
   1208             *face++ = v + slice;
   1209             *face++ = v + slice + slices + 1;
   1210             *face++ = v + next + slices + 1;
   1211             *face++ = v + next;
   1212         }
   1213         v += slices + 1;
   1214     }
   1215     PAR_FREE(scene->triangles);
   1216     scene->triangles = triangles;
   1217 
   1218     scene->npoints = npoints;
   1219     scene->ntriangles = ntriangles;
   1220 }
   1221 
   1222 par_shapes_mesh* par_shapes_create_lsystem(char const* text, int slices,
   1223     int maxdepth)
   1224 {
   1225     char* program;
   1226     program = PAR_MALLOC(char, strlen(text) + 1);
   1227 
   1228     // The first pass counts the number of rules and commands.
   1229     strcpy(program, text);
   1230     char *cmd = strtok(program, " ");
   1231     int nrules = 1;
   1232     int ncommands = 0;
   1233     while (cmd) {
   1234         char *arg = strtok(0, " ");
   1235         if (!arg) {
   1236             puts("lsystem error: unexpected end of program.");
   1237             break;
   1238         }
   1239         if (!strcmp(cmd, "rule")) {
   1240             nrules++;
   1241         } else {
   1242             ncommands++;
   1243         }
   1244         cmd = strtok(0, " ");
   1245     }
   1246 
   1247     // Allocate space.
   1248     par_shapes__rule* rules = PAR_MALLOC(par_shapes__rule, nrules);
   1249     par_shapes__command* commands = PAR_MALLOC(par_shapes__command, ncommands);
   1250 
   1251     // Initialize the entry rule.
   1252     par_shapes__rule* current_rule = &rules[0];
   1253     par_shapes__command* current_command = &commands[0];
   1254     current_rule->name = "entry";
   1255     current_rule->weight = 1;
   1256     current_rule->ncommands = 0;
   1257     current_rule->commands = current_command;
   1258 
   1259     // The second pass fills in the structures.
   1260     strcpy(program, text);
   1261     cmd = strtok(program, " ");
   1262     while (cmd) {
   1263         char *arg = strtok(0, " ");
   1264         if (!strcmp(cmd, "rule")) {
   1265             current_rule++;
   1266 
   1267             // Split the argument into a rule name and weight.
   1268             char* dot = strchr(arg, '.');
   1269             if (dot) {
   1270                 current_rule->weight = atoi(dot + 1);
   1271                 *dot = 0;
   1272             } else {
   1273                 current_rule->weight = 1;
   1274             }
   1275 
   1276             current_rule->name = arg;
   1277             current_rule->ncommands = 0;
   1278             current_rule->commands = current_command;
   1279         } else {
   1280             current_rule->ncommands++;
   1281             current_command->cmd = cmd;
   1282             current_command->arg = arg;
   1283             current_command++;
   1284         }
   1285         cmd = strtok(0, " ");
   1286     }
   1287 
   1288     // For testing purposes, dump out the parsed program.
   1289     #ifdef TEST_PARSE
   1290     for (int i = 0; i < nrules; i++) {
   1291         par_shapes__rule rule = rules[i];
   1292         printf("rule %s.%d\n", rule.name, rule.weight);
   1293         for (int c = 0; c < rule.ncommands; c++) {
   1294             par_shapes__command cmd = rule.commands[c];
   1295             printf("\t%s %s\n", cmd.cmd, cmd.arg);
   1296         }
   1297     }
   1298     #endif
   1299 
   1300     // Instantiate the aggregated shape and the template shapes.
   1301     par_shapes_mesh* scene = PAR_CALLOC(par_shapes_mesh, 1);
   1302     par_shapes_mesh* tube = par_shapes_create_cylinder(slices, 1);
   1303     par_shapes_mesh* turtle = par_shapes__create_turtle();
   1304 
   1305     // We're not attempting to support texture coordinates and normals
   1306     // with L-systems, so remove them from the template shape.
   1307     PAR_FREE(tube->normals);
   1308     PAR_FREE(tube->tcoords);
   1309     tube->normals = 0;
   1310     tube->tcoords = 0;
   1311 
   1312     const float xaxis[] = {1, 0, 0};
   1313     const float yaxis[] = {0, 1, 0};
   1314     const float zaxis[] = {0, 0, 1};
   1315     const float units[] = {1, 1, 1};
   1316 
   1317     // Execute the L-system program until the stack size is 0.
   1318     par_shapes__stackframe* stack =
   1319         PAR_CALLOC(par_shapes__stackframe, maxdepth);
   1320     int stackptr = 0;
   1321     stack[0].orientation = turtle;
   1322     stack[0].rule = &rules[0];
   1323     par_shapes__copy3(stack[0].scale, units);
   1324     while (stackptr >= 0) {
   1325         par_shapes__stackframe* frame = &stack[stackptr];
   1326         par_shapes__rule* rule = frame->rule;
   1327         par_shapes_mesh* turtle = frame->orientation;
   1328         float* position = frame->position;
   1329         float* scale = frame->scale;
   1330         if (frame->pc >= rule->ncommands) {
   1331             par_shapes_free_mesh(turtle);
   1332             stackptr--;
   1333             continue;
   1334         }
   1335 
   1336         par_shapes__command* cmd = rule->commands + (frame->pc++);
   1337         #ifdef DUMP_TRACE
   1338         printf("%5s %5s %5s:%d  %03d\n", cmd->cmd, cmd->arg, rule->name,
   1339             frame->pc - 1, stackptr);
   1340         #endif
   1341 
   1342         float value;
   1343         if (!strcmp(cmd->cmd, "shape")) {
   1344             par_shapes_mesh* m = par_shapes__apply_turtle(tube, turtle,
   1345                 position, scale);
   1346             if (!strcmp(cmd->arg, "connect")) {
   1347                 par_shapes__connect(scene, m, slices);
   1348             } else {
   1349                 par_shapes_merge(scene, m);
   1350             }
   1351             par_shapes_free_mesh(m);
   1352         } else if (!strcmp(cmd->cmd, "call") && stackptr < maxdepth - 1) {
   1353             rule = par_shapes__pick_rule(cmd->arg, rules, nrules);
   1354             frame = &stack[++stackptr];
   1355             frame->rule = rule;
   1356             frame->orientation = par_shapes_clone(turtle, 0);
   1357             frame->pc = 0;
   1358             par_shapes__copy3(frame->scale, scale);
   1359             par_shapes__copy3(frame->position, position);
   1360             continue;
   1361         } else {
   1362             value = atof(cmd->arg);
   1363             if (!strcmp(cmd->cmd, "rx")) {
   1364                 par_shapes_rotate(turtle, value * PAR_PI / 180.0, xaxis);
   1365             } else if (!strcmp(cmd->cmd, "ry")) {
   1366                 par_shapes_rotate(turtle, value * PAR_PI / 180.0, yaxis);
   1367             } else if (!strcmp(cmd->cmd, "rz")) {
   1368                 par_shapes_rotate(turtle, value * PAR_PI / 180.0, zaxis);
   1369             } else if (!strcmp(cmd->cmd, "tx")) {
   1370                 float vec[3] = {value, 0, 0};
   1371                 float t[3] = {
   1372                     par_shapes__dot3(turtle->points + 0, vec),
   1373                     par_shapes__dot3(turtle->points + 3, vec),
   1374                     par_shapes__dot3(turtle->points + 6, vec)
   1375                 };
   1376                 par_shapes__add3(position, t);
   1377             } else if (!strcmp(cmd->cmd, "ty")) {
   1378                 float vec[3] = {0, value, 0};
   1379                 float t[3] = {
   1380                     par_shapes__dot3(turtle->points + 0, vec),
   1381                     par_shapes__dot3(turtle->points + 3, vec),
   1382                     par_shapes__dot3(turtle->points + 6, vec)
   1383                 };
   1384                 par_shapes__add3(position, t);
   1385             } else if (!strcmp(cmd->cmd, "tz")) {
   1386                 float vec[3] = {0, 0, value};
   1387                 float t[3] = {
   1388                     par_shapes__dot3(turtle->points + 0, vec),
   1389                     par_shapes__dot3(turtle->points + 3, vec),
   1390                     par_shapes__dot3(turtle->points + 6, vec)
   1391                 };
   1392                 par_shapes__add3(position, t);
   1393             } else if (!strcmp(cmd->cmd, "sx")) {
   1394                 scale[0] *= value;
   1395             } else if (!strcmp(cmd->cmd, "sy")) {
   1396                 scale[1] *= value;
   1397             } else if (!strcmp(cmd->cmd, "sz")) {
   1398                 scale[2] *= value;
   1399             } else if (!strcmp(cmd->cmd, "sa")) {
   1400                 scale[0] *= value;
   1401                 scale[1] *= value;
   1402                 scale[2] *= value;
   1403             }
   1404         }
   1405     }
   1406     PAR_FREE(stack);
   1407     PAR_FREE(program);
   1408     PAR_FREE(rules);
   1409     PAR_FREE(commands);
   1410     return scene;
   1411 }
   1412 
   1413 void par_shapes_unweld(par_shapes_mesh* mesh, bool create_indices)
   1414 {
   1415     int npoints = mesh->ntriangles * 3;
   1416     float* points = PAR_MALLOC(float, 3 * npoints);
   1417     float* dst = points;
   1418     PAR_SHAPES_T const* index = mesh->triangles;
   1419     for (int i = 0; i < npoints; i++) {
   1420         float const* src = mesh->points + 3 * (*index++);
   1421         *dst++ = src[0];
   1422         *dst++ = src[1];
   1423         *dst++ = src[2];
   1424     }
   1425     PAR_FREE(mesh->points);
   1426     mesh->points = points;
   1427     mesh->npoints = npoints;
   1428     if (create_indices) {
   1429         PAR_SHAPES_T* tris = PAR_MALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
   1430         PAR_SHAPES_T* index = tris;
   1431         for (int i = 0; i < mesh->ntriangles * 3; i++) {
   1432             *index++ = i;
   1433         }
   1434         PAR_FREE(mesh->triangles);
   1435         mesh->triangles = tris;
   1436     }
   1437 }
   1438 
   1439 void par_shapes_compute_normals(par_shapes_mesh* m)
   1440 {
   1441     PAR_FREE(m->normals);
   1442     m->normals = PAR_CALLOC(float, m->npoints * 3);
   1443     PAR_SHAPES_T const* triangle = m->triangles;
   1444     float next[3], prev[3], cp[3];
   1445     for (int f = 0; f < m->ntriangles; f++, triangle += 3) {
   1446         float const* pa = m->points + 3 * triangle[0];
   1447         float const* pb = m->points + 3 * triangle[1];
   1448         float const* pc = m->points + 3 * triangle[2];
   1449         par_shapes__copy3(next, pb);
   1450         par_shapes__subtract3(next, pa);
   1451         par_shapes__copy3(prev, pc);
   1452         par_shapes__subtract3(prev, pa);
   1453         par_shapes__cross3(cp, next, prev);
   1454         par_shapes__add3(m->normals + 3 * triangle[0], cp);
   1455         par_shapes__copy3(next, pc);
   1456         par_shapes__subtract3(next, pb);
   1457         par_shapes__copy3(prev, pa);
   1458         par_shapes__subtract3(prev, pb);
   1459         par_shapes__cross3(cp, next, prev);
   1460         par_shapes__add3(m->normals + 3 * triangle[1], cp);
   1461         par_shapes__copy3(next, pa);
   1462         par_shapes__subtract3(next, pc);
   1463         par_shapes__copy3(prev, pb);
   1464         par_shapes__subtract3(prev, pc);
   1465         par_shapes__cross3(cp, next, prev);
   1466         par_shapes__add3(m->normals + 3 * triangle[2], cp);
   1467     }
   1468     float* normal = m->normals;
   1469     for (int p = 0; p < m->npoints; p++, normal += 3) {
   1470         par_shapes__normalize3(normal);
   1471     }
   1472 }
   1473 
   1474 static void par_shapes__subdivide(par_shapes_mesh* mesh)
   1475 {
   1476     assert(mesh->npoints == mesh->ntriangles * 3 && "Must be unwelded.");
   1477     int ntriangles = mesh->ntriangles * 4;
   1478     int npoints = ntriangles * 3;
   1479     float* points = PAR_CALLOC(float, npoints * 3);
   1480     float* dpoint = points;
   1481     float const* spoint = mesh->points;
   1482     for (int t = 0; t < mesh->ntriangles; t++, spoint += 9, dpoint += 3) {
   1483         float const* a = spoint;
   1484         float const* b = spoint + 3;
   1485         float const* c = spoint + 6;
   1486         float const* p0 = dpoint;
   1487         float const* p1 = dpoint + 3;
   1488         float const* p2 = dpoint + 6;
   1489         par_shapes__mix3(dpoint, a, b, 0.5);
   1490         par_shapes__mix3(dpoint += 3, b, c, 0.5);
   1491         par_shapes__mix3(dpoint += 3, a, c, 0.5);
   1492         par_shapes__add3(dpoint += 3, a);
   1493         par_shapes__add3(dpoint += 3, p0);
   1494         par_shapes__add3(dpoint += 3, p2);
   1495         par_shapes__add3(dpoint += 3, p0);
   1496         par_shapes__add3(dpoint += 3, b);
   1497         par_shapes__add3(dpoint += 3, p1);
   1498         par_shapes__add3(dpoint += 3, p2);
   1499         par_shapes__add3(dpoint += 3, p1);
   1500         par_shapes__add3(dpoint += 3, c);
   1501     }
   1502     PAR_FREE(mesh->points);
   1503     mesh->points = points;
   1504     mesh->npoints = npoints;
   1505     mesh->ntriangles = ntriangles;
   1506 }
   1507 
   1508 par_shapes_mesh* par_shapes_create_subdivided_sphere(int nsubd)
   1509 {
   1510     par_shapes_mesh* mesh = par_shapes_create_icosahedron();
   1511     par_shapes_unweld(mesh, false);
   1512     PAR_FREE(mesh->triangles);
   1513     mesh->triangles = 0;
   1514     while (nsubd--) {
   1515         par_shapes__subdivide(mesh);
   1516     }
   1517     for (int i = 0; i < mesh->npoints; i++) {
   1518         par_shapes__normalize3(mesh->points + i * 3);
   1519     }
   1520     mesh->triangles = PAR_MALLOC(PAR_SHAPES_T, 3 * mesh->ntriangles);
   1521     for (int i = 0; i < mesh->ntriangles * 3; i++) {
   1522         mesh->triangles[i] = i;
   1523     }
   1524     par_shapes_mesh* tmp = mesh;
   1525     mesh = par_shapes_weld(mesh, 0.01, 0);
   1526     par_shapes_free_mesh(tmp);
   1527     par_shapes_compute_normals(mesh);
   1528     return mesh;
   1529 }
   1530 
   1531 par_shapes_mesh* par_shapes_create_rock(int seed, int subd)
   1532 {
   1533     par_shapes_mesh* mesh = par_shapes_create_subdivided_sphere(subd);
   1534     struct osn_context* ctx;
   1535     par__simplex_noise(seed, &ctx);
   1536     for (int p = 0; p < mesh->npoints; p++) {
   1537         float* pt = mesh->points + p * 3;
   1538         float a = 0.25, f = 1.0;
   1539         double n = a * par__simplex_noise2(ctx, f * pt[0], f * pt[2]);
   1540         a *= 0.5; f *= 2;
   1541         n += a * par__simplex_noise2(ctx, f * pt[0], f * pt[2]);
   1542         pt[0] *= 1 + 2 * n;
   1543         pt[1] *= 1 + n;
   1544         pt[2] *= 1 + 2 * n;
   1545         if (pt[1] < 0) {
   1546             pt[1] = -pow(-pt[1], 0.5) / 2;
   1547         }
   1548     }
   1549     par__simplex_noise_free(ctx);
   1550     par_shapes_compute_normals(mesh);
   1551     return mesh;
   1552 }
   1553 
   1554 par_shapes_mesh* par_shapes_clone(par_shapes_mesh const* mesh,
   1555     par_shapes_mesh* clone)
   1556 {
   1557     if (!clone) {
   1558         clone = PAR_CALLOC(par_shapes_mesh, 1);
   1559     }
   1560     clone->npoints = mesh->npoints;
   1561     clone->points = PAR_REALLOC(float, clone->points, 3 * clone->npoints);
   1562     memcpy(clone->points, mesh->points, sizeof(float) * 3 * clone->npoints);
   1563     clone->ntriangles = mesh->ntriangles;
   1564     clone->triangles = PAR_REALLOC(PAR_SHAPES_T, clone->triangles, 3 *
   1565         clone->ntriangles);
   1566     memcpy(clone->triangles, mesh->triangles,
   1567         sizeof(PAR_SHAPES_T) * 3 * clone->ntriangles);
   1568     if (mesh->normals) {
   1569         clone->normals = PAR_REALLOC(float, clone->normals, 3 * clone->npoints);
   1570         memcpy(clone->normals, mesh->normals,
   1571             sizeof(float) * 3 * clone->npoints);
   1572     }
   1573     if (mesh->tcoords) {
   1574         clone->tcoords = PAR_REALLOC(float, clone->tcoords, 2 * clone->npoints);
   1575         memcpy(clone->tcoords, mesh->tcoords,
   1576             sizeof(float) * 2 * clone->npoints);
   1577     }
   1578     return clone;
   1579 }
   1580 
   1581 static struct {
   1582     float const* points;
   1583     int gridsize;
   1584 } par_shapes__sort_context;
   1585 
   1586 static int par_shapes__cmp1(const void *arg0, const void *arg1)
   1587 {
   1588     const int g = par_shapes__sort_context.gridsize;
   1589 
   1590     // Convert arg0 into a flattened grid index.
   1591     PAR_SHAPES_T d0 = *(const PAR_SHAPES_T*) arg0;
   1592     float const* p0 = par_shapes__sort_context.points + d0 * 3;
   1593     int i0 = (int) p0[0];
   1594     int j0 = (int) p0[1];
   1595     int k0 = (int) p0[2];
   1596     int index0 = i0 + g * j0 + g * g * k0;
   1597 
   1598     // Convert arg1 into a flattened grid index.
   1599     PAR_SHAPES_T d1 = *(const PAR_SHAPES_T*) arg1;
   1600     float const* p1 = par_shapes__sort_context.points + d1 * 3;
   1601     int i1 = (int) p1[0];
   1602     int j1 = (int) p1[1];
   1603     int k1 = (int) p1[2];
   1604     int index1 = i1 + g * j1 + g * g * k1;
   1605 
   1606     // Return the ordering.
   1607     if (index0 < index1) return -1;
   1608     if (index0 > index1) return 1;
   1609     return 0;
   1610 }
   1611 
   1612 static void par_shapes__sort_points(par_shapes_mesh* mesh, int gridsize,
   1613     PAR_SHAPES_T* sortmap)
   1614 {
   1615     // Run qsort over a list of consecutive integers that get deferenced
   1616     // within the comparator function; this creates a reorder mapping.
   1617     for (int i = 0; i < mesh->npoints; i++) {
   1618         sortmap[i] = i;
   1619     }
   1620     par_shapes__sort_context.gridsize = gridsize;
   1621     par_shapes__sort_context.points = mesh->points;
   1622     qsort(sortmap, mesh->npoints, sizeof(PAR_SHAPES_T), par_shapes__cmp1);
   1623 
   1624     // Apply the reorder mapping to the XYZ coordinate data.
   1625     float* newpts = PAR_MALLOC(float, mesh->npoints * 3);
   1626     PAR_SHAPES_T* invmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
   1627     float* dstpt = newpts;
   1628     for (int i = 0; i < mesh->npoints; i++) {
   1629         invmap[sortmap[i]] = i;
   1630         float const* srcpt = mesh->points + 3 * sortmap[i];
   1631         *dstpt++ = *srcpt++;
   1632         *dstpt++ = *srcpt++;
   1633         *dstpt++ = *srcpt++;
   1634     }
   1635     PAR_FREE(mesh->points);
   1636     mesh->points = newpts;
   1637 
   1638     // Apply the inverse reorder mapping to the triangle indices.
   1639     PAR_SHAPES_T* newinds = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
   1640     PAR_SHAPES_T* dstind = newinds;
   1641     PAR_SHAPES_T const* srcind = mesh->triangles;
   1642     for (int i = 0; i < mesh->ntriangles * 3; i++) {
   1643         *dstind++ = invmap[*srcind++];
   1644     }
   1645     PAR_FREE(mesh->triangles);
   1646     mesh->triangles = newinds;
   1647 
   1648     // Cleanup.
   1649     memcpy(sortmap, invmap, sizeof(PAR_SHAPES_T) * mesh->npoints);
   1650     PAR_FREE(invmap);
   1651 }
   1652 
   1653 static void par_shapes__weld_points(par_shapes_mesh* mesh, int gridsize,
   1654     float epsilon, PAR_SHAPES_T* weldmap)
   1655 {
   1656     // Each bin contains a "pointer" (really an index) to its first point.
   1657     // We add 1 because 0 is reserved to mean that the bin is empty.
   1658     // Since the points are spatially sorted, there's no need to store
   1659     // a point count in each bin.
   1660     PAR_SHAPES_T* bins = PAR_CALLOC(PAR_SHAPES_T,
   1661         gridsize * gridsize * gridsize);
   1662     int prev_binindex = -1;
   1663     for (int p = 0; p < mesh->npoints; p++) {
   1664         float const* pt = mesh->points + p * 3;
   1665         int i = (int) pt[0];
   1666         int j = (int) pt[1];
   1667         int k = (int) pt[2];
   1668         int this_binindex = i + gridsize * j + gridsize * gridsize * k;
   1669         if (this_binindex != prev_binindex) {
   1670             bins[this_binindex] = 1 + p;
   1671         }
   1672         prev_binindex = this_binindex;
   1673     }
   1674 
   1675     // Examine all bins that intersect the epsilon-sized cube centered at each
   1676     // point, and check for colocated points within those bins.
   1677     float const* pt = mesh->points;
   1678     int nremoved = 0;
   1679     for (int p = 0; p < mesh->npoints; p++, pt += 3) {
   1680 
   1681         // Skip if this point has already been welded.
   1682         if (weldmap[p] != p) {
   1683             continue;
   1684         }
   1685 
   1686         // Build a list of bins that intersect the epsilon-sized cube.
   1687         int nearby[8];
   1688         int nbins = 0;
   1689         int minp[3], maxp[3];
   1690         for (int c = 0; c < 3; c++) {
   1691             minp[c] = (int) (pt[c] - epsilon);
   1692             maxp[c] = (int) (pt[c] + epsilon);
   1693         }
   1694         for (int i = minp[0]; i <= maxp[0]; i++) {
   1695             for (int j = minp[1]; j <= maxp[1]; j++) {
   1696                 for (int k = minp[2]; k <= maxp[2]; k++) {
   1697                     int binindex = i + gridsize * j + gridsize * gridsize * k;
   1698                     PAR_SHAPES_T binvalue = *(bins + binindex);
   1699                     if (binvalue > 0) {
   1700                         if (nbins == 8) {
   1701                             printf("Epsilon value is too large.\n");
   1702                             break;
   1703                         }
   1704                         nearby[nbins++] = binindex;
   1705                     }
   1706                 }
   1707             }
   1708         }
   1709 
   1710         // Check for colocated points in each nearby bin.
   1711         for (int b = 0; b < nbins; b++) {
   1712             int binindex = nearby[b];
   1713             PAR_SHAPES_T binvalue = bins[binindex];
   1714             PAR_SHAPES_T nindex = binvalue - 1;
   1715             assert(nindex < mesh->npoints);
   1716             while (true) {
   1717 
   1718                 // If this isn't "self" and it's colocated, then weld it!
   1719                 if (nindex != p && weldmap[nindex] == nindex) {
   1720                     float const* thatpt = mesh->points + nindex * 3;
   1721                     float dist2 = par_shapes__sqrdist3(thatpt, pt);
   1722                     if (dist2 < epsilon) {
   1723                         weldmap[nindex] = p;
   1724                         nremoved++;
   1725                     }
   1726                 }
   1727 
   1728                 // Advance to the next point if possible.
   1729                 if (++nindex >= mesh->npoints) {
   1730                     break;
   1731                 }
   1732 
   1733                 // If the next point is outside the bin, then we're done.
   1734                 float const* nextpt = mesh->points + nindex * 3;
   1735                 int i = (int) nextpt[0];
   1736                 int j = (int) nextpt[1];
   1737                 int k = (int) nextpt[2];
   1738                 int nextbinindex = i + gridsize * j + gridsize * gridsize * k;
   1739                 if (nextbinindex != binindex) {
   1740                     break;
   1741                 }
   1742             }
   1743         }
   1744     }
   1745     PAR_FREE(bins);
   1746 
   1747     // Apply the weldmap to the vertices.
   1748     int npoints = mesh->npoints - nremoved;
   1749     float* newpts = PAR_MALLOC(float, 3 * npoints);
   1750     float* dst = newpts;
   1751     PAR_SHAPES_T* condensed_map = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
   1752     PAR_SHAPES_T* cmap = condensed_map;
   1753     float const* src = mesh->points;
   1754     int ci = 0;
   1755     for (int p = 0; p < mesh->npoints; p++, src += 3) {
   1756         if (weldmap[p] == p) {
   1757             *dst++ = src[0];
   1758             *dst++ = src[1];
   1759             *dst++ = src[2];
   1760             *cmap++ = ci++;
   1761         } else {
   1762             *cmap++ = condensed_map[weldmap[p]];
   1763         }
   1764     }
   1765     assert(ci == npoints);
   1766     PAR_FREE(mesh->points);
   1767     memcpy(weldmap, condensed_map, mesh->npoints * sizeof(PAR_SHAPES_T));
   1768     PAR_FREE(condensed_map);
   1769     mesh->points = newpts;
   1770     mesh->npoints = npoints;
   1771 
   1772     // Apply the weldmap to the triangle indices and skip the degenerates.
   1773     PAR_SHAPES_T const* tsrc = mesh->triangles;
   1774     PAR_SHAPES_T* tdst = mesh->triangles;
   1775     int ntriangles = 0;
   1776     for (int i = 0; i < mesh->ntriangles; i++, tsrc += 3) {
   1777         PAR_SHAPES_T a = weldmap[tsrc[0]];
   1778         PAR_SHAPES_T b = weldmap[tsrc[1]];
   1779         PAR_SHAPES_T c = weldmap[tsrc[2]];
   1780         if (a != b && a != c && b != c) {
   1781             assert(a < mesh->npoints);
   1782             assert(b < mesh->npoints);
   1783             assert(c < mesh->npoints);
   1784             *tdst++ = a;
   1785             *tdst++ = b;
   1786             *tdst++ = c;
   1787             ntriangles++;
   1788         }
   1789     }
   1790     mesh->ntriangles = ntriangles;
   1791 }
   1792 
   1793 par_shapes_mesh* par_shapes_weld(par_shapes_mesh const* mesh, float epsilon,
   1794     PAR_SHAPES_T* weldmap)
   1795 {
   1796     par_shapes_mesh* clone = par_shapes_clone(mesh, 0);
   1797     float aabb[6];
   1798     int gridsize = 20;
   1799     float maxcell = gridsize - 1;
   1800     par_shapes_compute_aabb(clone, aabb);
   1801     float scale[3] = {
   1802         aabb[3] == aabb[0] ? 1.0f : maxcell / (aabb[3] - aabb[0]),
   1803         aabb[4] == aabb[1] ? 1.0f : maxcell / (aabb[4] - aabb[1]),
   1804         aabb[5] == aabb[2] ? 1.0f : maxcell / (aabb[5] - aabb[2]),
   1805     };
   1806     par_shapes_translate(clone, -aabb[0], -aabb[1], -aabb[2]);
   1807     par_shapes_scale(clone, scale[0], scale[1], scale[2]);
   1808     PAR_SHAPES_T* sortmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
   1809     par_shapes__sort_points(clone, gridsize, sortmap);
   1810     bool owner = false;
   1811     if (!weldmap) {
   1812         owner = true;
   1813         weldmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
   1814     }
   1815     for (int i = 0; i < mesh->npoints; i++) {
   1816         weldmap[i] = i;
   1817     }
   1818     par_shapes__weld_points(clone, gridsize, epsilon, weldmap);
   1819     if (owner) {
   1820         PAR_FREE(weldmap);
   1821     } else {
   1822         PAR_SHAPES_T* newmap = PAR_MALLOC(PAR_SHAPES_T, mesh->npoints);
   1823         for (int i = 0; i < mesh->npoints; i++) {
   1824             newmap[i] = weldmap[sortmap[i]];
   1825         }
   1826         memcpy(weldmap, newmap, sizeof(PAR_SHAPES_T) * mesh->npoints);
   1827         PAR_FREE(newmap);
   1828     }
   1829     PAR_FREE(sortmap);
   1830     par_shapes_scale(clone, 1.0 / scale[0], 1.0 / scale[1], 1.0 / scale[2]);
   1831     par_shapes_translate(clone, aabb[0], aabb[1], aabb[2]);
   1832     return clone;
   1833 }
   1834 
   1835 // -----------------------------------------------------------------------------
   1836 // BEGIN OPEN SIMPLEX NOISE
   1837 // -----------------------------------------------------------------------------
   1838 
   1839 #define STRETCH_CONSTANT_2D (-0.211324865405187)  // (1 / sqrt(2 + 1) - 1 ) / 2;
   1840 #define SQUISH_CONSTANT_2D (0.366025403784439)  // (sqrt(2 + 1) -1) / 2;
   1841 #define STRETCH_CONSTANT_3D (-1.0 / 6.0)  // (1 / sqrt(3 + 1) - 1) / 3;
   1842 #define SQUISH_CONSTANT_3D (1.0 / 3.0)  // (sqrt(3+1)-1)/3;
   1843 #define STRETCH_CONSTANT_4D (-0.138196601125011)  // (1 / sqrt(4 + 1) - 1) / 4;
   1844 #define SQUISH_CONSTANT_4D (0.309016994374947)  // (sqrt(4 + 1) - 1) / 4;
   1845 
   1846 #define NORM_CONSTANT_2D (47.0)
   1847 #define NORM_CONSTANT_3D (103.0)
   1848 #define NORM_CONSTANT_4D (30.0)
   1849 
   1850 #define DEFAULT_SEED (0LL)
   1851 
   1852 struct osn_context {
   1853     int16_t* perm;
   1854     int16_t* permGradIndex3D;
   1855 };
   1856 
   1857 #define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0]))
   1858 
   1859 /*
   1860  * Gradients for 2D. They approximate the directions to the
   1861  * vertices of an octagon from the center.
   1862  */
   1863 static const int8_t gradients2D[] = {
   1864     5, 2, 2, 5, -5, 2, -2, 5, 5, -2, 2, -5, -5, -2, -2, -5,
   1865 };
   1866 
   1867 /*
   1868  * Gradients for 3D. They approximate the directions to the
   1869  * vertices of a rhombicuboctahedron from the center, skewed so
   1870  * that the triangular and square facets can be inscribed inside
   1871  * circles of the same radius.
   1872  */
   1873 static const signed char gradients3D[] = {
   1874     -11, 4, 4, -4, 11, 4, -4, 4, 11, 11, 4, 4, 4, 11, 4, 4, 4, 11, -11, -4, 4,
   1875     -4, -11, 4, -4, -4, 11, 11, -4, 4, 4, -11, 4, 4, -4, 11, -11, 4, -4, -4, 11,
   1876     -4, -4, 4, -11, 11, 4, -4, 4, 11, -4, 4, 4, -11, -11, -4, -4, -4, -11, -4,
   1877     -4, -4, -11, 11, -4, -4, 4, -11, -4, 4, -4, -11,
   1878 };
   1879 
   1880 /*
   1881  * Gradients for 4D. They approximate the directions to the
   1882  * vertices of a disprismatotesseractihexadecachoron from the center,
   1883  * skewed so that the tetrahedral and cubic facets can be inscribed inside
   1884  * spheres of the same radius.
   1885  */
   1886 static const signed char gradients4D[] = {
   1887     3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, -3, 1, 1, 1, -1, 3, 1, 1,
   1888     -1, 1, 3, 1, -1, 1, 1, 3, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1,
   1889     3, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, 3, 1, -1, 1, 1,
   1890     3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3,
   1891     1, -1, 1, -1, 3, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, -3,
   1892     -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, 3, 1, 1, -1, 1, 3,
   1893     1, -1, 1, 1, 3, -1, 1, 1, 1, -3, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1,
   1894     -1, 1, 1, -3, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, -3,
   1895     -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, 3, 1, -1, -1, 1, 3,
   1896     -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3,
   1897     -1, -1, 1, -1, -3, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1,
   1898     -3, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3,
   1899 };
   1900 
   1901 static double extrapolate2(
   1902     struct osn_context* ctx, int xsb, int ysb, double dx, double dy)
   1903 {
   1904     int16_t* perm = ctx->perm;
   1905     int index = perm[(perm[xsb & 0xFF] + ysb) & 0xFF] & 0x0E;
   1906     return gradients2D[index] * dx + gradients2D[index + 1] * dy;
   1907 }
   1908 
   1909 static inline int fastFloor(double x)
   1910 {
   1911     int xi = (int) x;
   1912     return x < xi ? xi - 1 : xi;
   1913 }
   1914 
   1915 static int allocate_perm(struct osn_context* ctx, int nperm, int ngrad)
   1916 {
   1917     PAR_FREE(ctx->perm);
   1918     PAR_FREE(ctx->permGradIndex3D);
   1919     ctx->perm = PAR_MALLOC(int16_t, nperm);
   1920     if (!ctx->perm) {
   1921         return -ENOMEM;
   1922     }
   1923     ctx->permGradIndex3D = PAR_MALLOC(int16_t, ngrad);
   1924     if (!ctx->permGradIndex3D) {
   1925         PAR_FREE(ctx->perm);
   1926         return -ENOMEM;
   1927     }
   1928     return 0;
   1929 }
   1930 
   1931 static int par__simplex_noise(int64_t seed, struct osn_context** ctx)
   1932 {
   1933     int rc;
   1934     int16_t source[256];
   1935     int i;
   1936     int16_t* perm;
   1937     int16_t* permGradIndex3D;
   1938     *ctx = PAR_MALLOC(struct osn_context, 1);
   1939     if (!(*ctx)) {
   1940         return -ENOMEM;
   1941     }
   1942     (*ctx)->perm = NULL;
   1943     (*ctx)->permGradIndex3D = NULL;
   1944     rc = allocate_perm(*ctx, 256, 256);
   1945     if (rc) {
   1946         PAR_FREE(*ctx);
   1947         return rc;
   1948     }
   1949     perm = (*ctx)->perm;
   1950     permGradIndex3D = (*ctx)->permGradIndex3D;
   1951     for (i = 0; i < 256; i++) {
   1952         source[i] = (int16_t) i;
   1953     }
   1954     seed = seed * 6364136223846793005LL + 1442695040888963407LL;
   1955     seed = seed * 6364136223846793005LL + 1442695040888963407LL;
   1956     seed = seed * 6364136223846793005LL + 1442695040888963407LL;
   1957     for (i = 255; i >= 0; i--) {
   1958         seed = seed * 6364136223846793005LL + 1442695040888963407LL;
   1959         int r = (int) ((seed + 31) % (i + 1));
   1960         if (r < 0)
   1961             r += (i + 1);
   1962         perm[i] = source[r];
   1963         permGradIndex3D[i] =
   1964             (short) ((perm[i] % (ARRAYSIZE(gradients3D) / 3)) * 3);
   1965         source[r] = source[i];
   1966     }
   1967     return 0;
   1968 }
   1969 
   1970 static void par__simplex_noise_free(struct osn_context* ctx)
   1971 {
   1972     if (!ctx)
   1973         return;
   1974     if (ctx->perm) {
   1975         PAR_FREE(ctx->perm);
   1976         ctx->perm = NULL;
   1977     }
   1978     if (ctx->permGradIndex3D) {
   1979         PAR_FREE(ctx->permGradIndex3D);
   1980         ctx->permGradIndex3D = NULL;
   1981     }
   1982     PAR_FREE(ctx);
   1983 }
   1984 
   1985 static double par__simplex_noise2(struct osn_context* ctx, double x, double y)
   1986 {
   1987     // Place input coordinates onto grid.
   1988     double stretchOffset = (x + y) * STRETCH_CONSTANT_2D;
   1989     double xs = x + stretchOffset;
   1990     double ys = y + stretchOffset;
   1991 
   1992     // Floor to get grid coordinates of rhombus (stretched square) super-cell
   1993     // origin.
   1994     int xsb = fastFloor(xs);
   1995     int ysb = fastFloor(ys);
   1996 
   1997     // Skew out to get actual coordinates of rhombus origin. We'll need these
   1998     // later.
   1999     double squishOffset = (xsb + ysb) * SQUISH_CONSTANT_2D;
   2000     double xb = xsb + squishOffset;
   2001     double yb = ysb + squishOffset;
   2002 
   2003     // Compute grid coordinates relative to rhombus origin.
   2004     double xins = xs - xsb;
   2005     double yins = ys - ysb;
   2006 
   2007     // Sum those together to get a value that determines which region we're in.
   2008     double inSum = xins + yins;
   2009 
   2010     // Positions relative to origin point.
   2011     double dx0 = x - xb;
   2012     double dy0 = y - yb;
   2013 
   2014     // We'll be defining these inside the next block and using them afterwards.
   2015     double dx_ext, dy_ext;
   2016     int xsv_ext, ysv_ext;
   2017 
   2018     double value = 0;
   2019 
   2020     // Contribution (1,0)
   2021     double dx1 = dx0 - 1 - SQUISH_CONSTANT_2D;
   2022     double dy1 = dy0 - 0 - SQUISH_CONSTANT_2D;
   2023     double attn1 = 2 - dx1 * dx1 - dy1 * dy1;
   2024     if (attn1 > 0) {
   2025         attn1 *= attn1;
   2026         value += attn1 * attn1 * extrapolate2(ctx, xsb + 1, ysb + 0, dx1, dy1);
   2027     }
   2028 
   2029     // Contribution (0,1)
   2030     double dx2 = dx0 - 0 - SQUISH_CONSTANT_2D;
   2031     double dy2 = dy0 - 1 - SQUISH_CONSTANT_2D;
   2032     double attn2 = 2 - dx2 * dx2 - dy2 * dy2;
   2033     if (attn2 > 0) {
   2034         attn2 *= attn2;
   2035         value += attn2 * attn2 * extrapolate2(ctx, xsb + 0, ysb + 1, dx2, dy2);
   2036     }
   2037 
   2038     if (inSum <= 1) {  // We're inside the triangle (2-Simplex) at (0,0)
   2039         double zins = 1 - inSum;
   2040         if (zins > xins || zins > yins) {
   2041             if (xins > yins) {
   2042                 xsv_ext = xsb + 1;
   2043                 ysv_ext = ysb - 1;
   2044                 dx_ext = dx0 - 1;
   2045                 dy_ext = dy0 + 1;
   2046             } else {
   2047                 xsv_ext = xsb - 1;
   2048                 ysv_ext = ysb + 1;
   2049                 dx_ext = dx0 + 1;
   2050                 dy_ext = dy0 - 1;
   2051             }
   2052         } else {  //(1,0) and (0,1) are the closest two vertices.
   2053             xsv_ext = xsb + 1;
   2054             ysv_ext = ysb + 1;
   2055             dx_ext = dx0 - 1 - 2 * SQUISH_CONSTANT_2D;
   2056             dy_ext = dy0 - 1 - 2 * SQUISH_CONSTANT_2D;
   2057         }
   2058     } else {  // We're inside the triangle (2-Simplex) at (1,1)
   2059         double zins = 2 - inSum;
   2060         if (zins < xins || zins < yins) {
   2061             if (xins > yins) {
   2062                 xsv_ext = xsb + 2;
   2063                 ysv_ext = ysb + 0;
   2064                 dx_ext = dx0 - 2 - 2 * SQUISH_CONSTANT_2D;
   2065                 dy_ext = dy0 + 0 - 2 * SQUISH_CONSTANT_2D;
   2066             } else {
   2067                 xsv_ext = xsb + 0;
   2068                 ysv_ext = ysb + 2;
   2069                 dx_ext = dx0 + 0 - 2 * SQUISH_CONSTANT_2D;
   2070                 dy_ext = dy0 - 2 - 2 * SQUISH_CONSTANT_2D;
   2071             }
   2072         } else {  //(1,0) and (0,1) are the closest two vertices.
   2073             dx_ext = dx0;
   2074             dy_ext = dy0;
   2075             xsv_ext = xsb;
   2076             ysv_ext = ysb;
   2077         }
   2078         xsb += 1;
   2079         ysb += 1;
   2080         dx0 = dx0 - 1 - 2 * SQUISH_CONSTANT_2D;
   2081         dy0 = dy0 - 1 - 2 * SQUISH_CONSTANT_2D;
   2082     }
   2083 
   2084     // Contribution (0,0) or (1,1)
   2085     double attn0 = 2 - dx0 * dx0 - dy0 * dy0;
   2086     if (attn0 > 0) {
   2087         attn0 *= attn0;
   2088         value += attn0 * attn0 * extrapolate2(ctx, xsb, ysb, dx0, dy0);
   2089     }
   2090 
   2091     // Extra Vertex
   2092     double attn_ext = 2 - dx_ext * dx_ext - dy_ext * dy_ext;
   2093     if (attn_ext > 0) {
   2094         attn_ext *= attn_ext;
   2095         value += attn_ext * attn_ext *
   2096             extrapolate2(ctx, xsv_ext, ysv_ext, dx_ext, dy_ext);
   2097     }
   2098 
   2099     return value / NORM_CONSTANT_2D;
   2100 }
   2101 
   2102 void par_shapes_remove_degenerate(par_shapes_mesh* mesh, float mintriarea)
   2103 {
   2104     int ntriangles = 0;
   2105     PAR_SHAPES_T* triangles = PAR_MALLOC(PAR_SHAPES_T, mesh->ntriangles * 3);
   2106     PAR_SHAPES_T* dst = triangles;
   2107     PAR_SHAPES_T const* src = mesh->triangles;
   2108     float next[3], prev[3], cp[3];
   2109     float mincplen2 = (mintriarea * 2) * (mintriarea * 2);
   2110     for (int f = 0; f < mesh->ntriangles; f++, src += 3) {
   2111         float const* pa = mesh->points + 3 * src[0];
   2112         float const* pb = mesh->points + 3 * src[1];
   2113         float const* pc = mesh->points + 3 * src[2];
   2114         par_shapes__copy3(next, pb);
   2115         par_shapes__subtract3(next, pa);
   2116         par_shapes__copy3(prev, pc);
   2117         par_shapes__subtract3(prev, pa);
   2118         par_shapes__cross3(cp, next, prev);
   2119         float cplen2 = par_shapes__dot3(cp, cp);
   2120         if (cplen2 >= mincplen2) {
   2121             *dst++ = src[0];
   2122             *dst++ = src[1];
   2123             *dst++ = src[2];
   2124             ntriangles++;
   2125         }
   2126     }
   2127     mesh->ntriangles = ntriangles;
   2128     PAR_FREE(mesh->triangles);
   2129     mesh->triangles = triangles;
   2130 }
   2131 
   2132 #endif // PAR_SHAPES_IMPLEMENTATION
   2133 #endif // PAR_SHAPES_H
   2134 
   2135 // par_shapes is distributed under the MIT license:
   2136 //
   2137 // Copyright (c) 2019 Philip Rideout
   2138 //
   2139 // Permission is hereby granted, free of charge, to any person obtaining a copy
   2140 // of this software and associated documentation files (the "Software"), to deal
   2141 // in the Software without restriction, including without limitation the rights
   2142 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   2143 // copies of the Software, and to permit persons to whom the Software is
   2144 // furnished to do so, subject to the following conditions:
   2145 //
   2146 // The above copyright notice and this permission notice shall be included in
   2147 // all copies or substantial portions of the Software.
   2148 //
   2149 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   2150 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   2151 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   2152 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   2153 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   2154 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   2155 // SOFTWARE.