csg 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 032ae67480be4a8091aaceae652d8f7ba608c799
4
- data.tar.gz: e9c632170b74ef2bc33a62f4f54f6a39be8176e2
3
+ metadata.gz: 75fa78d0a7457950ab6f58724d12d6889a1ad040
4
+ data.tar.gz: e42df82e618300fd3ecbb378b5671e30c241adc0
5
5
  SHA512:
6
- metadata.gz: 59540582ac22f6e0beb5158c023e2e492ac470ca52e324c807d14869c1d1d8b00dbb8825d2b52ffdcd271aa553b263e918a4004e7af00a500bdfd75aeea32e00
7
- data.tar.gz: e53ca53c28394c684e3647660350725a2db98cc4a232f652aa4d785ae8a0d9c3b23e35e0a3b725f69ee4fb53ccf4024b784aa76f5e25e67af35e25b9af5cf443
6
+ metadata.gz: f38fca9b843039bd79aee405e6b25fb9284f925cb3799ab9b11438800c76960c47a688bf5ed4e6946a52ae8f915712dbae7152103c1df9c582153dd2d7bd42ff
7
+ data.tar.gz: 8aa32fdda09f7abba5cbac125581ac258cee68761a97eddd659749a6408268846dc377e85a319c2716c71f7ba6e05c97c810e5384dcd0f548d4c27f430560a58
data/Makefile CHANGED
@@ -10,6 +10,17 @@ CPPFLAGS = $(OPTCPPFLAGS)
10
10
  LIBS = -lm $(OPTLIBS)
11
11
  CFLAGS = -D_POSIX_C_SOURCE=200112L -g -std=c99 $(INCLUDE) -Wall -Werror $(OPTFLAGS)
12
12
 
13
+ # If DEBUG is set, we build a new set of objects and a new target
14
+ ifneq ($(origin DEBUG), undefined)
15
+ OBJS = $(patsubst %.c,%.dbg.o,$(SOURCES))
16
+ TARGET := $(TARGET).dbg
17
+ endif
18
+
19
+ # If RELEASE is set, we turn on NDEBUG and NO_LINENOS
20
+ ifneq ($(origin RELEASE), undefined)
21
+ CFLAGS += -DNDEBUG -DNO_LINENOS -UDEBUG
22
+ endif
23
+
13
24
  ifeq ($(shell uname),Darwin)
14
25
  LIB_TARGET = libcsg.dylib
15
26
  else
@@ -20,11 +31,11 @@ endif
20
31
  all: $(TARGET) $(LIB_TARGET)
21
32
 
22
33
  clean:
23
- make -C tests clean
34
+ $(MAKE) -C tests clean
24
35
  rm -rf $(OBJS) $(TARGET) $(TARGET).o $(TARGET).new $(LIB_TARGET)
25
36
 
26
37
  test:
27
- @make -C tests clean test
38
+ @$(MAKE) -C tests clean test
28
39
 
29
40
  .PHONY: all clean test libcsg loc
30
41
 
@@ -37,6 +48,10 @@ $(LIB_TARGET): $(OBJS)
37
48
 
38
49
  libcsg: $(LIB_TARGET)
39
50
 
51
+
52
+ %.dbg.o: %.c
53
+ $(CC) -fPIC $(CFLAGS) -DDEBUG -o $@ -c $^
54
+
40
55
  %.o: %.c
41
56
  $(CC) -fPIC $(CFLAGS) -o $@ -c $^
42
57
 
data/lib/csg.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'ffi'
2
2
 
3
3
  module CSG
4
+ class Error < StandardError; end
5
+
4
6
  module Native
5
7
  extend FFI::Library
6
8
 
@@ -70,7 +72,7 @@ module CSG
70
72
  if not mesh_ptr.null?
71
73
  @mesh = CSG::Native::Mesh.new mesh_ptr
72
74
  else
73
- raise Exception.new("Failed to produce Mesh from #{path}")
75
+ raise CSG::Error.new("Failed to produce Mesh from #{path}")
74
76
  end
75
77
  end
76
78
 
@@ -83,25 +85,25 @@ module CSG
83
85
  define_method name do |solid|
84
86
  # I'm so paranoid because ruby will gladly FFI through a
85
87
  # *NULL and explode if you ask, and that's much worse.
86
- raise Exception.new("The calling mesh is a NULL pointer") if mesh.null?
87
- raise Exception.new("The parameter mesh is a NULL pointer") if solid.mesh.null?
88
+ raise CSG::Error.new("The calling mesh is a NULL pointer") if mesh.null?
89
+ raise CSG::Error.new("The parameter mesh is a NULL pointer") if solid.mesh.null?
88
90
 
89
- raise Exception.new("My BSP tree is NULL.") if (my_bsp_ptr = mesh[:to_bsp].call mesh).null?
91
+ raise CSG::Error.new("My BSP tree is NULL.") if (my_bsp_ptr = mesh[:to_bsp].call mesh).null?
90
92
  # Assign ASAP in case the exception triggers an unwind, and I want the GC to know about this
91
93
  my_bsp = CSG::Native::BSPNode.new(my_bsp_ptr)
92
94
 
93
- raise Exception.new("My BSP tree is NULL.") if (their_bsp_ptr = solid.mesh[:to_bsp].call solid.mesh).null?
95
+ raise CSG::Error.new("My BSP tree is NULL.") if (their_bsp_ptr = solid.mesh[:to_bsp].call solid.mesh).null?
94
96
  their_bsp = CSG::Native::BSPNode.new(their_bsp_ptr)
95
97
 
96
98
  result_ptr = CSG::Native.send "bsp_#{name}", my_bsp, their_bsp
97
- raise Exception.new("Result of #{name} is NULL") if result_ptr.null?
99
+ raise CSG::Error.new("Result of #{name} is NULL") if result_ptr.null?
98
100
 
99
101
  # We will not wrap the result in a CSG::Native::BSPNode because
100
102
  # to avoid garbage collection, and we'll manage this pointer
101
103
  # inside of the CSG::Native::Mesh object we get with
102
104
  # bsp_to_mesh(.., 0) - which will not clone the input parameter
103
105
  result_mesh_ptr = CSG::Native.bsp_to_mesh result_ptr, 0
104
- raise Exception.new("Failed to wrap BSPNode(#{result_mesh_ptr} pointer as a Mesh, got NULL") if result_mesh_ptr.null?
106
+ raise CSG::Error.new("Failed to wrap BSPNode(#{result_mesh_ptr} pointer as a Mesh, got NULL") if result_mesh_ptr.null?
105
107
  CSG::Solid.new :mesh => CSG::Native::Mesh.new(result_mesh_ptr)
106
108
  end
107
109
  end
data/src/bsp.c CHANGED
@@ -2,33 +2,29 @@
2
2
 
3
3
  #include "bsp.h"
4
4
  #include "dbg.h"
5
+ #include "util.h"
5
6
  #include "export.h"
6
7
  #include "bsp_mesh.h"
7
8
 
8
9
  bsp_node_t *alloc_bsp_node(void) {
9
10
  bsp_node_t *node = NULL;
10
- check_mem(node = calloc(1, sizeof(bsp_node_t)));
11
+ assert_mem(node = calloc(1, sizeof(bsp_node_t)));
11
12
  node->polygons = kl_init(poly);
12
13
  return node;
13
- error:
14
- return NULL;
15
14
  }
16
15
 
17
16
  bsp_node_t *clone_bsp_tree(bsp_node_t *tree) {
18
17
  bsp_node_t *copy = alloc_bsp_node();
19
- check_mem(copy);
20
18
 
21
19
  kliter_t(poly) *iter = kl_begin(tree->polygons);
22
20
  for(; iter != kl_end(tree->polygons); iter = kl_next(iter)) {
23
21
  poly_t *poly_copy = clone_poly(kl_val(iter));
24
- check_mem(poly_copy);
25
22
  *kl_pushp(poly, copy->polygons) = poly_copy;
26
23
  }
27
24
 
28
25
  free_poly(copy->divider, 1);
29
26
  if(tree->divider) {
30
27
  copy->divider = clone_poly(tree->divider);
31
- check_mem(copy->divider);
32
28
  }
33
29
  else {
34
30
  copy->divider = NULL;
@@ -36,17 +32,12 @@ bsp_node_t *clone_bsp_tree(bsp_node_t *tree) {
36
32
 
37
33
  if(tree->front != NULL) {
38
34
  copy->front = clone_bsp_tree(tree->front);
39
- check_mem(copy->front);
40
35
  }
41
36
  if(tree->back != NULL) {
42
37
  copy->back = clone_bsp_tree(tree->back);
43
- check_mem(copy->back);
44
38
  }
45
39
 
46
40
  return copy;
47
- error:
48
- if(copy != NULL) free_bsp_tree(copy);
49
- return NULL;
50
41
  }
51
42
 
52
43
  void free_bsp_node(bsp_node_t *node) {
@@ -98,11 +89,21 @@ int bsp_subdivide(poly_t *divider, poly_t *poly,
98
89
  poly_t *b = NULL;
99
90
  check(poly_split(divider, poly, &f, &b) == 0,
100
91
  "Failed to split polygon(%p) with divider(%p)", poly, divider);
101
- front[*n_front] = f;
102
- *n_front += 1;
103
92
 
104
- back[*n_back] = b;
105
- *n_back += 1;
93
+ // TODO: This is where shit can get weird.
94
+ // When we create polygons we have the option of rejecting them
95
+ // by freeing and setting them to NULL, preventing them from
96
+ // being added to the result lists
97
+
98
+ // Append to the front and back lists and counts
99
+ if(f != NULL) {
100
+ front[*n_front] = f;
101
+ *n_front += 1;
102
+ }
103
+ if(b != NULL) {
104
+ back[*n_back] = b;
105
+ *n_back += 1;
106
+ }
106
107
 
107
108
  // Do we care about telling the caller about polygons
108
109
  // who's pointers are not in any of the "real" lists?
@@ -113,10 +114,14 @@ int bsp_subdivide(poly_t *divider, poly_t *poly,
113
114
 
114
115
  // How about polygons that we just made?
115
116
  if(created != NULL) {
116
- created[*n_created] = f;
117
- *n_created += 1;
118
- created[*n_created] = b;
119
- *n_created += 1;
117
+ if(f != NULL) {
118
+ created[*n_created] = f;
119
+ *n_created += 1;
120
+ }
121
+ if(b != NULL) {
122
+ created[*n_created] = b;
123
+ *n_created += 1;
124
+ }
120
125
  }
121
126
  break;
122
127
  }
@@ -129,7 +134,7 @@ error:
129
134
 
130
135
  bsp_node_t *bsp_build(bsp_node_t *node, klist_t(poly) *polygons, int copy) {
131
136
  poly_t **polys = NULL;
132
- check_mem(polys = malloc(sizeof(poly_t*) * polygons->size));
137
+ assert_mem(polys = malloc(sizeof(poly_t*) * polygons->size));
133
138
 
134
139
  kliter_t(poly) *iter = NULL;
135
140
  int i = 0;
@@ -178,7 +183,6 @@ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys,
178
183
  // Allocate a node if we weren't given one. It's the nice
179
184
  // thing to do for people.
180
185
  node = alloc_bsp_node();
181
- check_mem(node);
182
186
  }
183
187
 
184
188
  if(n_polys == 0) return node;
@@ -193,14 +197,13 @@ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys,
193
197
  poly_i += 1;
194
198
 
195
199
  node->divider = clone_poly(polygons[0]);
196
- check_mem(node->divider);
197
200
  }
198
201
 
199
202
 
200
- check_mem(coplanar = malloc(sizeof(poly_t*) * n_polys));
201
- check_mem(front_p = malloc(sizeof(poly_t*) * n_polys));
202
- check_mem(back_p = malloc(sizeof(poly_t*) * n_polys));
203
- check_mem(unused = malloc(sizeof(poly_t*) * n_polys));
203
+ assert_mem(coplanar = malloc(sizeof(poly_t*) * n_polys));
204
+ assert_mem(front_p = malloc(sizeof(poly_t*) * n_polys));
205
+ assert_mem(back_p = malloc(sizeof(poly_t*) * n_polys));
206
+ assert_mem(unused = malloc(sizeof(poly_t*) * n_polys));
204
207
  for(; poly_i < n_polys; poly_i++) {
205
208
  poly = polygons[poly_i];
206
209
  rc = bsp_subdivide(node->divider, poly,
@@ -236,13 +239,11 @@ bsp_node_t *bsp_build_array(bsp_node_t *node, poly_t **polygons, size_t n_polys,
236
239
 
237
240
  if((n_front > 0)) {
238
241
  if(node->front == NULL) node->front = alloc_bsp_node();
239
- check_mem(node->front);
240
242
  check(bsp_build_array(node->front, front_p, n_front, free_unused) != NULL,
241
243
  "Failed to build front tree of bsp_node_array(%p)", node);
242
244
  }
243
245
  if((n_back > 0)) {
244
246
  if(node->back == NULL) node->back = alloc_bsp_node();
245
- check_mem(node->back);
246
247
  check(bsp_build_array(node->back, back_p, n_back, free_unused) != NULL,
247
248
  "Failed to build back tree of bsp_node(%p)", node);
248
249
  }
@@ -267,7 +268,6 @@ int bsp_copy_node_polygons(bsp_node_t *node, int make_triangles, klist_t(poly) *
267
268
  int vertex_count = poly_vertex_count(poly);
268
269
  if(!make_triangles || vertex_count == 3) {
269
270
  poly_t *copy = clone_poly(poly);
270
- check_mem(copy);
271
271
  *kl_pushp(poly, dst) = copy;
272
272
  }
273
273
  else if(vertex_count > 3){
@@ -278,7 +278,6 @@ int bsp_copy_node_polygons(bsp_node_t *node, int make_triangles, klist_t(poly) *
278
278
  v_cur = &poly->vertices[i];
279
279
  v_prev = &poly->vertices[i - 1];
280
280
  poly_t *tri = poly_make_triangle(poly->vertices[0], *v_prev, *v_cur);
281
- check_mem(tri);
282
281
  *kl_pushp(poly, dst) = tri;
283
282
  }
284
283
  }
@@ -369,7 +368,7 @@ klist_t(poly) *bsp_clip_polygon_array(bsp_node_t *node, poly_t **polygons, size_
369
368
 
370
369
  if(node->divider != NULL) {
371
370
  if((n_polys * 4) > STATIC_POLY_BUFFER_SIZE) {
372
- check_mem(poly_buffer = malloc((sizeof(poly_t*) * n_polys) * 4));
371
+ assert_mem(poly_buffer = malloc((sizeof(poly_t*) * n_polys) * 4));
373
372
  }
374
373
  front_array = poly_buffer;
375
374
  back_array = poly_buffer + n_polys;
@@ -394,7 +393,6 @@ klist_t(poly) *bsp_clip_polygon_array(bsp_node_t *node, poly_t **polygons, size_
394
393
  else {
395
394
  for(i = 0; i < n_front; i++) {
396
395
  copy = clone_poly(front_array[i]);
397
- check_mem(copy);
398
396
  *kl_pushp(poly, result) = copy;
399
397
  }
400
398
  }
@@ -418,8 +416,7 @@ klist_t(poly) *bsp_clip_polygon_array(bsp_node_t *node, poly_t **polygons, size_
418
416
  else {
419
417
  // If we don't have a divider we just copy out the polygons
420
418
  for(i = 0; i < n_polys; i++) {
421
- check_mem(p = clone_poly(polygons[i]));
422
- *kl_pushp(poly, result) = p;
419
+ *kl_pushp(poly, result) = clone_poly(polygons[i]);
423
420
  }
424
421
  }
425
422
 
@@ -433,7 +430,6 @@ error:
433
430
  klist_t(poly) *bsp_clip_polygons(bsp_node_t *node, klist_t(poly) *polygons, klist_t(poly) *dst) {
434
431
  klist_t(poly) *result = dst != NULL ? dst : kl_init(poly);
435
432
  kliter_t(poly) *iter = NULL;
436
- poly_t *p = NULL;
437
433
  int rc = -1;
438
434
 
439
435
  poly_t *static_poly_buffer[STATIC_POLY_BUFFER_SIZE];
@@ -450,7 +446,7 @@ klist_t(poly) *bsp_clip_polygons(bsp_node_t *node, klist_t(poly) *polygons, klis
450
446
 
451
447
  if(node->divider != NULL) {
452
448
  if((polygons->size * 4) > STATIC_POLY_BUFFER_SIZE) {
453
- check_mem(poly_buffer = malloc(sizeof(poly_t*) * polygons->size * 4));
449
+ assert_mem(poly_buffer = malloc(sizeof(poly_t*) * polygons->size * 4));
454
450
  }
455
451
  front_array = poly_buffer;
456
452
  back_array = poly_buffer + polygons->size;
@@ -465,7 +461,6 @@ klist_t(poly) *bsp_clip_polygons(bsp_node_t *node, klist_t(poly) *polygons, klis
465
461
  }
466
462
 
467
463
  int i;
468
- poly_t *copy = NULL;
469
464
  // Recur to the front tree, or copy my current front nodes to result.
470
465
  if(node->front) {
471
466
  result = bsp_clip_polygon_array(node->front, front_array, n_front, result);
@@ -473,9 +468,7 @@ klist_t(poly) *bsp_clip_polygons(bsp_node_t *node, klist_t(poly) *polygons, klis
473
468
  }
474
469
  else {
475
470
  for(i = 0; i < n_front; i++) {
476
- copy = clone_poly(front_array[i]);
477
- check_mem(copy);
478
- *kl_pushp(poly, result) = copy;
471
+ *kl_pushp(poly, result) = clone_poly(front_array[i]);
479
472
  }
480
473
  }
481
474
 
@@ -498,8 +491,7 @@ klist_t(poly) *bsp_clip_polygons(bsp_node_t *node, klist_t(poly) *polygons, klis
498
491
  else {
499
492
  // If we don't have a divider we just copy out the polygons
500
493
  for(iter = kl_begin(polygons); iter != kl_end(polygons); iter = kl_next(iter)) {
501
- check_mem(p = clone_poly(kl_val(iter)));
502
- *kl_pushp(poly, result) = p;
494
+ *kl_pushp(poly, result) = clone_poly(kl_val(iter));
503
495
  }
504
496
  }
505
497
 
@@ -527,8 +519,8 @@ bsp_node_t *bsp_subtract(bsp_node_t *tree_a, bsp_node_t *tree_b) {
527
519
  bsp_node_t *result = NULL;
528
520
  klist_t(poly) *b_polys = NULL;
529
521
 
530
- check_mem(a = clone_bsp_tree(tree_a));
531
- check_mem(b = clone_bsp_tree(tree_b));
522
+ a = clone_bsp_tree(tree_a);
523
+ b = clone_bsp_tree(tree_b);
532
524
 
533
525
  check(bsp_invert(a) != NULL, "Failed to invert A");
534
526
  check(bsp_clip(a, b) != NULL, "Failed to clip(A, B)");
@@ -544,7 +536,6 @@ bsp_node_t *bsp_subtract(bsp_node_t *tree_a, bsp_node_t *tree_b) {
544
536
  // TODO: Build a more balanced trees from the polys of
545
537
  // a instead of cloning a tree with potential gaps.
546
538
  result = clone_bsp_tree(a);
547
- check_mem(result);
548
539
 
549
540
  if(b_polys != NULL) kl_destroy(poly, b_polys);
550
541
  if(a != NULL) free_bsp_tree(a);
@@ -564,8 +555,8 @@ bsp_node_t *bsp_union(bsp_node_t *tree_a, bsp_node_t *tree_b) {
564
555
  bsp_node_t *result = NULL;
565
556
  klist_t(poly) *b_polys = NULL;
566
557
 
567
- check_mem(a = clone_bsp_tree(tree_a));
568
- check_mem(b = clone_bsp_tree(tree_b));
558
+ a = clone_bsp_tree(tree_a);
559
+ b = clone_bsp_tree(tree_b);
569
560
 
570
561
  check(bsp_clip(a, b) != NULL, "Failed to clip(A, B)");
571
562
  check(bsp_clip(b, a) != NULL, "Failed clip(B, A)");
@@ -579,7 +570,6 @@ bsp_node_t *bsp_union(bsp_node_t *tree_a, bsp_node_t *tree_b) {
579
570
  // TODO: Build a more balanced trees from the polys of
580
571
  // a instead of cloning a tree with potential gaps.
581
572
  result = clone_bsp_tree(a);
582
- check_mem(result);
583
573
 
584
574
  if(b_polys != NULL) kl_destroy(poly, b_polys);
585
575
  if(a != NULL) free_bsp_tree(a);
@@ -599,8 +589,8 @@ bsp_node_t *bsp_intersect(bsp_node_t *tree_a, bsp_node_t *tree_b) {
599
589
  bsp_node_t *result = NULL;
600
590
  klist_t(poly) *b_polys = NULL;
601
591
 
602
- check_mem(a = clone_bsp_tree(tree_a));
603
- check_mem(b = clone_bsp_tree(tree_b));
592
+ a = clone_bsp_tree(tree_a);
593
+ b = clone_bsp_tree(tree_b);
604
594
 
605
595
  check(bsp_invert(a) != NULL, "Failed to invert A");
606
596
  check(bsp_clip(b, a) != NULL, "Failed clip(B, A)");
@@ -616,7 +606,6 @@ bsp_node_t *bsp_intersect(bsp_node_t *tree_a, bsp_node_t *tree_b) {
616
606
  // TODO: Build a more balanced trees from the polys of
617
607
  // a instead of cloning a tree with potential gaps.
618
608
  result = clone_bsp_tree(a);
619
- check_mem(result);
620
609
 
621
610
  if(b_polys != NULL) kl_destroy(poly, b_polys);
622
611
  if(a != NULL) free_bsp_tree(a);
@@ -642,14 +631,12 @@ int bsp_count_polygons(bsp_node_t *tree) {
642
631
  int bsp_mesh_init(void *self, void *data) {
643
632
  bsp_mesh_t *mesh = (bsp_mesh_t*)self;
644
633
  if(data == NULL) {
645
- check_mem(mesh->bsp = alloc_bsp_node());
634
+ mesh->bsp = alloc_bsp_node();
646
635
  }
647
636
  else {
648
637
  mesh->bsp = (bsp_node_t*)data;
649
638
  }
650
639
  return 0;
651
- error:
652
- return -1;
653
640
  }
654
641
 
655
642
  void bsp_mesh_destroy(void *self) {
@@ -0,0 +1,72 @@
1
+ #include "cmd_audit.h"
2
+
3
+ #include "stl_mesh.h"
4
+
5
+ // The finalizer for `cmd_audit`. Cleans up the structures
6
+ // used, and then returns the value passed.
7
+ // Because I fuckign hate spelling this shit out twice, like I
8
+ // do literally everywhere else in this codebase.
9
+ #define __FINISH_CMD_AUDIT(ret) do { \
10
+ if(in != NULL) free_mesh(in); \
11
+ if(polys != NULL) kl_destroy(poly, polys); \
12
+ } while(false); \
13
+ return (ret)
14
+
15
+ // `audit` command entry point.
16
+ // Takes one mesh as the last arg then walks it looking for
17
+ // abnormalities.
18
+ int cmd_audit(int argc, char *argv[]) {
19
+ char *name = argv[argc - 1];
20
+ mesh_t *in = NULL;
21
+ klist_t(poly)* polys = NULL;
22
+
23
+ check(argc >= 1, "Too few args");
24
+ check(in = mesh_read_file(name), "Failed to read [%s]", name);
25
+ check(in->poly_count(in) > 0, "Mesh does not contain any polygons.");
26
+
27
+ // If we load an STL, we need to patch mesh->to_polygons(..) to
28
+ // a version that bypasses the `poly_push_vertex` checks, otherwise
29
+ // invalid polygons simply won't be created, and a shitload of warning
30
+ // spam will appear.
31
+ const char *stl_type = "STL";
32
+ if(strncmp(in->type, stl_type, strlen(stl_type)) == 0) {
33
+ log_info("Patching mesh to produce unsafe polygons.");
34
+ in->to_polygons = stl_mesh_to_polygons_unsafe;
35
+ }
36
+
37
+
38
+ log_info("Converting mesh to polygon list for walk.");
39
+ check(polys = in->to_polygons(in), "Failed to get polygons from mesh.");
40
+
41
+ // We should get the same number of polygons as we had in the original structure
42
+ // after conversion.
43
+ check(in->poly_count(in) == polys->size,
44
+ "Polygon counts differ after polygon list conversion. Mesh(%d) vs List(%zd)", in->poly_count(in), polys->size);
45
+
46
+ log_info("Loaded [%d] polys from '%s', beginning walk", in->poly_count(in), name);
47
+ kliter_t(poly) *iter = kl_begin(polys);
48
+ poly_t *poly = NULL;
49
+ size_t count = 0;
50
+ size_t bad_count = 0;
51
+ for(; iter != kl_end(polys); iter = kl_next(iter), count++) {
52
+ poly = kl_val(iter);
53
+ if(poly == NULL) {
54
+ log_warn("Failed to get polygon %zd from mesh, it is NULL", count);
55
+ bad_count++;
56
+ continue;
57
+ }
58
+
59
+ // If a squard edge length is zero, it's zero.
60
+ if(poly_min_edge_length2(poly) == 0.0) {
61
+ bad_count++;
62
+ log_warn("Poly %zd has an edge of length2 = %f", count, poly_min_edge_length2(poly));
63
+ poly_print(poly, stderr);
64
+ }
65
+ }
66
+
67
+ log_info("Checked %zd polygons. %zd had problems.", count, bad_count);
68
+
69
+ __FINISH_CMD_AUDIT(bad_count);
70
+ error:
71
+ __FINISH_CMD_AUDIT(-1);
72
+ }