BRL-CAD
test_root3-subd.cpp
Go to the documentation of this file.
1 /* T E S T _ R O O T 3 - S U B D . C P P
2  * BRL-CAD
3  *
4  * Copyright (c) 2013-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #include "common.h"
22 
23 #include <map>
24 #include <set>
25 #include <queue>
26 #include <list>
27 #include <iostream>
28 #include <fstream>
29 
30 #include "vmath.h"
31 #include "raytrace.h"
32 #include "wdb.h"
33 #include "plot3.h"
34 #include "opennurbs.h"
35 
36 
37 void
38 plot_face(ON_3dPoint *pt1, ON_3dPoint *pt2, ON_3dPoint *pt3, int r, int g, int b, FILE *c_plot)
39 {
40  point_t p1, p2, p3;
41 
42  VSET(p1, pt1->x, pt1->y, pt1->z);
43  VSET(p2, pt2->x, pt2->y, pt2->z);
44  VSET(p3, pt3->x, pt3->y, pt3->z);
45 
46  pl_color(c_plot, r, g, b);
47 
48  pdv_3move(c_plot, p1);
49  pdv_3cont(c_plot, p2);
50  pdv_3move(c_plot, p1);
51  pdv_3cont(c_plot, p3);
52  pdv_3move(c_plot, p2);
53  pdv_3cont(c_plot, p3);
54 }
55 
56 
57 struct Mesh_Info {
58  ON_3dPointArray points_p0;
59  ON_3dPointArray points_q;
60  ON_3dPointArray points_inf;
61  std::map<size_t, size_t> iteration_of_insert;
62  std::map<size_t, std::vector<size_t> > face_pts;
63  std::map<size_t, size_t> index_in_next;
64  std::map<size_t, size_t> point_valence;
65  std::multimap<size_t, size_t> point_neighbors;
66  std::map<std::pair<size_t, size_t>, std::set<size_t> > edges_to_faces;
67  size_t iteration_cnt;
68 };
69 
70 
71 // Kobbelt sqrt(3)-Subdivision, eqn. 1
72 void
73 find_q_pts(struct Mesh_Info *mesh)
74 {
75  std::map<size_t, std::vector<size_t> >::iterator f_it;
76  std::vector<size_t>::iterator l_it;
77 
78  for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) {
79  ON_3dPoint p1, p2, p3;
80 
81  l_it = (*f_it).second.begin();
82  p1 = *mesh->points_p0.At((int)(*l_it));
83  p2 = *mesh->points_p0.At((int)(*(l_it+1)));
84  p3 = *mesh->points_p0.At((int)(*(l_it+2)));
85 
86  ON_3dPoint q((p1.x + p2.x + p3.x)/3, (p1.y + p2.y + p3.y)/3, (p1.z + p2.z + p3.z)/3);
87  mesh->points_q.Append(q);
88  }
89 }
90 
91 
92 // Kobbelt sqrt(3)-Subdivision, eqn. 6
93 fastf_t
94 alpha_n(size_t n)
95 {
96  return (4 - 2 * cos(M_2PI/n))/9;
97 }
98 
99 
100 // From Kobbelt sqrt(3)-Subdivision, eqns 7 and 8, solving for pinf
101 void
102 point_inf(size_t p, struct Mesh_Info *mesh, ON_3dPointArray *p_a)
103 {
104  size_t n = mesh->point_valence[p];
105  std::multimap<size_t, size_t>::iterator p_it;
106  std::pair<std::multimap<size_t, size_t>::iterator, std::multimap<size_t, size_t>::iterator> range;
107 
108  range = mesh->point_neighbors.equal_range(p);
109 
110  ON_3dPoint psum = ON_3dPoint(0, 0, 0);
111  for (p_it = range.first; p_it != range.second; p_it++) {
112  psum = psum + *mesh->points_p0.At((int)(*p_it).second);
113  }
114 
115  fastf_t alpha = alpha_n(n);
116  //
117  // 3 an 1
118  // [pinf = ---------- * psum + -------- * p0]
119  // 3 an n + n 3 an + 1
120  //
121  ON_3dPoint pinf = (3*alpha/((3*alpha+1)*n))*psum + 1/(3*alpha+1) * *mesh->points_p0.At((int)p);
122  p_a->Append(pinf);
123 }
124 
125 
126 // Kobbelt sqrt(3)-Subdivision, eqn. 8
127 void
128 point_subdiv(size_t m, size_t p, struct Mesh_Info *mesh, ON_3dPointArray *p_a)
129 {
130  size_t n = mesh->point_valence[p];
131 
132  point_inf(p, mesh, &mesh->points_inf);
133 
134  fastf_t gamma = pow((2/3 - alpha_n(n)), m);
135  ON_3dPoint subdiv_pt = gamma * *mesh->points_p0.At((int)p) + (1-gamma) * *mesh->points_inf.At((int)p);
136 
137  p_a->Append(subdiv_pt);
138 }
139 
140 
141 // Kobbelt sqrt(3)-Subdivision, eqn. 9
142 ON_3dPoint
143 p_edge_new(ON_3dPoint *p1, ON_3dPoint *p2, ON_3dPoint *curr)
144 {
145  ON_3dPoint pnew = (10 * *p1 + 16 * *curr + *p2)/27;
146  return pnew;
147 }
148 
149 
150 ON_3dPoint
151 p_edge_move(ON_3dPoint *p1, ON_3dPoint *p2, ON_3dPoint *curr)
152 {
153  ON_3dPoint pmv = (4 * *p1 + 19 * *curr + 4 * *p2)/27;
154  return pmv;
155 }
156 
157 
158 // Break edge handling cases into functions. For each
159 
160 /* Case 1 - edge with no boundary points, face is internal to mesh
161  /
162  / C
163  / / \
164  / / ' \
165  / / ' \
166  / P1 / ' \ P2
167  / / ' \
168  / / ' P ' \
169  / / ' ' \
170  / / ' ' \
171  / /'_______________'\
172  / A B
173  /
174  / P3
175 */
176 // Edge is A->B, all face edges have an additional ajoint face. New
177 // faces associated with A->B are A->P3->P and P->P3->B.
178 
179 /* Case 2 - edge with one boundary point, face is on border of mesh
180  /
181  / Edge is A->B. If iteration count is odd:
182  /
183  / C
184  / / \
185  / / ' \
186  / / ' \
187  / / ' \ P2
188  / / ' \
189  / / ' P ' \
190  / / ' ' \
191  / / ' ' \
192  / /'_______________'\
193  / A B
194  /
195  / P3
196 */
197 // new faces are A->P3->P and P->P3->B
198 //
199 //
200 // If iteration count is even, there are two possible cases - depending on P3's A->X edge and
201 // whether it has one or two boundary points.
202 //
203 /* A->X has one boundary point:
204  /
205  / C
206  / / \
207  / / \
208  / E2 / \
209  / / \ P2
210  / / \
211  / E1 / \
212  / / \
213  / / \
214  / / _______________ \
215  / A B
216  / \ /
217  / \ /
218  / \ P3 /
219  / \ /
220  / \ /
221  / \ /
222  / P4 \ / P5
223  / \ /
224  / \ /
225  / X
226  /
227  /
228  /
229 */
230 // insert faces B->E1->P3 and P3->E1->A
231 //
232 /* A->X has two boundary points:
233  /
234  / C
235  / / \
236  / / \
237  / E2 / \
238  / / \ P2
239  / / \
240  / E1 / \
241  / / \
242  / / \
243  / / _______________ \
244  / A B
245  / \ /
246  / \ /
247  / \ /
248  / E3 \ /
249  / \ /
250  / \ /
251  / \ / P5
252  / E4 \ /
253  / \ /
254  / X
255  /
256 */
257 //
258 //
259 // insert faces B->E1->E3 and E1->A->E3
260 
261 
262 // Case 3 - edge with two boundary points, face is on border of mesh
263 //
264 //
265 /* Edge is A->B. If iteration count is odd
266  /
267  /
268  / C
269  / / \
270  / / ' \
271  / / ' \
272  / / ' \
273  / / ' \
274  / / ' P ' \
275  / / ' ' \
276  / / ' ' \
277  / /'_______________'\
278  / A B
279  /
280 */
281 // insert one face - A->B->P
282 //
283 /* If iteration count is even,
284  /
285  /
286  / C
287  / / \
288  / / \
289  / / \
290  / / \
291  / / \
292  / / \
293  / / \
294  / / \
295  / / _______________ \
296  / A B
297  /
298  / E1 E2
299 */
300 // insert one face - E1 -> E2 -> C
301 
302 
303 // Make an edge using consistent vertex ordering
304 std::pair<size_t, size_t>
305 mk_edge(size_t pt_A, size_t pt_B)
306 {
307  if (pt_A <= pt_B) {
308  return std::make_pair(pt_A, pt_B);
309  } else {
310  return std::make_pair(pt_B, pt_A);
311  }
312 }
313 
314 
315 void
316 mesh_add_face(size_t pt1, size_t pt2, size_t pt3, size_t face_cnt, struct Mesh_Info *mesh)
317 {
318  mesh->face_pts[face_cnt].push_back(pt1);
319  mesh->face_pts[face_cnt].push_back(pt2);
320  mesh->face_pts[face_cnt].push_back(pt3);
321 
322  mesh->edges_to_faces[mk_edge(pt1, pt2)].insert(face_cnt);
323  mesh->edges_to_faces[mk_edge(pt2, pt3)].insert(face_cnt);
324  mesh->edges_to_faces[mk_edge(pt3, pt1)].insert(face_cnt);
325 
326  mesh->point_neighbors.insert(std::pair<size_t, size_t>(pt1, pt2));
327  mesh->point_neighbors.insert(std::pair<size_t, size_t>(pt2, pt3));
328  mesh->point_neighbors.insert(std::pair<size_t, size_t>(pt3, pt1));
329 
330  mesh->point_valence[pt1] += 1;
331  mesh->point_valence[pt2] += 1;
332  mesh->point_valence[pt3] += 1;
333 }
334 
335 
336 void
337 mesh_info_init(struct rt_bot_internal *bot, struct Mesh_Info *mesh)
338 {
339  for (size_t i = 0; i < bot->num_vertices; ++i) {
340  mesh->points_p0.Append(ON_3dPoint(&bot->vertices[i*3]));
341  mesh->iteration_of_insert[i] = 0;
342  }
343 
344  for (size_t i = 0; i < bot->num_faces; ++i) {
345  mesh_add_face(bot->faces[i*3+0], bot->faces[i*3+1], bot->faces[i*3+2], i, mesh);
346  }
347 
348  mesh->iteration_cnt = 0;
349 }
350 
351 
352 // Find all edges in mesh
353 void
354 get_all_edges(struct Mesh_Info *mesh, std::set<std::pair<size_t, size_t> > *edges)
355 {
356  std::map<size_t, std::vector<size_t> >::iterator f_it;
357  std::vector<size_t>::iterator l_it;
358 
359  for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) {
360  l_it = (*f_it).second.begin();
361  edges->insert(mk_edge((*l_it), (*(l_it+1))));
362  edges->insert(mk_edge((*(l_it+1)), (*(l_it+2))));
363  edges->insert(mk_edge((*(l_it+2)), (*l_it)));
364  }
365 }
366 
367 
368 // Find outer edge segments and vertices
369 void
370 get_boundaries(struct Mesh_Info *mesh, std::set<size_t> *outer_pts, std::set<std::pair<size_t, size_t> > *outer_edges, std::set<size_t> *outer_faces)
371 {
372  std::map<std::pair<size_t, size_t>, std::set<size_t> >::iterator e_it;
373 
374  for (e_it = mesh->edges_to_faces.begin(); e_it!=mesh->edges_to_faces.end(); e_it++) {
375  if ((*e_it).second.size() == 1) {
376  outer_edges->insert((*e_it).first);
377  outer_faces->insert(*(*e_it).second.begin());
378  outer_pts->insert((*e_it).first.first);
379  outer_pts->insert((*e_it).first.second);
380  }
381  }
382 }
383 
384 
385 // Core subdivision iteration loop
386 struct Mesh_Info *
387 iterate(struct rt_bot_internal *bot, struct Mesh_Info *prev_mesh)
388 {
389  std::map<size_t, std::vector<size_t> >::iterator f_it;
390  std::vector<size_t>::iterator l_it;
391 
392  struct Mesh_Info *starting_mesh;
393  if (!prev_mesh) {
394  starting_mesh = new Mesh_Info;
395  mesh_info_init(bot, starting_mesh);
396  } else {
397  starting_mesh = prev_mesh;
398  }
399  struct Mesh_Info *mesh = new Mesh_Info;
400 
401  mesh->iteration_cnt = starting_mesh->iteration_cnt + 1;
402 
403  find_q_pts(starting_mesh);
404 
405  std::set<std::pair<size_t, size_t> > old_edges;
406  std::set<std::pair<size_t, size_t> >::iterator e_it;
407  get_all_edges(starting_mesh, &old_edges);
408 
409  std::set<std::pair<size_t, size_t> > outer_edges;
410  std::set<size_t > outer_pts;
411  std::set<size_t > outer_faces;
412  get_boundaries(starting_mesh, &outer_pts, &outer_edges, &outer_faces);
413 
414  std::cout << "outer pt count: " << outer_pts.size() << "\n";
415  std::cout << "outer edge count: " << outer_edges.size() << "\n";
416  std::cout << "outer face count: " << outer_faces.size() << "\n";
417 
418  // Relax old points here
419  for (size_t pcnt = 0; pcnt < (size_t)starting_mesh->points_p0.Count(); pcnt++) {
420  mesh->points_p0.Append(*starting_mesh->points_p0.At((int)pcnt));
421  mesh->iteration_of_insert[pcnt] = starting_mesh->iteration_of_insert[pcnt];
422  }
423 
424  for (f_it = starting_mesh->face_pts.begin(); f_it != starting_mesh->face_pts.end(); f_it++) {
425  mesh->points_p0.Append(starting_mesh->points_q[(int)(*f_it).first]);
426  mesh->iteration_of_insert[mesh->points_p0.Count()-1] = mesh->iteration_cnt;
427  starting_mesh->index_in_next[(*f_it).first] = mesh->points_p0.Count()-1;
428  }
429 
430  // Use the old faces to guide the insertion of the new.
431  size_t face_cnt = 0;
432  for (f_it = starting_mesh->face_pts.begin(); f_it != starting_mesh->face_pts.end(); f_it++) {
433  std::set<std::pair<size_t, size_t> > face_old_edges;
434 
435  size_t q0 = starting_mesh->index_in_next[(*f_it).first];
436  l_it = (*f_it).second.begin();
437 
438  face_old_edges.insert(std::make_pair((*l_it), (*(l_it+1))));
439  face_old_edges.insert(std::make_pair((*(l_it+1)), (*(l_it+2))));
440  face_old_edges.insert(std::make_pair((*(l_it+2)), (*l_it)));
441 
442  for (e_it = face_old_edges.begin(); e_it != face_old_edges.end(); e_it++) {
443  std::pair<size_t, size_t> edge = mk_edge((*e_it).first, (*e_it).second);
444 
445  if (old_edges.find(edge) != old_edges.end()) {
446  if (outer_edges.find(edge) == outer_edges.end()) {
447 
448  std::set<size_t> curr_faces = starting_mesh->edges_to_faces[edge];
449 
450  curr_faces.erase((*f_it).first);
451  size_t q1 = starting_mesh->index_in_next[*curr_faces.begin()];
452 
453  if (outer_faces.find(q0) != outer_faces.end() && outer_faces.find(q1) != outer_faces.end()) {
454  std::cout << "Got two edge faces\n";
455  }
456 
457  mesh_add_face((*e_it).first, q1, q0, face_cnt, mesh);
458  face_cnt++;
459  mesh_add_face((*e_it).second, q0, q1, face_cnt, mesh);
460  face_cnt++;
461  old_edges.erase(edge);
462  } else {
463  if (mesh->iteration_cnt % 2 == 0) {
464  std::cout << "second iteration: " << q0 << "\n";
465  } else {
466  mesh_add_face((*e_it).first, (*e_it).second, q0, face_cnt, mesh);
467  face_cnt++;
468  old_edges.erase(edge);
469  }
470  }
471  }
472  }
473  }
474 
475  delete starting_mesh;
476  return mesh;
477 }
478 
479 
480 int
481 main(int argc, char *argv[])
482 {
483  struct db_i *dbip;
484  struct directory *dp;
485  struct rt_db_internal intern;
486  struct rt_bot_internal *bot_ip = NULL;
487  struct rt_wdb *wdbp;
488  struct bu_vls name;
489  struct bu_vls bname;
490  struct Mesh_Info *prev_mesh = NULL;
491  struct Mesh_Info *mesh = NULL;
492 
493  bu_vls_init(&name);
494 
495  if (argc != 3) {
496  bu_exit(1, "Usage: %s file.g object", argv[0]);
497  }
498 
499  dbip = db_open(argv[1], DB_OPEN_READWRITE);
500  if (dbip == DBI_NULL) {
501  bu_exit(1, "ERROR: Unable to read from geometry database file %s\n", argv[1]);
502  }
503 
504  if (db_dirbuild(dbip) < 0)
505  bu_exit(1, "ERROR: Unable to read from %s\n", argv[1]);
506 
507  dp = db_lookup(dbip, argv[2], LOOKUP_QUIET);
508  if (dp == RT_DIR_NULL) {
509  bu_exit(1, "ERROR: Unable to look up object %s\n", argv[2]);
510  }
511 
512  RT_DB_INTERNAL_INIT(&intern)
513  if (rt_db_get_internal(&intern, dp, dbip, NULL, &rt_uniresource) < 0) {
514  bu_exit(1, "ERROR: Unable to get internal representation of %s\n", argv[2]);
515  }
516 
517  if (intern.idb_minor_type != DB5_MINORTYPE_BRLCAD_BOT) {
518  bu_exit(1, "ERROR: object %s does not appear to be of type BoT\n", argv[2]);
519  } else {
520  bot_ip = (struct rt_bot_internal *)intern.idb_ptr;
521  }
522  RT_BOT_CK_MAGIC(bot_ip);
523 
524  for (size_t i_cnt = 1; i_cnt < 3; i_cnt++) {
525  mesh = iterate(bot_ip, prev_mesh);
526  prev_mesh = mesh;
527 
528  // Plot results
529  struct bu_vls fname;
530  bu_vls_init(&fname);
531  bu_vls_printf(&fname, "root3_%d.pl", i_cnt);
532  FILE* plot_file = fopen(bu_vls_addr(&fname), "w");
533  std::map<size_t, std::vector<size_t> >::iterator f_it;
534  std::vector<size_t>::iterator l_it;
535  int r = int(256*drand48() + 1.0);
536  int g = int(256*drand48() + 1.0);
537  int b = int(256*drand48() + 1.0);
538  for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) {
539  l_it = (*f_it).second.begin();
540  plot_face(&mesh->points_p0[(int)(*l_it)], &mesh->points_p0[(int)(*(l_it+1))], &mesh->points_p0[(int)(*(l_it+2))], r, g , b, plot_file);
541  }
542  fclose(plot_file);
543  }
544 
545  // When constructing the final BoT, use the limit points for all
546  // vertices
547  ON_3dPointArray points_inf;
548  for (size_t v = 0; v < (size_t)mesh->points_p0.Count(); v++) {
549  points_inf.Append(*mesh->points_p0.At((int)v));
550  //point_inf(v, mesh, &points_inf);
551  }
552  // The subdivision process shrinks the bot relative to its original
553  // vertex positions - to better approximate the original surface,
554  // average the change in position of the original vertices to get a
555  // scaling factor and apply it to all points in the final mesh.
556  fastf_t scale = 0.0;
557  for (size_t pcnt = 0; pcnt < bot_ip->num_vertices; pcnt++) {
558  ON_3dVector v1(ON_3dPoint(&bot_ip->vertices[pcnt*3]));
559  ON_3dVector v2(*points_inf.At((int)pcnt));
560  scale += 1 + (v1.Length() - v2.Length())/v1.Length();
561  }
562  scale = scale / bot_ip->num_vertices;
563  for (size_t pcnt = 0; pcnt < (size_t)points_inf.Count(); pcnt++) {
564  ON_3dPoint p0(*points_inf.At((int)pcnt));
565  ON_3dPoint p1 = p0 * scale;
566  *points_inf.At((int)pcnt) = p1;
567  }
568 
569  wdbp = wdb_dbopen(dbip, RT_WDB_TYPE_DB_DISK);
570 
571  fastf_t *vertices = (fastf_t *)bu_malloc(sizeof(fastf_t) * points_inf.Count() * 3, "new verts");
572  int *faces = (int *)bu_malloc(sizeof(int) * mesh->face_pts.size() * 3, "new faces");
573  for (size_t v = 0; v < (size_t)points_inf.Count(); v++) {
574  vertices[v*3] = points_inf[(int)v].x;
575  vertices[v*3+1] = points_inf[(int)v].y;
576  vertices[v*3+2] = points_inf[(int)v].z;
577  }
578  std::map<size_t, std::vector<size_t> >::iterator f_it;
579  std::vector<size_t>::iterator l_it;
580  for (f_it = mesh->face_pts.begin(); f_it != mesh->face_pts.end(); f_it++) {
581  l_it = (*f_it).second.begin();
582  faces[(*f_it).first*3] = (*l_it);
583  faces[(*f_it).first*3+1] = (*(l_it + 1));
584  faces[(*f_it).first*3+2] = (*(l_it + 2));
585  }
586 
587  bu_vls_init(&bname);
588  bu_vls_sprintf(&bname, "%s_subd", argv[2]);
589  mk_bot(wdbp, bu_vls_addr(&bname), RT_BOT_SOLID, RT_BOT_UNORIENTED, 0, points_inf.Count(), mesh->face_pts.size(), vertices, faces, (fastf_t *)NULL, (struct bu_bitv *)NULL);
590  wdb_close(wdbp);
591  bu_vls_free(&bname);
592 
593  bu_free(vertices, "free subdivision BoT vertices");
594  bu_free(faces, "free subdivision BoT faces");
595 
596  return 0;
597 }
598 
599 
600 // Local Variables:
601 // tab-width: 8
602 // mode: C++
603 // c-basic-offset: 4
604 // indent-tabs-mode: t
605 // c-file-style: "stroustrup"
606 // End:
607 // ex: shiftwidth=4 tabstop=8
void bu_vls_init(struct bu_vls *vp)
Definition: vls.c:56
int mk_bot(struct rt_wdb *fp, const char *name, unsigned char mode, unsigned char orientation, unsigned char error_mode, size_t num_vertices, size_t num_faces, fastf_t *vertices, int *faces, fastf_t *thickness, struct bu_bitv *face_mode)
Definition: bot.c:121
ON_3dPoint p_edge_move(ON_3dPoint *p1, ON_3dPoint *p2, ON_3dPoint *curr)
Definition: raytrace.h:800
int rt_db_get_internal(struct rt_db_internal *ip, const struct directory *dp, const struct db_i *dbip, const mat_t mat, struct resource *resp)
Definition: dir.c:76
ON_3dPointArray points_q
void pdv_3move(register FILE *plotfp, const fastf_t *pt)
Definition: plot3.c:618
std::map< size_t, std::vector< size_t > > face_pts
#define VSET(a, b, c, d)
Definition: color.c:53
size_t iteration_cnt
struct directory * db_lookup(const struct db_i *, const char *name, int noisy)
Definition: db_lookup.c:153
void find_q_pts(struct Mesh_Info *mesh)
Header file for the BRL-CAD common definitions.
ON_3dPoint p_edge_new(ON_3dPoint *p1, ON_3dPoint *p2, ON_3dPoint *curr)
ON_3dPointArray points_p0
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
std::pair< size_t, size_t > mk_edge(size_t pt_A, size_t pt_B)
#define DB_OPEN_READWRITE
Definition: raytrace.h:3555
void bu_vls_free(struct bu_vls *vp)
Definition: vls.c:248
struct resource rt_uniresource
default. Defined in librt/globals.c
Definition: globals.c:41
void bu_exit(int status, const char *fmt,...) _BU_ATTR_NORETURN _BU_ATTR_PRINTF23
Definition: bomb.c:195
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
void bu_vls_sprintf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:707
void get_boundaries(struct Mesh_Info *mesh, std::set< size_t > *outer_pts, std::set< std::pair< size_t, size_t > > *outer_edges, std::set< size_t > *outer_faces)
#define LOOKUP_QUIET
Definition: raytrace.h:893
std::map< std::pair< size_t, size_t >, std::set< size_t > > edges_to_faces
#define RT_WDB_TYPE_DB_DISK
Definition: raytrace.h:1295
void plot_face(ON_3dPoint *pt1, ON_3dPoint *pt2, ON_3dPoint *pt3, int r, int g, int b, FILE *c_plot)
void pdv_3cont(register FILE *plotfp, const fastf_t *pt)
Definition: plot3.c:630
void point_inf(size_t p, struct Mesh_Info *mesh, ON_3dPointArray *p_a)
char * bu_vls_addr(const struct bu_vls *vp)
Definition: vls.c:111
double drand48(void)
ustring alpha
void pl_color(register FILE *plotfp, int r, int g, int b)
Definition: plot3.c:325
void wdb_close(struct rt_wdb *wdbp)
Definition: wdb.c:333
void * idb_ptr
Definition: raytrace.h:195
void mesh_info_init(struct rt_bot_internal *bot, struct Mesh_Info *mesh)
std::multimap< size_t, size_t > point_neighbors
#define DBI_NULL
Definition: raytrace.h:827
void point_subdiv(size_t m, size_t p, struct Mesh_Info *mesh, ON_3dPointArray *p_a)
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
#define RT_DIR_NULL
Definition: raytrace.h:875
ON_3dPointArray points_inf
struct db_i * db_open(const char *name, const char *mode)
Definition: db_open.c:59
struct Mesh_Info * iterate(struct rt_bot_internal *bot, struct Mesh_Info *prev_mesh)
std::map< size_t, size_t > iteration_of_insert
int idb_minor_type
ID_xxx.
Definition: raytrace.h:193
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
std::map< size_t, size_t > point_valence
void mesh_add_face(size_t pt1, size_t pt2, size_t pt3, size_t face_cnt, struct Mesh_Info *mesh)
int db_dirbuild(struct db_i *dbip)
Definition: db5_scan.c:301
void get_all_edges(struct Mesh_Info *mesh, std::set< std::pair< size_t, size_t > > *edges)
fastf_t alpha_n(size_t n)
Definition: bitv.h:105
int main(int argc, char *argv[])
std::map< size_t, size_t > index_in_next
Definition: vls.h:56
double fastf_t
Definition: defines.h:300
struct rt_wdb * wdb_dbopen(struct db_i *dbip, int mode)
Definition: wdb.c:64