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.
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
- int poly_push_vertex(poly_t *poly, float3 v);
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
- check_mem(obj);
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
- check_mem(obj->facets);
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
- float mag = sqrt(v1_x_v2[0]*v1_x_v2[0] + v1_x_v2[1]*v1_x_v2[1] + v1_x_v2[2]*v1_x_v2[2]);
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
- check_mem(facet);
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
- check_mem(facet);
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
- check_mem(obj->facets);
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++) {
@@ -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
- check_mem(mesh->stl = stl_alloc(NULL, 0));
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)* stl_mesh_to_polygons(void *self) {
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 = poly_make_triangle(mesh->stl->facets[i].vertices[0],
35
- mesh->stl->facets[i].vertices[1],
36
- mesh->stl->facets[i].vertices[2]);
37
- check_mem(poly);
38
- *kl_pushp(poly, polys) = poly;
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
- error:
44
- if(polys != NULL) kl_destroy(poly, polys);
45
- return NULL;
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
@@ -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 "ctype.h"
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
- check_mem(copy_str = calloc(strlen(str) + 1, sizeof(char)));
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 = NULL;
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 = NULL;
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
- check_mem(line = calloc(strlen(read_buffer) + 1, sizeof(char)));
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
- check_mem(new_line = calloc(strlen(line) + strlen(read_buffer) + 1, sizeof(char)));
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
@@ -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 = sqrt((*v)[0] * (*v)[0] +
15
- (*v)[1] * (*v)[1] +
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
+ }
@@ -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.3
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-04-01 00:00:00.000000000 Z
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.0.3
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