csg 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (9) hide show
  1. checksums.yaml +7 -0
  2. data/Makefile +7 -1
  3. data/src/bsp.c +78 -15
  4. data/src/bsp.h +4 -2
  5. data/src/commands.c +105 -0
  6. data/src/commands.h +17 -0
  7. data/src/poly.c +61 -3
  8. data/src/poly.h +10 -1
  9. metadata +11 -13
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0156d8c17eb3aa465dccdec30ce073b111c15f31
4
+ data.tar.gz: ffc2a35116bdd1cdd181943ae3e40ef51fcf5e88
5
+ SHA512:
6
+ metadata.gz: 9dce1d39a95353b489193bcfa6427127e87b99e2de342e0d571e65678a6c0785dc9b86a53b0f4a5f4e8058a3c8d0050979e7b54002c04275d051cd845073dfe2
7
+ data.tar.gz: c4f6ec8bf5905402348f7daec9d3db3994aeb237bf9eb49d5057eaa5bd7ab7ce7c9ecda037c5e2274e6aa448c9d0a9fd9877822fafc2daee535543e8cd2667ff
data/Makefile CHANGED
@@ -26,7 +26,7 @@ clean:
26
26
  test:
27
27
  @make -C tests clean test
28
28
 
29
- .PHONY: all clean test libcsg
29
+ .PHONY: all clean test libcsg loc
30
30
 
31
31
  $(TARGET): $(TARGET).o $(OBJS)
32
32
  $(CC) $(CFLAGS) $^ $(LIBS) -o $@.new
@@ -39,3 +39,9 @@ libcsg: $(LIB_TARGET)
39
39
 
40
40
  %.o: %.c
41
41
  $(CC) -fPIC $(CFLAGS) -o $@ -c $^
42
+
43
+ loc:
44
+ @echo "=> Source:"
45
+ find src/ -name '*.[ch]' -not -name 'dbg.*' | xargs wc -l csgtool.c
46
+ @echo "=> Tests:"
47
+ find tests/ -name '*.[ch]' -not -path '*clar*' | xargs wc -l
data/src/bsp.c CHANGED
@@ -69,7 +69,9 @@ int bsp_subdivide(poly_t *divider, poly_t *poly,
69
69
  poly_t **coplanar_front, int *n_cp_front,
70
70
  poly_t **coplanar_back, int *n_cp_back,
71
71
  poly_t **front, int *n_front,
72
- poly_t **back, int *n_back) {
72
+ poly_t **back, int *n_back,
73
+ poly_t **unused, int *n_unused,
74
+ poly_t **created, int *n_created) {
73
75
  switch(poly_classify_poly(divider, poly)) {
74
76
  case FRONT:
75
77
  front[*n_front] = poly;
@@ -99,6 +101,21 @@ int bsp_subdivide(poly_t *divider, poly_t *poly,
99
101
 
100
102
  back[*n_back] = b;
101
103
  *n_back += 1;
104
+
105
+ // Do we care about telling the caller about polygons
106
+ // who's pointers are not in any of the "real" lists?
107
+ if(unused != NULL) {
108
+ unused[*n_unused] = poly;
109
+ *n_unused += 1;
110
+ }
111
+
112
+ // How about polygons that we just made?
113
+ if(created != NULL) {
114
+ created[*n_created] = f;
115
+ *n_created += 1;
116
+ created[*n_created] = b;
117
+ *n_created += 1;
118
+ }
102
119
  break;
103
120
  }
104
121
  }
@@ -122,7 +139,7 @@ bsp_node_t *bsp_build(bsp_node_t *node, klist_t(poly) *polygons, int copy) {
122
139
  polys[i] = poly;
123
140
  }
124
141
 
125
- check((node = bsp_build_array(node, polys, polygons->size)),
142
+ check((node = bsp_build_array(node, polys, polygons->size, copy)),
126
143
  "Failed to build node from list(%p) of %zd polys", polygons, polygons->size);
127
144
  free(polys);
128
145
 
@@ -131,7 +148,8 @@ error:
131
148
  if(polys) free(polys);
132
149
  return NULL;
133
150
  }
134
- bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys) {
151
+
152
+ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys, int free_unused) {
135
153
  int rc = 0;
136
154
 
137
155
  // Polygon lists and counters
@@ -142,6 +160,14 @@ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys)
142
160
  poly_t **front_p = NULL;
143
161
  poly_t **back_p = NULL;
144
162
 
163
+ // List and counter of unused polygons
164
+ // These will get freed after the build
165
+ // because they will not appear with identity
166
+ // in coplanar, front_p, or back_p if free_unused
167
+ // is true
168
+ int n_unused = 0;
169
+ poly_t **unused = NULL;
170
+
145
171
  // Iterators
146
172
  poly_t *poly = NULL;
147
173
  size_t poly_i = 0;
@@ -172,20 +198,34 @@ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys)
172
198
  check_mem(coplanar = malloc(sizeof(poly_t*) * n_polys));
173
199
  check_mem(front_p = malloc(sizeof(poly_t*) * n_polys));
174
200
  check_mem(back_p = malloc(sizeof(poly_t*) * n_polys));
201
+ check_mem(unused = malloc(sizeof(poly_t*) * n_polys));
175
202
  for(; poly_i < n_polys; poly_i++) {
176
203
  poly = polygons[poly_i];
177
204
  rc = bsp_subdivide(node->divider, poly,
178
205
  coplanar, &n_coplanar,
179
206
  coplanar, &n_coplanar,
180
207
  front_p, &n_front,
181
- back_p, &n_back);
208
+ back_p, &n_back,
209
+ unused, &n_unused,
210
+ NULL, NULL);
182
211
  check(rc == 0, "Failed to subdivide: %p => %p", node->divider, poly);
183
212
  }
184
213
 
214
+ // Destroy the unused polygons now, if we're asked,
215
+ // otherwise we'll lose the references
216
+ int i = 0;
217
+ if(free_unused != 0) {
218
+ for(i = 0; i < n_unused; i++) {
219
+ free_poly(unused[i], 1);
220
+ }
221
+ }
222
+ // Free now and mark NULL to make sure it's not double free'd on `error:`
223
+ free(unused);
224
+ unused = NULL;
225
+
185
226
  // Store the coplanar nodes in this node's polygon list
186
227
  // and free the container, letting the list destructor
187
228
  // clean up
188
- int i = 0;
189
229
  for(i = 0; i < n_coplanar; i++) {
190
230
  *kl_pushp(poly, node->polygons) = coplanar[i];
191
231
  }
@@ -195,13 +235,13 @@ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys)
195
235
  if((n_front > 0)) {
196
236
  if(node->front == NULL) node->front = alloc_bsp_node();
197
237
  check_mem(node->front);
198
- check(bsp_build_array(node->front, front_p, n_front) != NULL,
238
+ check(bsp_build_array(node->front, front_p, n_front, free_unused) != NULL,
199
239
  "Failed to build front tree of bsp_node_array(%p)", node);
200
240
  }
201
241
  if((n_back > 0)) {
202
242
  if(node->back == NULL) node->back = alloc_bsp_node();
203
243
  check_mem(node->back);
204
- check(bsp_build_array(node->back, back_p, n_back) != NULL,
244
+ check(bsp_build_array(node->back, back_p, n_back, free_unused) != NULL,
205
245
  "Failed to build back tree of bsp_node(%p)", node);
206
246
  }
207
247
  free(front_p);
@@ -213,6 +253,7 @@ error:
213
253
  if(coplanar) free(coplanar);
214
254
  if(back_p) free(back_p);
215
255
  if(front_p) free(front_p);
256
+ if(unused) free(unused);
216
257
  return NULL;
217
258
  }
218
259
 
@@ -316,24 +357,28 @@ klist_t(poly) *bsp_clip_polygon_array(bsp_node_t *node, poly_t **polygons, size_
316
357
  poly_t **poly_buffer = static_poly_buffer;
317
358
  poly_t **front_array = NULL;
318
359
  poly_t **back_array = NULL;
360
+ poly_t **created_array = NULL;
319
361
  int n_front = 0;
320
362
  int n_back = 0;
363
+ int n_created = 0;
321
364
 
322
365
  // Let's end this quick if there's nothing to do.
323
366
  if(n_polys == 0) return result;
324
367
 
325
368
  if(node->divider != NULL) {
326
- if((n_polys * 2) > STATIC_POLY_BUFFER_SIZE) {
327
- check_mem(poly_buffer = malloc((sizeof(poly_t*) * n_polys) * 2));
369
+ if((n_polys * 3) > STATIC_POLY_BUFFER_SIZE) {
370
+ check_mem(poly_buffer = malloc((sizeof(poly_t*) * n_polys) * 3));
328
371
  }
329
372
  front_array = poly_buffer;
330
373
  back_array = poly_buffer + n_polys;
374
+ created_array = poly_buffer + (n_polys * 2);
331
375
  // Sort this node's polygons into the front or back
332
376
  for(i = 0; i < n_polys; i++) {
333
377
  p = polygons[i];
334
378
  rc = bsp_subdivide(node->divider, p,
335
379
  front_array, &n_front, back_array, &n_back,
336
- front_array, &n_front, back_array, &n_back);
380
+ front_array, &n_front, back_array, &n_back,
381
+ NULL, NULL, created_array, &n_created);
337
382
  check(rc != -1, "Failed to subdivide poly %p", p);
338
383
  }
339
384
 
@@ -358,8 +403,15 @@ klist_t(poly) *bsp_clip_polygon_array(bsp_node_t *node, poly_t **polygons, size_
358
403
  check(result != NULL, "Failed to clip back tree");
359
404
  }
360
405
 
361
- if(poly_buffer != static_poly_buffer) free(poly_buffer);
406
+ // Free all the polygons in 'created_array` since they would have
407
+ // been cloned if they were important, and the input set is not our
408
+ // responsibility
409
+ for(int j = 0; j < n_created; j++) {
410
+ free_poly(created_array[j], 1);
411
+ }
412
+
362
413
  // Clean up the result halves, now that they're copied into `result`
414
+ if(poly_buffer != static_poly_buffer) free(poly_buffer);
363
415
  }
364
416
  else {
365
417
  // If we don't have a divider we just copy out the polygons
@@ -386,23 +438,27 @@ klist_t(poly) *bsp_clip_polygons(bsp_node_t *node, klist_t(poly) *polygons, klis
386
438
  poly_t **poly_buffer = static_poly_buffer;
387
439
  poly_t **front_array = NULL;
388
440
  poly_t **back_array = NULL;
441
+ poly_t **created_array = NULL;
389
442
  int n_front = 0;
390
443
  int n_back = 0;
444
+ int n_created = 0;
391
445
 
392
446
  // Let's end this quick if there's nothing to do.
393
447
  if(polygons->size == 0) return result;
394
448
 
395
449
  if(node->divider != NULL) {
396
- if((polygons->size * 2) > STATIC_POLY_BUFFER_SIZE) {
397
- check_mem(poly_buffer = malloc(sizeof(poly_t*) * polygons->size * 2));
450
+ if((polygons->size * 3) > STATIC_POLY_BUFFER_SIZE) {
451
+ check_mem(poly_buffer = malloc(sizeof(poly_t*) * polygons->size * 3));
398
452
  }
399
453
  front_array = poly_buffer;
400
454
  back_array = poly_buffer + polygons->size;
455
+ created_array = poly_buffer + (polygons->size * 2);
401
456
  // Sort this node's polygons into the front or back
402
457
  for(iter = kl_begin(polygons); iter != kl_end(polygons); iter = kl_next(iter)) {
403
458
  rc = bsp_subdivide(node->divider, kl_val(iter),
404
459
  front_array, &n_front, back_array, &n_back,
405
- front_array, &n_front, back_array, &n_back);
460
+ front_array, &n_front, back_array, &n_back,
461
+ NULL, NULL, created_array, &n_created);
406
462
  check(rc != -1, "Failed to subdivide poly %p", kl_val(iter));
407
463
  }
408
464
 
@@ -427,8 +483,15 @@ klist_t(poly) *bsp_clip_polygons(bsp_node_t *node, klist_t(poly) *polygons, klis
427
483
  check(result != NULL, "Failed to clip back tree");
428
484
  }
429
485
 
486
+ // Free all the polygons in 'created_array` since they would have
487
+ // been cloned if they were important, and the input set is not our
488
+ // responsibility
489
+ for(int j = 0; j < n_created; j++) {
490
+ free_poly(created_array[j], 1);
491
+ }
492
+
493
+
430
494
  if(poly_buffer != static_poly_buffer) free(poly_buffer);
431
- // Clean up the result halves, now that they're copied into `result`
432
495
  }
433
496
  else {
434
497
  // If we don't have a divider we just copy out the polygons
data/src/bsp.h CHANGED
@@ -33,10 +33,12 @@ int bsp_subdivide(poly_t *divider, poly_t *poly,
33
33
  poly_t **coplanar_front, int *n_cp_front,
34
34
  poly_t **coplanar_back, int *n_cp_back,
35
35
  poly_t **front, int *n_front,
36
- poly_t **back, int *n_back);
36
+ poly_t **back, int *n_back,
37
+ poly_t **unused, int *n_unused,
38
+ poly_t **created, int *n_created);
37
39
 
38
40
  bsp_node_t *bsp_build(bsp_node_t *node, klist_t(poly) *polygons, int copy);
39
- bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys);
41
+ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys, int free_unused);
40
42
  klist_t(poly) *bsp_to_polygons(bsp_node_t *tree, int make_triangles, klist_t(poly) *dst);
41
43
 
42
44
  bsp_node_t *bsp_invert(bsp_node_t *tree);
data/src/commands.c ADDED
@@ -0,0 +1,105 @@
1
+ #include <string.h>
2
+ #include "dbg.h"
3
+
4
+ #include "commands.h"
5
+ #include "stl.h"
6
+ #include "bsp.h"
7
+ #include "export.h"
8
+
9
+ typedef bsp_node_t* (*bsp_binary_op)(bsp_node_t *, bsp_node_t *);
10
+
11
+ // A generalization of a binary CSG operation being performed on an STL
12
+ // in `path1` and `path1` defined by an operation `op` from` bsp.h
13
+ // Result is freshly allocated, and needs to be freed with `free_bsp_tree()`
14
+ bsp_node_t* bsp_binary_operation(char *path1, char *path2, bsp_binary_op op) {
15
+ stl_object *file1 = NULL;
16
+ bsp_node_t *bsp1 = NULL;
17
+
18
+ stl_object *file2 = NULL;
19
+ bsp_node_t *bsp2 = NULL;
20
+
21
+ bsp_node_t *result = NULL;
22
+
23
+ // Read 1
24
+ file1 = stl_read_file(path1, 1);
25
+ check(file1 != NULL, "Failed to read .stl from '%s'", path1);
26
+ log_info("Loaded file: %s %d facets", path1, file1->facet_count);
27
+ bsp1 = stl_to_bsp(file1);
28
+ check_mem(bsp1);
29
+
30
+ // Read 2
31
+ file2 = stl_read_file(path2, 1);
32
+ check(file2 != NULL, "Failed to read .stl from '%s'", path2);
33
+ log_info("Loaded file: %s %d facets", path2, file2->facet_count);
34
+ bsp2 = stl_to_bsp(file2);
35
+ check_mem(bsp2);
36
+
37
+ // Operate
38
+ result = op(bsp1, bsp2);
39
+
40
+ if(file1 != NULL) stl_free(file1);
41
+ if(file2 != NULL) stl_free(file2);
42
+ if(bsp1 != NULL) free_bsp_tree(bsp1);
43
+ if(bsp2 != NULL) free_bsp_tree(bsp2);
44
+ return result;
45
+ error:
46
+ if(file1 != NULL) stl_free(file1);
47
+ if(file2 != NULL) stl_free(file2);
48
+ if(bsp1 != NULL) free_bsp_tree(bsp1);
49
+ if(bsp2 != NULL) free_bsp_tree(bsp2);
50
+ if(result != NULL) free_bsp_tree(result);
51
+ return NULL;
52
+ }
53
+
54
+ // Constructor for commands named after the CSG functions they perform.
55
+ // Produces a function named `cmd_<name>(int argc, char **argv) that reads
56
+ // two files and an optional output path and calls a matching function
57
+ // bsp_<name>(bsp_node_t*,bsp_node_t*) and writes the resulting mesh
58
+ // to disk as either `./out.stl` or the value of argv[2]
59
+ // Uses the above `bsp_binary_operation(..)` wrapper to do most of the
60
+ // heavy lifting.
61
+ #define MAKE_CSG_COMMAND(name) \
62
+ int cmd_##name(int argc, char **argv) { \
63
+ bsp_node_t *result = NULL; \
64
+ stl_object *out = NULL; \
65
+ char *out_path = "./out.stl"; \
66
+ \
67
+ check(argc >= 2, "At least two input files required."); \
68
+ if(argc > 2) out_path = argv[2]; \
69
+ \
70
+ result = bsp_binary_operation(argv[0], argv[1], bsp_##name); \
71
+ out = bsp_to_stl(result); \
72
+ log_info("Writing output to %s", out_path); \
73
+ check(stl_write_file(out, out_path) == 0, "Failed to write STL to %s", out_path); \
74
+ \
75
+ if(result != NULL) free_bsp_tree(result); \
76
+ if(out != NULL) stl_free(out); \
77
+ return 0; \
78
+ error: \
79
+ if(result != NULL) free_bsp_tree(result); \
80
+ if(out != NULL) stl_free(out); \
81
+ return -1; \
82
+ }
83
+
84
+ // Each MAKE_BSP_COMMAND(name) results in a function named
85
+ // cmd_<name>(int argc, argv) which calls bsp_<name>() with
86
+ // two trees built from files in argv[0] and argv[1]
87
+ MAKE_CSG_COMMAND(intersect);
88
+ MAKE_CSG_COMMAND(union);
89
+ MAKE_CSG_COMMAND(subtract);
90
+
91
+ // Available commands
92
+ const cmd_t commands[] = {
93
+ {"intersect", "Intersect two geometries", cmd_intersect},
94
+ {"subtract", "Subtract two geometries", cmd_subtract},
95
+ {"union", "Union two geometries", cmd_union},
96
+ {NULL, NULL, NULL}
97
+ };
98
+
99
+ // Search for a command by name.
100
+ cmd_fun_t cmd_find(const char *name) {
101
+ for(cmd_t *c = (cmd_t*)commands; c->name != NULL; c++) {
102
+ if(0 == strcmp(c->name, name)) return c->fun;
103
+ }
104
+ return NULL;
105
+ }
data/src/commands.h ADDED
@@ -0,0 +1,17 @@
1
+ #include <stdio.h>
2
+
3
+ #ifndef __COMMANDS_H
4
+ #define __COMMANDS_H
5
+
6
+ typedef int (*cmd_fun_t)(int argc, char **argv);
7
+
8
+ typedef struct s_cmd_t {
9
+ char *name;
10
+ char *description;
11
+ cmd_fun_t fun;
12
+ } cmd_t;
13
+
14
+ extern const cmd_t commands[];
15
+ cmd_fun_t cmd_find(const char *name);
16
+
17
+ #endif
data/src/poly.c CHANGED
@@ -13,11 +13,17 @@ error:
13
13
 
14
14
  void free_poly(poly_t *p, int free_self) {
15
15
  if(p == NULL) return;
16
+ if(poly_vertex_dynamic_p(p) == 1) {
17
+ if(p->vertices != NULL) free(p->vertices);
18
+ p->vertices = NULL;
19
+ }
16
20
  if(free_self) free(p);
17
21
  }
18
22
 
19
23
  poly_t *poly_init(poly_t *poly) {
20
24
  poly->vertex_count = 0;
25
+ poly->vertex_max = POLY_MAX_VERTS;
26
+ poly->vertices = poly->_vbuffer;
21
27
  return poly;
22
28
  }
23
29
 
@@ -25,8 +31,23 @@ poly_t *clone_poly(poly_t *poly) {
25
31
  poly_t *copy = NULL;
26
32
  check_mem(copy = alloc_poly());
27
33
  memcpy(copy, poly, sizeof(poly_t));
34
+
35
+ // Either point the clone at its own copied
36
+ // buffer, or copy over the dynamic vertex buffer
37
+ if(poly_vertex_dynamic_p(poly) == 0) {
38
+ copy->vertices = copy->_vbuffer;
39
+ }
40
+ else {
41
+ // We can lean on the `copy->*` memebers
42
+ // since they would have been memcpy'd over
43
+ copy->vertices = malloc(poly_vertex_max(copy) * sizeof(float3));
44
+ check_mem(copy->vertices);
45
+ memcpy(copy->vertices, poly->vertices, poly_vertex_max(copy) * sizeof(float3));
46
+ }
47
+
28
48
  return copy;
29
49
  error:
50
+ if(copy != NULL) free_poly(copy, 1);
30
51
  return NULL;
31
52
  }
32
53
 
@@ -53,10 +74,47 @@ int poly_vertex_count(poly_t *poly) {
53
74
  return poly->vertex_count;
54
75
  }
55
76
 
56
- // Add a vertex to the end of the polygon vertex list
77
+ int poly_vertex_max(poly_t *poly) {
78
+ return poly->vertex_max;
79
+ }
80
+
81
+ int poly_vertex_available(poly_t *poly) {
82
+ return poly->vertex_max - poly->vertex_count;
83
+ }
84
+
85
+ // Has the vertex buffer been dynamically allocated?
86
+ int poly_vertex_dynamic_p(poly_t *poly) {
87
+ return (poly->vertices != poly->_vbuffer) ? 1 : 0;
88
+ }
89
+
90
+ int poly_vertex_expand(poly_t *poly) {
91
+ // Not using realloc because the original buffer may be struct-owned
92
+ int new_size = poly->vertex_max * 2;
93
+ float3 *new_verts = malloc(new_size * sizeof(float3));
94
+ check_mem(new_verts);
95
+
96
+ memcpy(new_verts, poly->vertices, poly->vertex_max * sizeof(float3));
97
+ poly->vertex_max = new_size;
98
+
99
+ // Free the existing buffer if it's not part of the struct's space
100
+ if(poly_vertex_dynamic_p(poly) == 1) {
101
+ free(poly->vertices);
102
+ }
103
+
104
+ // Install the new vertex buffer
105
+ poly->vertices = new_verts;
106
+
107
+ return 0;
108
+ error:
109
+ if(new_verts != NULL) free(new_verts);
110
+ return -1;
111
+ }
112
+
113
+ // add a vertex to the end of the polygon vertex list
57
114
  int poly_push_vertex(poly_t *poly, float3 v) {
58
- // TODO: Don't assert, grow
59
- assert(poly->vertex_count < POLY_MAX_VERTS);
115
+ if(poly_vertex_available(poly) == 0) {
116
+ poly_vertex_expand(poly);
117
+ }
60
118
 
61
119
  // Dat assignment copy
62
120
  poly->vertices[poly->vertex_count][0] = v[0];
data/src/poly.h CHANGED
@@ -12,14 +12,19 @@
12
12
  #define BACK 2
13
13
  #define SPANNING 3
14
14
 
15
+ #ifndef POLY_MAX_VERTS
15
16
  #define POLY_MAX_VERTS 40
17
+ #endif
16
18
 
17
19
  typedef struct s_poly {
18
- float3 vertices[POLY_MAX_VERTS];
20
+ float3 *vertices;
19
21
  int vertex_count;
22
+ int vertex_max;
20
23
 
21
24
  float3 normal;
22
25
  float w;
26
+
27
+ float3 _vbuffer[POLY_MAX_VERTS];
23
28
  } poly_t;
24
29
 
25
30
  poly_t *alloc_poly(void);
@@ -32,6 +37,10 @@ int poly_update(poly_t *poly);
32
37
  poly_t *poly_invert(poly_t *poly);
33
38
 
34
39
  int poly_vertex_count(poly_t *poly);
40
+ int poly_vertex_max(poly_t *poly);
41
+ int poly_vertex_available(poly_t *poly);
42
+ int poly_vertex_dynamic_p(poly_t *poly);
43
+ int poly_vertex_expand(poly_t *poly);
35
44
  int poly_push_vertex(poly_t *poly, float3 v);
36
45
 
37
46
  int poly_classify_vertex(poly_t *poly, float3 v);
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
5
- prerelease:
4
+ version: 0.0.3
6
5
  platform: ruby
7
6
  authors:
8
7
  - Yaroslav Shirokov
@@ -10,22 +9,20 @@ authors:
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2013-07-11 00:00:00.000000000 Z
12
+ date: 2013-09-23 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: ffi
17
16
  requirement: !ruby/object:Gem::Requirement
18
- none: false
19
17
  requirements:
20
- - - ! '>='
18
+ - - '>='
21
19
  - !ruby/object:Gem::Version
22
20
  version: '0'
23
21
  type: :runtime
24
22
  prerelease: false
25
23
  version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
24
  requirements:
28
- - - ! '>='
25
+ - - '>='
29
26
  - !ruby/object:Gem::Version
30
27
  version: '0'
31
28
  description: A fast library for Constructive Solid Geometry
@@ -40,12 +37,14 @@ files:
40
37
  - Makefile
41
38
  - lib/csg.rb
42
39
  - src/bsp.c
40
+ - src/commands.c
43
41
  - src/dbg.c
44
42
  - src/export.c
45
43
  - src/poly.c
46
44
  - src/stl.c
47
45
  - src/vector.c
48
46
  - src/bsp.h
47
+ - src/commands.h
49
48
  - src/dbg.h
50
49
  - src/export.h
51
50
  - src/klist.h
@@ -55,26 +54,25 @@ files:
55
54
  - ext/Rakefile
56
55
  homepage: https://github.com/sshirokov/csgtool/
57
56
  licenses: []
57
+ metadata: {}
58
58
  post_install_message:
59
59
  rdoc_options: []
60
60
  require_paths:
61
61
  - lib
62
62
  required_ruby_version: !ruby/object:Gem::Requirement
63
- none: false
64
63
  requirements:
65
- - - ! '>='
64
+ - - '>='
66
65
  - !ruby/object:Gem::Version
67
66
  version: '0'
68
67
  required_rubygems_version: !ruby/object:Gem::Requirement
69
- none: false
70
68
  requirements:
71
- - - ! '>='
69
+ - - '>='
72
70
  - !ruby/object:Gem::Version
73
71
  version: '0'
74
72
  requirements: []
75
73
  rubyforge_project:
76
- rubygems_version: 1.8.23
74
+ rubygems_version: 2.0.3
77
75
  signing_key:
78
- specification_version: 3
76
+ specification_version: 4
79
77
  summary: A fast library for Constructive Solid Geometry
80
78
  test_files: []