Giter VIP home page Giter VIP logo

par's Introduction

Build Status

par

Single-file C libraries under the MIT license, mostly graphics related. Documentation can be found at the top of each header file, but some libraries have an accompanying blog post. The most useful ones are listed in the following table.

library description link
par_camera_control.h orbit controller, or pan-and-zoom like Google Maps demo project
par_octasphere.h malloc-free mesh gen for spheres and rounded cuboids blog post
par_streamlines.h triangulate wide lines and curves blog post
par_string_blocks.h string manager for snippets of Lua or GLSL
par_shapes.h generate parametric surfaces and other simple shapes blog post

There are more libraries too but they're probably less useful; scroll to the bottom of this README.

tests

To run tests, you need CMake and pkg-config. On macOS, these can be installed with homebrew:

$ brew install cmake pkg-config

Here's how you can tell CMake to use the CMakeLists in the test folder, placing all the messy stuff in a new folder called build.

$ cmake test -Bbuild   # Create makefiles
$ cmake --build build  # Invoke the build

The tests are executed by simply running the programs:

$ build/test_bubbles
$ build/test_shapes
$ build/test_octasphere

code formatting

This library's code style is strictly enforced to be vertically dense (no consecutive newlines) and 100 columns or less.

The tools/format.py script invokes a two-step code formatting process:

  1. Runs uncrustify with our custom configuration. This auto-formats all code in the root folder, up to a point.
  2. Checks for violations that are not otherwise enforced with uncrustify.

The aforementioned Python script is also invoked from Travis, but using the --check option, which checks for conformance without editing the code.

Beyond what our uncrustify configuration enforces, the Python script does the following:

  • Checks that no lines are more than 100 chars.
  • Checks for extra newlines before an end brace.

other libraries

library description link
par_bluenoise.h generate progressive 2D point sequences blog post
par_bubbles.h pack circles into hierarchical diagrams blog post
par_easings.h Robert Penner's easing functions
par_easycurl.h simple HTTP requests using libcurl
par_filecache.h LRU caching on your device's filesystem
par_sprune.h efficient broad-phase collision detection in 2D web demo
par_msquares.h unmaintained marching squares library (do not use) blog post

par's People

Contributors

kecman avatar narendraumate avatar prideout avatar sonoro1234 avatar timgates42 avatar turol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

par's Issues

par_msquares generating too much triangles for uint16_t

par_msquares_grayscale, depending on the image size, threshold value and size value can generate meshes that dont fit in par_msquares_mesh because uint16_t* triangles; instead of uint32_t* triangles;

quick (and dirty?) solution would be to replace all uint16_t occurences in par_msquares with a define that could use uint16_t or uint32_t (similar to par_shapes)

What do you thing?. Shall I do a PR with that?

Warning: implicit conversion from 'int' to 'float' (RAND_MAX)

Hi there,
par_shapes.h:1103:32:

warning: implicit conversion from 'int' to 'float' changes value from 2147483647 to 2147483648 [-Wimplicit-const-int-float-conversion]
note: expanded from macro 'RAND_MAX'

maybe change like this ? or do a c-style cast for RAND_MAX?

// float r = (float) rand() / RAND_MAX;
float r = rand() / (RAND_MAX + 1.0f); // [0, 1)
float r = rand() / (float)RAND_MAX;  // [0, 1]

Variable length array causes compile failure in VS 2015

Hi Philip!

I was trying to check out your par_shapes library but I ran into a problem with compiling it under VS2015's C++ compiler.

c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1107): error C2131: expression did not evaluate to a constant (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1107): note: failure was caused by non-constant arguments or reference to a non-constant symbol (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1107): note: see usage of 'text' (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1129): error C2131: expression did not evaluate to a constant (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1129): note: failure was caused by non-constant arguments or reference to a non-constant symbol (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1129): note: see usage of 'nrules' (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1130): error C2131: expression did not evaluate to a constant (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1130): note: failure was caused by non-constant arguments or reference to a non-constant symbol (compiling source file ..\..\..\src\DebugDraw.cpp)
c:\cygwin64\home\dale kim\sjgame1\src\par_shapes.h(1130): note: see usage of 'ncommands' (compiling source file ..\..\..\src\DebugDraw.cpp)

This occurs due to the use of variable length arrays in the par_shapes_create_lsystem() function. For now, I've continued to check out your library by commenting out that function entirely (I don't need it).

From what I've gathered, this is allowable under ISO C99, but not under C90 or any version of C++ (unless using extensions in gcc).

Library looks pretty awesome, thanks for making it!

-Dale Kim

[Question] par_* library version?

I saw no version is assigned to any of the libraries. I know it's just a formalism but it would be nice to have a version assigned.

Possible error in fread call in par_bluenoise

In par_bluenoise.h line 337 the code does:

int consumed = (int) fread(buf, nbytes, 1, fin);
assert(consumed == nbytes);

I believe that fread is defined to be something akin to:

size_t fread(void *ptr, size_t size, size_t count, FILE *stream);

Note the order of the size (of a single element, in bytes) and count (number of elements to read).

This means that the call to fread as you have it, is reading a single element of nbytes size. The end-result is pretty much the same from a bytes in memory point of view. But for the assert immediately following it, it's a bit of a problem (since nconsumed will be equal to 1.)

(I'd send you a pull request instead, but I don't have a great git setup at hand, and the fix is rather easy anyway. That is, if I'm not mistaken of course.)

Thanks,

Jaap Suter - http://jaapsuter.com

shapes: Division by zero in par_shapes_weld

The function par_shapes_weld computes a scale factor based on the mesh AABB. This computation may produce NaNs (and does for par_shapes_create_plane) when the input mesh is "flat", i.e. the AABB has zero width on at least one axis.

A simple fix could be:

float scale[3] = {
    aabb[3] == aabb[0] ? 1.0 : maxcell / (aabb[3] - aabb[0]),
    aabb[4] == aabb[1] ? 1.0 : maxcell / (aabb[4] - aabb[1]),
    aabb[5] == aabb[2] ? 1.0 : maxcell / (aabb[5] - aabb[2]),
};

[shapes] Support texture coordinates

I've noticed that default texture coordinates are not being generated for some shapes. It would be great some default texture coordinates could be generated, at least for basic meshes (cube, cillinder, torus...).

Or maybe provide some function to generate texture coordinates, like normals generation.

Congrats for the library, it's amazing! I'm planning to add meshes generation to raylib using it! :)

EDIT: Just seen sphere provides texcoords, miss it for cube and other basic shapes...

Issue on OSX

Everything builds and runs fine, but at certain parts has a segfault of 11.
Here are the test infos:

bubbles


  par_bubbles_pack
Segmentation fault: 11

shapes


  cylinders and spheres
    ✓ should fail when the number of stacks or slices is invalid
    ✓ should generate correct number of vertices
    ✓ should have expected number of triangles


  par_shapes_create_plane
    ✓ should not have NaN's


  par_shapes_export
Segmentation fault: 11

sprune


  par_sprune_overlap
box0 collides with box1
There are now 3 collisions.
Segmentation fault: 11

bluenoise works fine, test_linker outputs nothing. test_cpp does nothing.

the file cache tests both work fine and produce the same output.

I tried squares twice, and one time it downloaded the assets and then had a segmentation fault of 11.

the other time I tried it, I got this:

Downloading http://github.prideout.net/assets/msquares_island.1024.bin...
test_msquares(24328,0x7fffb8cd6340) malloc: *** error for object 0x1030cf000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

When I ran it again (thinking it was just a random memory error that would fix with a relaunch), I got the same error code but with a different "object":

test_msquares(24339,0x7fffb8cd6340) malloc: *** error for object 0x10f6d8000: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6

this "object" is different every time I relaunch the squares test.

Question about lsystems

Hi,

I have made a luajit ffi wrapping for par_shapes. Great for generating meshes!!
I would like to better understand par_shapes_create_lsystem.
Could you explain the actions done by shape tube and shape connect?

Thanks
victor bombi

Acknowledgement as plugin

Hi. This isn't an "issue", exactly, but I didn't see a contact e-mail.

I've wrapped up a plugin based on msquares for Corona SDK and am trying to flesh out the docs, which I imagine will largely draw from your blog post. I've basically kept the same API, though there might be a few concessions to play well with Lua. (It's been a little well since I first bound it, so I'd have to review.)

The plugin listing will also include an icon. (This would default to the company icon I provided for myself.) Any preference here? I was thinking maybe the "island" next to the "Marching Squares" blog post here, but wanted to run it by you first. (Alternatively, the grasshopper or some variation on it.)

(I've had my eye on a few other libraries, too.)

par_msquares connected components

Hi Philip,

I am doing a Lua ffi wrapping of par_msquares. Grayscale gives one mesh even if there are unconnected components (althought extract_boundary will give you different boundarys for different components)
Would be possible to change grayscale to give as many meshes as unconnected components?

Best
victor

par_streamlines feature idea: M C C C spines

Sometimes computing reflection over the endpoint for first control point is not flexible enough and having a SVG equivalent of M C C C ... spines would enable this handy little library to make more complex results.

Linkage not compatible between C and C++ translation units

While the code compiles as either C and C++, the mangling of the functions differs partially between the languages, which means you have to decide when building the source file that contains the implementation if it's to be used in C or C++ source files in the project.

STB solves this in his libraries by wrapping the code in the following, which ensures a consistent "C" linkage:

#ifdef __cplusplus
extern "C" {
#endif

The triangles data in par_shapes

Hi Mr Rideout
big fan of your iphone book. Now i'm enjoying this library par_shapes. Please forgive me for a basic question, but I noticed that par_shapes_create_subdivided_sphere(1) returns with ntriangles as 80. I am gathering that the triangle integers returned are indices into the points array, but it's not clear why this number is not a multiple of 3. I was assuming that each 3 indices in triangles is a single triangle, and then the next 3 are the next triangle.. but then, shouldn't there be enough points to supply whole triangles? Or, are the last 2 points supposed to be joined with the original first point to create the final triangle?

drop static in two functions

I would like to use this two function from my code
par_shapes__compute_welded_normals and par_shapes__connect but it is not possible with the static declaration.
Would it be possible to drop the static keyword in this two functions?

connect inversion

I am proposing a change in the par_shapes__connect function.
The change is in https://github.com/prideout/par/blob/master/par_shapes.h#L1166
from

    memcpy(newpts, cylinder->points + (slices + 1) * 3,
        sizeof(float) * (slices + 1) * 3);

to memcpy(newpts, cylinder->points ,sizeof(float) * (slices + 1) * 3);

This are the results from lsystem
before
connect_lsystem1

and after
connect_lsystem2

difference is difficult to see.

But with this code:

        local mesh = par_shapes.create.empty()
	local tube = par_shapes.create.cylinder(slices, 1);
	local cone = par_shapes.create.cone(slices,1)
	mesh:merge(tube)
	cone:translate(1,1,3)
	mesh:connect(cone,slices)
	mesh:merge(cone)

we have before: end to end connection
connect_cone1

and after: end to begining connection
connect_cone2

For me, the expected result would be the second.
The proposed change is in PR #35

Perhaps another solution would be having an extra boolean argument to par_shapes__connect for choosing the way of connect (direct or inverse)

What is your opinion?

par_shapes__weld_points error

Hi,

I am investigating some SIGSEGV error in par_shapes.
Crash happens with par_shapes.create.cylinder(626,100) (perhaps slightly higher numbers depending on the compiler-architecture)

I have find this is due to par_shapes__weld_points generating meshes in which triangles contain points not present in the welded mesh.

If in https://github.com/prideout/par/blob/master/par_shapes.h#L1726 we add

		assert(a < mesh->npoints);
		assert(b < mesh->npoints);
		assert(c < mesh->npoints);

It will assert sometimes when nremoved > 0

Still looking for the bug but seems related to #20

bluenoise par_bluenoise_set_viewport question

Hi
I'm trying par bluenoise, its very fast ! Thanks for making it public.

While experimenting with it, I noticed par_bluenoise_set_viewport behaviour I didn't expect.
Changing left/right bounds preserves points pattern and returns resonable point counts.
In contrast, changing bottom/top bounds looks totally different and makes point counts less stable.
I recorded a screengrab to illustrate this. Take a look at the end of video, where a slight change in upper bound, causes almost 10x change in generated point count. Is this to be expected ? I'm not really familiar with algorithm's internals.

Thanks for any tips.

https://www.youtube.com/watch?v=-WKOSpt47cg&feature=youtu.be

Here is how I use par blue noise - calling dist_wang_tiles() on each frame.
https://pastebin.com/9dkFm7n8

easycurl: CURL_GLOBAL_SSL

curl_global_init(CURL_GLOBAL_SSL);

It seems that on Windows it only initializes SSL, so requests don't work.

compute_welded_normals in bunny.ctm

Related to #30

When loading this ctm mesh:

bunny.zip

compute_welded_normals dont crash (as in #30) but there are normals not correctly calculated.
It can be avoided by recompiling par_shapes with
https://github.com/prideout/par/blob/master/par_shapes.h#L305
replaced by par_shapes_mesh* welded = par_shapes_weld(m, 0.001, weldmap);

So changing epsilon to a smaller size will not weld different position points.
It also makes #30 to happen only for higher values of slices and stacks.

I think it would be useful to provide access to the epsilon value, it could be done making it an argument to par_shapes__compute_welded_normals and to par_shapes_create_parametric

What do you think?
Shall I do a PR for that?

Smooth normals?

Thank you for the par library! I'm trying to use some meshes generated with par_shapes with a phong shader, but I'm getting flat triangles. So it looks like the normals are all the same for each triangle. However, I see references to "smooth normals" in the instructions and the front sphere in the image of the three types of spheres appears to be smooth. I think my shader requires each normal to point out from the center of the sphere. Is that what the library provides?

I've tried the parametric_sphere, subdivided_sphere and other shapes both with and without unweld() and compute_normals().

easycurl: strncasecmp and strings.h

Is there anything strncasecmp can be replaced with? My compiler doesn't have strings.h and I wasn't able to find it.

Windows 10
cl 19.11.25508.2

par_shapes_create_parametric_sphere() loses "equator" when calling par_shapes_remove_degenerate()?

I've been trying to use the sphere mesh to help visualize things in the game I am working on, but I noticed that the parametric sphere seems to have triangles at the "equator" missing:

untitled

But if I go into par_shapes_create_parametric_sphere() and remove the call to par_shapes_remove_degenerate() then I get this:
untitled2

The call is simply par_shapes_create_parametric_sphere(16, 16). Am I doing something bad here? Feels like I shouldn't need to remove this call.

shapes: Support custom allocation functions

There are two problems currently:

  • There are many direct calls to the stdlib functions. All malloc/calloc/realloc/free calls should be replaced with PAR_MALLOC/PAR_CALLOC/PAR_REALLOC/PAR_FREE respectively.
  • It'd be more convenient to decouple the allocation functions from PAR_HELPERS. Right now you're forced to redefine all other helper functions if you want to override the allocation functions. Something like:
#ifndef PAR_MALLOC
#define PAR_MALLOC(T, N) ((T*) malloc(N * sizeof(T)))
#define PAR_CALLOC(T, N) ((T*) calloc(N * sizeof(T), 1))
#define PAR_REALLOC(T, BUF, N) ((T*) realloc(BUF, sizeof(T) * N))
#define PAR_FREE(BUF) free(BUF)
#endif

would be great.

par_streamlines does not compile using cl.exe

Hey, I'm using par_streamlines in my creative coding sketches and I noticed par_streamlines throws errors when compiling with cl.exe. It appears the errors are from the use of _attribute__((unused)) in 4 spots, lines: 837, 867, 983, and 1009. Commenting these out seems to allow me to compile the library with no issues.

I can submit a merge request if that will help!

Inside of torus shows through outside, only from one orientation

Hello Philip!
I do say, good day to you again sir!
I am having one peculiarity with the torus in par_shapes; I do not have this issue with any of the other shapes. When I rotate the torus, on one side the center properly is out of view by the outer edge. But 180 degrees flipped, the center shows through. I've experimented with various GL culling and depth settings, but I thought I'd ask here if possibly the triangles on the inside are not winding correct to cull them correctly? (If that's even the right terminology or concept). Here is what I'm seeing:

screen shot 2016-01-28 at 06 41 37

screen shot 2016-01-28 at 06 44 38

Many thanks for a neat little library.

Use of uninitialized memory and memory leaks

Valgrind says:

Conditional jump or move depends on uninitialised value(s)
   at 0x48A74F8: sqrt (w_sqrt_compat.c:31)
   by 0x109F93: par_shapes__normalize3 (par_shapes.h:291)
   by 0x10CC99: par_shapes_scale (par_shapes.h:840)
   by 0x110364: par_shapes_weld (par_shapes.h:1805)
   by 0x10A1C6: par_shapes__compute_welded_normals (par_shapes.h:324)
   by 0x10A9F6: par_shapes_create_parametric (par_shapes.h:492)
   by 0x10A2D6: par_shapes_create_cylinder (par_shapes.h:343)
   by 0x111360: main (test_shapes.c:17)
 Uninitialised value was created by a heap allocation
   at 0x483F7B5: malloc (vg_replace_malloc.c:381)
   by 0x10A189: par_shapes__compute_welded_normals (par_shapes.h:322)
   by 0x10A9F6: par_shapes_create_parametric (par_shapes.h:492)
   by 0x10A2D6: par_shapes_create_cylinder (par_shapes.h:343)
   by 0x111360: main (test_shapes.c:17)

and also memory leaks:

2,772 bytes in 1 blocks are definitely lost in loss record 1 of 2
   at 0x483F7B5: malloc (vg_replace_malloc.c:381)
   by 0x10A189: par_shapes__compute_welded_normals (par_shapes.h:322)
   by 0x10A9F6: par_shapes_create_parametric (par_shapes.h:492)
   by 0x10A524: par_shapes_create_klein_bottle (par_shapes.h:404)
   by 0x111B28: main (test_shapes.c:77)

This is caused by m->normals already being set and unconditionally overwritten here:

m->normals = PAR_MALLOC(float, m->npoints * 3);

I'm not sure what the right fix is here.

msquares color_multi wrong coords?

With greyscale and color x coords vary from 0 to 1 and y coords from 0 to height/width
The coords with color_multi are different for the same image.

Recommended # of subdivisions

I can draw the points from this fine:

par_shapes_create_subdivided_sphere(5)

but the following change eats up all the memory and crashes the app with a malloc error, and Google and Stackoverflow results suggest it is because a tremendous amount of memory is being allocated:

par_shapes_create_subdivided_sphere(10)

Is there a good way to know what the reasonable limits are for the various parameters of the library?

Having trouble with subdivided sphere with `nsubd > 5` and Raylib

Hi,

I'm trying to use par_shapes_create_subdivided_sphere but am having some trouble.
The shape seems to work fine up to 5 subdivisions. When I use nsubd of 6 or higher though, it breaks.

icosphere

The code I'm using to translate the shape information seems to be correct, this is the relevant part:

//Generate mesh function
Mesh GenMeshIcosphere(int subdivisions) {
    assert(subdivisions > 0 && "Trying to create IcoSphere mesh with subdivisions <= 0");

    Mesh mesh; // raylib mesh struct
    par_shapes_mesh *sphere = par_shapes_create_subdivided_sphere(subdivisions);

    // Allocating mem for geometry info
    //    texcoords are not generated in previous par_shapes call
    mesh.vertices = (float *)RL_MALLOC(sphere->ntriangles * 3 * 3 * sizeof(float));
    mesh.normals = (float *)RL_MALLOC(sphere->ntriangles * 3 * 3 * sizeof(float));

    mesh.vertexCount = sphere->ntriangles * 3;
    mesh.triangleCount = sphere->ntriangles;

    for (int k = 0; k < mesh.vertexCount; k++) {
        mesh.vertices[k * 3] = sphere->points[sphere->triangles[k] * 3];
        mesh.vertices[k * 3 + 1] = sphere->points[sphere->triangles[k] * 3 + 1];
        mesh.vertices[k * 3 + 2] = sphere->points[sphere->triangles[k] * 3 + 2];

        mesh.normals[k * 3] = sphere->normals[sphere->triangles[k] * 3];
        mesh.normals[k * 3 + 1] = sphere->normals[sphere->triangles[k] * 3 + 1];
        mesh.normals[k * 3 + 2] = sphere->normals[sphere->triangles[k] * 3 + 2];
    }

    par_shapes_free_mesh(sphere);

    UploadMesh(&mesh, false);
    return mesh;
}

This is based on the way Raylib uses par_shapes.h on its mesh functions, as can be seen here, and seems to work up to 5 subdivisions.

The broken shape is consistent, and breaks in exactly the same way every time. At first, it seemed to be some kind of accidental memory overwrite; but I'm starting to think it might not be on my side.

Does par_shapes_create_subdivided_sphere have a limit on subdivisions? Any chance the problem is not on my side?

Thank you very much!

[shapes] Simplify API in `par_shapes.h` by returning `par_shapes_mesh` by value?

Currently the functions which create meshes return pointers to the par_shapes_mesh struct but I think this is unnecessary and removing it would save a call to PAR_CALLOC and PAR_FREE and would allow users to store their meshes on the stack. The changes would be something like:

typedef struct par_shapes_mesh_s {
    float* points = null;           // Flat list of 3-tuples (X Y Z X Y Z...)
    int npoints = 0;                // Number of points
    PAR_SHAPES_T* triangles = null; // Flat list of 3-tuples (I J K I J K...)
    int ntriangles = 0;             // Number of triangles
    float* normals = null;          // Optional list of 3-tuples (X Y Z X Y Z...)
    float* tcoords = null;          // Optional list of 2-tuples (U V U V U V...)
} par_shapes_mesh;

par_shapes_mesh par_shapes_create_parametric(par_shapes_fn fn,
    int slices, int stacks, void* userdata)
{
    par_shapes_mesh mesh;

    // Generate verts.
    mesh.npoints = (slices + 1) * (stacks + 1);
    mesh.points = PAR_CALLOC(float, 3 * mesh.npoints);
    // ...

    // Generate texture coordinates.
    mesh.tcoords = PAR_CALLOC(float, 2 * mesh.npoints);
    // ...

    // Generate faces.
    mesh.ntriangles = 2 * slices * stacks;
    mesh.triangles = PAR_CALLOC(PAR_SHAPES_T, 3 * mesh.ntriangles);
    // ...

    par_shapes__compute_welded_normals(*mesh);
    return mesh;
}

void par_shapes_free_mesh(par_shapes_mesh* mesh) {
    PAR_FREE(mesh->points);
    PAR_FREE(mesh->triangles);
    PAR_FREE(mesh->normals);
    PAR_FREE(mesh->tcoords);
}

and then users can write:

{
    // This would be the most common usage I guess
    par_shapes_mesh stack_plane = par_shapes_create_plane(4, 4);
    par_shape_free_mesh(*stack_plane);
}

{
    // If you really want a heap allocated mesh you can do this, but it would
    // probably be simpler to store meshes by value in almost all cases
    par_shapes_mesh* heap_plane = PAR_CALLOC(par_shapes_mesh, 1);
    *heap_plane = par_shapes_create_plane(4, 4);
    par_shape_free_mesh(heap_plane);
    PAR_FREE(heap_plane);
}

I think this change would also remove the need for the par_shapes_create_empty and par_shapes_merge_and_free functions.

Marching Squares edge cases

First of all thanks for providing the nice implementation of the Marching Squares algorithm.

I've noticed some inconsistencies for various edge cases (literal "edge"-cases). I'm testing a simple 4x4 grayscale input data where all the values are 0 except one of the corners and a threshold of 0.5. Depending on which corner is set to 1, the number of mesh points varies between 3, 5, and 8. As a result, the boundary extraction also gives significantly different results of what (I think) should just be shaped which are rotated versions of each other.

shapes: Crash when creating shapes with many removed vertices

Example:
shape = par_shapes_create_torus(40, 40, 0.8);

While the crash itself happens deep inside the code (a triangle with a uninitialized value) the problem is caused around par_shapes.h#L1678 :

    for (int p = 0; p < mesh->npoints; p++, src += 3) {
        if (weldmap[p] == p) {
            *dst++ = src[0];
            *dst++ = src[1];
            *dst++ = src[2];
            *cmap++ = ci++;
        } else {
            // NOTE(phed) 
            // Example: p == 556, weldmap[p] == 563
            // condensed_map[weldmap[p]] == uninitialized
            // assert(weldmap[p] < p); // Seems to reliably detect when the error is about to happen
            *cmap++ = condensed_map[weldmap[p]];
        }

A non-fix, but code that seemingly works, I am not sure how to do it in a single pass, so I resorted to a magic number to work around it:

    for (int p = 0; p < mesh->npoints; p++, src += 3) {
        if (weldmap[p] == p) {
            *dst++ = src[0];
            *dst++ = src[1];
            *dst++ = src[2];
            *cmap++ = ci++;
        } else {
            *cmap++ = 65535;
        }
    }
    cmap = condensed_map;
    for (int p = 0; p < mesh->npoints; p++) {
        if (*cmap == 65535) {
            *cmap = condensed_map[weldmap[p]];
        }
        cmap++;
    }

install

Hi.

Some notes about installation:

sudo apt-get install libcurl4-gnutls-dev
git clone https://github.com/prideout/par
cd par
cmake test -Bbuild
cd build
cmake .
make
./test_bubbles

par_bubbles_pack
Memory protection violation

Explicit type cast required for malloc/calloc in some C++ compiler

Some C++ compiler(e.g. MacOSX's default clang++) reports an error when compiling par_msqures.h(and other .h which uses malloc/calloc) with C++ codes, for example:

./par_msquares.h:255:28: error: cannot initialize a variable of type 'par_msquares_meshlist *' (aka 'par_msquares_meshlist_s *')
      with an rvalue of type 'void *'
    par_msquares_meshlist* merged = malloc(sizeof(par_msquares_meshlist));
                           ^        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It would be nice to add explicit type cast for malloc/calloc(or functions returning void pointer) to par_***.h

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.