csg 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +17 -2
- data/lib/csg.rb +9 -7
- data/src/bsp.c +41 -54
- data/src/cmd_audit.c +72 -0
- data/src/cmd_audit.h +9 -0
- data/src/commands.c +47 -2
- data/src/export.c +44 -23
- data/src/export.h +1 -0
- data/src/poly.c +202 -29
- data/src/poly.h +24 -1
- data/src/stl.c +6 -11
- data/src/stl_mesh.c +18 -12
- data/src/stl_mesh.h +7 -0
- data/src/util.c +14 -19
- data/src/util.h +9 -0
- data/src/vector.c +18 -3
- data/src/vector.h +3 -0
- metadata +20 -18
data/src/poly.h
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
#include <stdbool.h>
|
1
2
|
#include <strings.h>
|
2
3
|
#include "dbg.h"
|
3
4
|
#include "klist.h"
|
@@ -28,26 +29,48 @@ typedef struct s_poly {
|
|
28
29
|
} poly_t;
|
29
30
|
|
30
31
|
poly_t *alloc_poly(void);
|
32
|
+
poly_t *poly_make_triangle_guarded(float3 a, float3 b, float3 c, bool guard);
|
31
33
|
poly_t *poly_make_triangle(float3 a, float3 b, float3 c);
|
34
|
+
poly_t *poly_make_triangle_unsafe(float3 a, float3 b, float3 c);
|
32
35
|
poly_t *clone_poly(poly_t *poly);
|
33
36
|
void free_poly(poly_t *p, int free_self);
|
34
37
|
|
38
|
+
void poly_print(poly_t *p, FILE *stream);
|
39
|
+
void poly_print_with_plane_info(poly_t *p, poly_t *plane, FILE *stream);
|
40
|
+
|
35
41
|
poly_t *poly_init(poly_t *poly);
|
36
42
|
int poly_update(poly_t *poly);
|
37
43
|
poly_t *poly_invert(poly_t *poly);
|
38
44
|
|
45
|
+
float poly_triangle_2area(poly_t *triangle);
|
46
|
+
float poly_triangle_area(poly_t *triangle);
|
47
|
+
float poly_area(poly_t *poly);
|
48
|
+
float poly_2area(poly_t *poly);
|
49
|
+
bool poly_has_area(poly_t *poly);
|
50
|
+
|
39
51
|
int poly_vertex_count(poly_t *poly);
|
40
52
|
int poly_vertex_max(poly_t *poly);
|
41
53
|
int poly_vertex_available(poly_t *poly);
|
42
54
|
int poly_vertex_dynamic_p(poly_t *poly);
|
43
55
|
int poly_vertex_expand(poly_t *poly);
|
44
|
-
|
56
|
+
bool poly_push_vertex(poly_t *poly, float3 v);
|
57
|
+
bool poly_push_vertex_unsafe(poly_t *poly, float3 v);
|
58
|
+
bool poly_push_vertex_guarded(poly_t *poly, float3 v, bool guard);
|
45
59
|
|
46
60
|
int poly_classify_vertex(poly_t *poly, float3 v);
|
61
|
+
const char* poly_classify_vertex_string(poly_t *poly, float3 v);
|
47
62
|
int poly_classify_poly(poly_t *this, poly_t *other);
|
48
63
|
|
49
64
|
int poly_split(poly_t *divider, poly_t *poly, poly_t **front, poly_t **back);
|
50
65
|
|
66
|
+
float poly_max_edge_length2(poly_t *poly);
|
67
|
+
float poly_min_edge_length2(poly_t *poly);
|
68
|
+
|
69
|
+
// Some polygon helpers that don't explicitly work on `poly_t`
|
70
|
+
// but are close enough to be grouped here
|
71
|
+
|
72
|
+
float triangle_2area(float3 a, float3 b, float3 c);
|
73
|
+
|
51
74
|
#define mp_poly_free(x) free_poly(kl_val(x), 1)
|
52
75
|
KLIST_INIT(poly, poly_t*, mp_poly_free)
|
53
76
|
|
data/src/stl.c
CHANGED
@@ -18,7 +18,7 @@ void stl_free(stl_object *obj) {
|
|
18
18
|
|
19
19
|
stl_object *stl_alloc(char *header, uint32_t n_facets) {
|
20
20
|
stl_object *obj = (stl_object*)calloc(1, sizeof(stl_object));
|
21
|
-
|
21
|
+
assert_mem(obj);
|
22
22
|
|
23
23
|
if(header != NULL) {
|
24
24
|
memcpy(obj->header, header, sizeof(obj->header));
|
@@ -27,12 +27,10 @@ stl_object *stl_alloc(char *header, uint32_t n_facets) {
|
|
27
27
|
obj->facet_count = n_facets;
|
28
28
|
if(n_facets > 0) {
|
29
29
|
obj->facets = (stl_facet*)calloc(n_facets, sizeof(stl_facet));
|
30
|
-
|
30
|
+
assert_mem(obj->facets);
|
31
31
|
}
|
32
32
|
|
33
33
|
return obj;
|
34
|
-
error:
|
35
|
-
exit(-1);
|
36
34
|
}
|
37
35
|
|
38
36
|
void v3_cross(float3 *result, float3 v1, float3 v2, int normalize) {
|
@@ -42,10 +40,7 @@ void v3_cross(float3 *result, float3 v1, float3 v2, int normalize) {
|
|
42
40
|
v1[0]*v2[1] - v1[1]*v2[0]
|
43
41
|
};
|
44
42
|
if(normalize) {
|
45
|
-
|
46
|
-
v1_x_v2[0] /= mag;
|
47
|
-
v1_x_v2[1] /= mag;
|
48
|
-
v1_x_v2[2] /= mag;
|
43
|
+
f3_normalize(&v1_x_v2);
|
49
44
|
}
|
50
45
|
memcpy(result, &v1_x_v2, sizeof(float3));
|
51
46
|
}
|
@@ -60,7 +55,7 @@ void stl_facet_update_normal(stl_facet *facet) {
|
|
60
55
|
stl_facet *stl_read_facet(int fd) {
|
61
56
|
int rc = -1;
|
62
57
|
stl_facet *facet = (stl_facet*)calloc(1, sizeof(stl_facet));
|
63
|
-
|
58
|
+
assert_mem(facet);
|
64
59
|
|
65
60
|
rc = read(fd, &facet->normal, sizeof(facet->normal));
|
66
61
|
check(rc == sizeof(facet->normal), "Failed to read normal. Read %d expected %zu", rc, sizeof(facet->normal));
|
@@ -79,7 +74,7 @@ stl_facet *stl_read_text_facet(const char *declaration, FILE *f) {
|
|
79
74
|
int rc = -1;
|
80
75
|
char *line = NULL;
|
81
76
|
|
82
|
-
|
77
|
+
assert_mem(facet);
|
83
78
|
rc = sscanf(declaration, "facet normal %f %f %f", &facet->normal[0], &facet->normal[1], &facet->normal[2]);
|
84
79
|
check(rc == 3, "stl_Read_text_facet(%s): Normal line malformed", declaration);
|
85
80
|
|
@@ -149,7 +144,7 @@ stl_object *stl_read_text_object(int fd) {
|
|
149
144
|
|
150
145
|
obj->facet_count = facets->size;
|
151
146
|
obj->facets = calloc(facets->size, sizeof(stl_facet));
|
152
|
-
|
147
|
+
assert_mem(obj->facets);
|
153
148
|
|
154
149
|
stl_facet *facet = NULL;
|
155
150
|
for(int i = 0; kl_shift(stl_facet, facets, &facet) != -1; i++) {
|
data/src/stl_mesh.c
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
#include "stl_mesh.h"
|
2
|
+
#include "util.h"
|
2
3
|
|
3
4
|
// Mesh type prototype methods
|
4
5
|
int stl_mesh_init(void *self, void *data) {
|
5
6
|
stl_mesh_t *mesh = (stl_mesh_t*)self;
|
6
7
|
if(data == NULL) {
|
7
|
-
|
8
|
+
assert_mem(mesh->stl = stl_alloc(NULL, 0));
|
8
9
|
}
|
9
10
|
else {
|
10
11
|
mesh->stl = (stl_object*)data;
|
11
12
|
}
|
12
13
|
return 0;
|
13
|
-
error:
|
14
|
-
return -1;
|
15
14
|
}
|
16
15
|
|
17
16
|
void stl_mesh_destroy(void *self) {
|
@@ -25,24 +24,31 @@ int stl_mesh_poly_count(void *self) {
|
|
25
24
|
return mesh->stl->facet_count;
|
26
25
|
}
|
27
26
|
|
28
|
-
klist_t(poly)*
|
27
|
+
klist_t(poly)* stl_mesh_to_polygons_guarded(void *self, bool guard) {
|
29
28
|
stl_mesh_t *mesh = (stl_mesh_t*)self;
|
30
29
|
int count = mesh->_(poly_count)(mesh);
|
31
30
|
klist_t(poly)* polys = kl_init(poly);
|
32
31
|
|
33
32
|
for(int i = 0; i < count; i++) {
|
34
|
-
poly_t *poly =
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
poly_t *poly = poly_make_triangle_guarded(mesh->stl->facets[i].vertices[0],
|
34
|
+
mesh->stl->facets[i].vertices[1],
|
35
|
+
mesh->stl->facets[i].vertices[2],
|
36
|
+
guard);
|
37
|
+
if(poly != NULL) {
|
38
|
+
*kl_pushp(poly, polys) = poly;
|
39
|
+
}
|
39
40
|
}
|
40
41
|
|
41
42
|
|
42
43
|
return polys;
|
43
|
-
|
44
|
-
|
45
|
-
|
44
|
+
}
|
45
|
+
|
46
|
+
klist_t(poly)* stl_mesh_to_polygons(void *self) {
|
47
|
+
return stl_mesh_to_polygons_guarded(self, true);
|
48
|
+
}
|
49
|
+
|
50
|
+
klist_t(poly)* stl_mesh_to_polygons_unsafe(void *self) {
|
51
|
+
return stl_mesh_to_polygons_guarded(self, false);
|
46
52
|
}
|
47
53
|
|
48
54
|
// Mesh type definitions
|
data/src/stl_mesh.h
CHANGED
@@ -12,4 +12,11 @@ typedef struct s_stl_mesh_t {
|
|
12
12
|
stl_object *stl;
|
13
13
|
} stl_mesh_t;
|
14
14
|
|
15
|
+
// Alternative implementations for `to_polygons` are available.
|
16
|
+
// The default performs sanity checks on the constructed polygons,
|
17
|
+
// the `_unsafe` variant ignores these checks and returns a polygon
|
18
|
+
// list as-defined, but possibly mathematically useless.
|
19
|
+
klist_t(poly)* stl_mesh_to_polygons(void *self);
|
20
|
+
klist_t(poly)* stl_mesh_to_polygons_unsafe(void *self);
|
21
|
+
|
15
22
|
#endif
|
data/src/util.c
CHANGED
@@ -1,14 +1,12 @@
|
|
1
|
-
#include
|
1
|
+
#include <ctype.h>
|
2
2
|
|
3
3
|
#include "util.h"
|
4
4
|
|
5
5
|
char *str_dup(char *str) {
|
6
6
|
char *copy_str = NULL;
|
7
|
-
|
7
|
+
assert_mem(copy_str = calloc(strlen(str) + 1, sizeof(char)));
|
8
8
|
strncpy(copy_str, str, strlen(str));
|
9
9
|
return copy_str;
|
10
|
-
error:
|
11
|
-
return NULL;
|
12
10
|
}
|
13
11
|
|
14
12
|
char *str_ltrim(char *str, bool copy) {
|
@@ -34,12 +32,9 @@ char *str_ltrim(char *str, bool copy) {
|
|
34
32
|
return str;
|
35
33
|
}
|
36
34
|
else {
|
37
|
-
char *copy_str =
|
38
|
-
check_mem(copy_str = str_dup(str));
|
35
|
+
char *copy_str = str_dup(str);
|
39
36
|
return str_ltrim(copy_str, false);
|
40
37
|
}
|
41
|
-
error:
|
42
|
-
return NULL;
|
43
38
|
}
|
44
39
|
|
45
40
|
char *str_rtrim(char *str, bool copy) {
|
@@ -51,25 +46,19 @@ char *str_rtrim(char *str, bool copy) {
|
|
51
46
|
return str;
|
52
47
|
}
|
53
48
|
else {
|
54
|
-
char *copy_str =
|
55
|
-
check_mem(copy_str = str_dup(str));
|
49
|
+
char *copy_str = str_dup(str);
|
56
50
|
return str_ltrim(copy_str, false);
|
57
51
|
}
|
58
|
-
error:
|
59
|
-
return NULL;
|
60
52
|
}
|
61
53
|
|
62
54
|
char *str_trim(char *str, bool copy) {
|
63
55
|
char *trim_str = copy ? str_dup(str) : str;
|
64
|
-
check_mem(trim_str);
|
65
56
|
|
66
57
|
// Since we have already made a copy if we need one,
|
67
58
|
// we can just chain these two together, since non-copy
|
68
59
|
// operations can't throw out a NULL and the pointer itself
|
69
60
|
// cannot change.
|
70
61
|
return str_ltrim(str_rtrim(trim_str, false), false);
|
71
|
-
error:
|
72
|
-
return NULL;
|
73
62
|
}
|
74
63
|
|
75
64
|
char *read_line(FILE *f, bool downcase, bool trim) {
|
@@ -89,7 +78,7 @@ char *read_line(FILE *f, bool downcase, bool trim) {
|
|
89
78
|
if((rc == NULL) && feof(f)) return NULL;
|
90
79
|
|
91
80
|
check_debug(rc != NULL, "Failed to read line from FILE(%p)", f);
|
92
|
-
|
81
|
+
assert_mem(line = calloc(strlen(read_buffer) + 1, sizeof(char)));
|
93
82
|
strncpy(line, read_buffer, strlen(read_buffer));
|
94
83
|
|
95
84
|
// See if we need to finish reading the line
|
@@ -104,7 +93,7 @@ char *read_line(FILE *f, bool downcase, bool trim) {
|
|
104
93
|
// Append the new data to the end of the line
|
105
94
|
char *new_line = NULL;
|
106
95
|
check(rc != NULL, "Error finishing line from FILE(%p)", f);
|
107
|
-
|
96
|
+
assert_mem(new_line = calloc(strlen(line) + strlen(read_buffer) + 1, sizeof(char)));
|
108
97
|
|
109
98
|
strncpy(new_line, line, strlen(line));
|
110
99
|
strncpy(new_line + strlen(new_line), read_buffer, strlen(read_buffer));
|
@@ -130,8 +119,8 @@ char *read_line(FILE *f, bool downcase, bool trim) {
|
|
130
119
|
return line;
|
131
120
|
error:
|
132
121
|
if(line != NULL) free(line);
|
133
|
-
if(feof(f)) debug("FILE(%p) EOF", f);
|
134
|
-
if(ferror(f)) debug("FILE(%p): ERROR. %s", f, clean_errno());
|
122
|
+
if(feof(f)) { debug("FILE(%p) EOF", f); }
|
123
|
+
if(ferror(f)) { debug("FILE(%p): ERROR. %s", f, clean_errno()); }
|
135
124
|
return NULL;
|
136
125
|
}
|
137
126
|
|
@@ -147,3 +136,9 @@ char *next_line(FILE *f, bool downcase, bool trim) {
|
|
147
136
|
|
148
137
|
return line;
|
149
138
|
}
|
139
|
+
|
140
|
+
float clampf(float val, float min, float max) {
|
141
|
+
if(val > max) return max;
|
142
|
+
if(val < min) return min;
|
143
|
+
return val;
|
144
|
+
}
|
data/src/util.h
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
#include <stdbool.h>
|
2
2
|
#include <stdio.h>
|
3
3
|
#include <stdlib.h>
|
4
|
+
#include <assert.h>
|
4
5
|
|
5
6
|
#include "dbg.h"
|
6
7
|
|
7
8
|
#ifndef __UTIL_H
|
8
9
|
#define __UTIL_H
|
9
10
|
|
11
|
+
// Fatal memory check
|
12
|
+
#define assert_mem(A) if((A) == NULL) { \
|
13
|
+
assert("Out of memory." && false); \
|
14
|
+
abort(); \
|
15
|
+
}
|
16
|
+
|
10
17
|
|
11
18
|
char *str_dup(char *str);
|
12
19
|
|
@@ -24,4 +31,6 @@ char *read_line(FILE *f, bool downcase, bool trim);
|
|
24
31
|
// Gets the "next" non-blank line
|
25
32
|
char *next_line(FILE *f, bool downcase, bool trim);
|
26
33
|
|
34
|
+
float clampf(float val, float min, float max);
|
35
|
+
|
27
36
|
#endif
|
data/src/vector.c
CHANGED
@@ -10,10 +10,15 @@ float3 *clone_f3(float3 f) {
|
|
10
10
|
return clone;
|
11
11
|
}
|
12
12
|
|
13
|
+
float f3_magnitude(float3 *v) {
|
14
|
+
return sqrt((*v)[0] * (*v)[0] +
|
15
|
+
(*v)[1] * (*v)[1] +
|
16
|
+
(*v)[2] * (*v)[2]);
|
17
|
+
}
|
18
|
+
|
13
19
|
float3 *f3_normalize(float3 *v) {
|
14
|
-
float mag =
|
15
|
-
|
16
|
-
(*v)[2] * (*v)[2]);
|
20
|
+
float mag = f3_magnitude(v);
|
21
|
+
|
17
22
|
(*v)[0] /= mag;
|
18
23
|
(*v)[1] /= mag;
|
19
24
|
(*v)[2] /= mag;
|
@@ -53,3 +58,13 @@ float3 *f3_interpolate(float3 *result, float3 start, float3 v, float alpha) {
|
|
53
58
|
}
|
54
59
|
return result;
|
55
60
|
}
|
61
|
+
|
62
|
+
float f3_distance(float3 a, float3 b) {
|
63
|
+
return sqrt(f3_distance2(a, b));
|
64
|
+
}
|
65
|
+
|
66
|
+
float f3_distance2(float3 a, float3 b) {
|
67
|
+
float3 diff = FLOAT3_INIT;
|
68
|
+
f3_sub(&diff, a, b);
|
69
|
+
return f3_dot(diff, diff);
|
70
|
+
}
|
data/src/vector.h
CHANGED
@@ -19,6 +19,7 @@ typedef float float3[3];
|
|
19
19
|
float3 *clone_f3(float3 f);
|
20
20
|
|
21
21
|
// Vector Updating operations
|
22
|
+
float f3_magnitude(float3 *v);
|
22
23
|
float3 *f3_normalize(float3 *v);
|
23
24
|
float3 *f3_scale(float3 *f, float c);
|
24
25
|
|
@@ -27,6 +28,8 @@ float3 *f3_cross(float3 *result, float3 v1, float3 v2);
|
|
27
28
|
float f3_dot(float3 v1, float3 v2);
|
28
29
|
float3 *f3_sub(float3 *result, float3 v1, float3 v2);
|
29
30
|
float3 *f3_interpolate(float3 *result, float3 start, float3 v, float alpha);
|
31
|
+
float f3_distance(float3 a, float3 b);
|
32
|
+
float f3_distance2(float3 a, float3 b);
|
30
33
|
|
31
34
|
// Containers
|
32
35
|
#define mp_float3_free(x) free(kl_val(x))
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yaroslav Shirokov
|
@@ -9,20 +9,20 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-09-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
28
|
description: A fast library for Constructive Solid Geometry
|
@@ -35,32 +35,34 @@ extensions:
|
|
35
35
|
extra_rdoc_files: []
|
36
36
|
files:
|
37
37
|
- Makefile
|
38
|
+
- ext/Rakefile
|
38
39
|
- lib/csg.rb
|
39
40
|
- src/bsp.c
|
40
|
-
- src/commands.c
|
41
|
-
- src/dbg.c
|
42
|
-
- src/export.c
|
43
|
-
- src/mesh.c
|
44
|
-
- src/poly.c
|
45
|
-
- src/reader.c
|
46
|
-
- src/stl.c
|
47
|
-
- src/stl_mesh.c
|
48
|
-
- src/util.c
|
49
|
-
- src/vector.c
|
50
41
|
- src/bsp.h
|
51
42
|
- src/bsp_mesh.h
|
43
|
+
- src/cmd_audit.c
|
44
|
+
- src/cmd_audit.h
|
45
|
+
- src/commands.c
|
52
46
|
- src/commands.h
|
47
|
+
- src/dbg.c
|
53
48
|
- src/dbg.h
|
49
|
+
- src/export.c
|
54
50
|
- src/export.h
|
55
51
|
- src/klist.h
|
52
|
+
- src/mesh.c
|
56
53
|
- src/mesh.h
|
54
|
+
- src/poly.c
|
57
55
|
- src/poly.h
|
56
|
+
- src/reader.c
|
58
57
|
- src/reader.h
|
58
|
+
- src/stl.c
|
59
59
|
- src/stl.h
|
60
|
+
- src/stl_mesh.c
|
60
61
|
- src/stl_mesh.h
|
62
|
+
- src/util.c
|
61
63
|
- src/util.h
|
64
|
+
- src/vector.c
|
62
65
|
- src/vector.h
|
63
|
-
- ext/Rakefile
|
64
66
|
homepage: https://github.com/sshirokov/csgtool/
|
65
67
|
licenses:
|
66
68
|
- MIT
|
@@ -71,17 +73,17 @@ require_paths:
|
|
71
73
|
- lib
|
72
74
|
required_ruby_version: !ruby/object:Gem::Requirement
|
73
75
|
requirements:
|
74
|
-
- -
|
76
|
+
- - ">="
|
75
77
|
- !ruby/object:Gem::Version
|
76
78
|
version: '0'
|
77
79
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
80
|
requirements:
|
79
|
-
- -
|
81
|
+
- - ">="
|
80
82
|
- !ruby/object:Gem::Version
|
81
83
|
version: '0'
|
82
84
|
requirements: []
|
83
85
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.
|
86
|
+
rubygems_version: 2.2.2
|
85
87
|
signing_key:
|
86
88
|
specification_version: 4
|
87
89
|
summary: A fast library for Constructive Solid Geometry
|