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 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
+ }