BRL-CAD
nmg_copy.c
Go to the documentation of this file.
1 /* N M G _ C O P Y . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2011-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 /** @addtogroup nmg */
21 /** @{ */
22 /** @file primitives/nmg/nmg_copy.c
23  *
24  * Support routine for n-Manifold Geometry:
25  * Deep copy of NMG model structure
26  *
27  */
28 /** @} */
29 
30 #include "common.h"
31 
32 #include <string.h>
33 
34 #include "nurb.h"
35 #include "raytrace.h"
36 
37 
38 static struct nmgregion_a *
39 nmg_construct_region_a(const struct nmgregion_a *original, void **structArray)
40 {
41  struct nmgregion_a *ret;
42 
43  NMG_GETSTRUCT(ret, nmgregion_a);
44 
45  ret->magic = NMG_REGION_A_MAGIC;
46 
47  VMOVE(ret->min_pt, original->min_pt);
48  VMOVE(ret->max_pt, original->max_pt);
49 
50  ret->index = original->index;
51  structArray[ret->index] = ret;
52 
53  return ret;
54 }
55 
56 
57 static struct nmgregion *
58 nmg_construct_region(struct model *parent, const struct nmgregion *original, void **structArray)
59 {
60  struct nmgregion *ret;
61 
62  NMG_GETSTRUCT(ret, nmgregion);
63 
64  ret->l.magic = NMG_REGION_MAGIC;
65  ret->m_p = parent;
66  ret->ra_p = (struct nmgregion_a *)NULL;
67 
68  BU_LIST_INIT(&ret->s_hd);
69 
70  ret->index = original->index;
71  structArray[ret->index] = ret;
72 
73  if (original->ra_p != NULL) {
74  const struct nmgregion_a *originalAttributes = original->ra_p;
75  struct nmgregion_a *newAttributes
76  = (struct nmgregion_a *)structArray[originalAttributes->index];
77 
78  if (newAttributes == NULL)
79  newAttributes = nmg_construct_region_a(originalAttributes, structArray);
80 
81  ret->ra_p = newAttributes;
82  }
83 
84  return ret;
85 }
86 
87 
88 static struct face_g_plane *
89 nmg_construct_face_g_plane(const struct face_g_plane *original, void **structArray)
90 {
91  struct face_g_plane *ret;
92 
93  NMG_GETSTRUCT(ret, face_g_plane);
94 
95  ret->magic = NMG_FACE_G_PLANE_MAGIC;
96 
97  BU_LIST_INIT(&ret->f_hd);
98  HMOVE(ret->N, original->N);
99 
100  ret->index = original->index;
101  structArray[ret->index] = ret;
102 
103  return ret;
104 }
105 
106 
107 static struct face_g_snurb *
108 nmg_construct_face_g_snurb(const struct face_g_snurb *original, void **structArray)
109 {
110  struct face_g_snurb *ret;
111 
112  NMG_GETSTRUCT(ret, face_g_snurb);
113 
114  ret->l.magic = NMG_FACE_G_SNURB_MAGIC;
115 
116  BU_LIST_INIT(&ret->f_hd);
117 
118  ret->order[0] = original->order[0];
119  ret->order[1] = original->order[1];
120 
121  ret->u.magic = NMG_KNOT_VECTOR_MAGIC;
122  ret->u.k_size = original->u.k_size;
123  ret->u.knots = (fastf_t *)bu_malloc(ret->u.k_size * sizeof(fastf_t),
124  "nmg_construct_face_g_snurb(): u.knots");
125  memcpy(ret->u.knots, original->u.knots, ret->u.k_size * sizeof(fastf_t));
126  ret->v.magic = NMG_KNOT_VECTOR_MAGIC;
127  ret->v.k_size = original->v.k_size;
128  ret->v.knots = (fastf_t *)bu_malloc(ret->v.k_size * sizeof(fastf_t),
129  "nmg_construct_face_g_snurb(): v.knots");
130  memcpy(ret->v.knots, original->v.knots, ret->v.k_size * sizeof(fastf_t));
131 
132  ret->s_size[0] = original->s_size[0];
133  ret->s_size[1] = original->s_size[1];
134  ret->pt_type = original->pt_type;
135  ret->ctl_points
136  = (fastf_t *)bu_malloc(original->s_size[0] * original->s_size[1] * RT_NURB_EXTRACT_COORDS(ret->pt_type) * sizeof(fastf_t),
137  "nmg_construct_face_g_snurb(): ctl_points");
138  memcpy(ret->ctl_points, original->ctl_points, original->s_size[0] * original->s_size[1] * RT_NURB_EXTRACT_COORDS(ret->pt_type) * sizeof(fastf_t));
139 
140  ret->dir = original->dir;
141  VMOVE(ret->min_pt, original->min_pt);
142  VMOVE(ret->max_pt, original->max_pt);
143 
144  ret->index = original->index;
145  structArray[ret->index] = ret;
146 
147  return ret;
148 }
149 
150 
151 static struct face *
152 nmg_construct_face(struct faceuse *parent, const struct face *original, void **structArray)
153 {
154  struct face *ret;
155 
156  NMG_GETSTRUCT(ret, face);
157 
158  ret->l.magic = NMG_FACE_MAGIC;
159  ret->fu_p = parent;
160  ret->g.magic_p = (uint32_t *)NULL;
161  ret->flip = original->flip;
162 
163  VMOVE(ret->min_pt, original->min_pt);
164  VMOVE(ret->max_pt, original->max_pt);
165 
166  ret->index = original->index;
167  structArray[ret->index] = ret;
168 
169  switch (*original->g.magic_p) {
171  ret->g.plane_p = (struct face_g_plane *)structArray[original->g.plane_p->index];
172 
173  if (ret->g.plane_p == NULL)
174  ret->g.plane_p = nmg_construct_face_g_plane(original->g.plane_p, structArray);
175 
176  BU_LIST_INSERT(&ret->g.plane_p->f_hd, &ret->l);
177  break;
178 
180  ret->g.snurb_p = (struct face_g_snurb *)structArray[original->g.plane_p->index];
181 
182  if (ret->g.snurb_p == NULL)
183  ret->g.snurb_p = nmg_construct_face_g_snurb(original->g.snurb_p, structArray);
184 
185  BU_LIST_INSERT(&ret->g.snurb_p->f_hd, &ret->l);
186  }
187 
188  return ret;
189 }
190 
191 
192 static struct vertex_g *
193 nmg_construct_vertex_g(const struct vertex_g *original, void **structArray)
194 {
195  struct vertex_g *ret;
196 
197  NMG_GETSTRUCT(ret, vertex_g);
198 
199  ret->magic = NMG_VERTEX_G_MAGIC;
200 
201  VMOVE(ret->coord, original->coord);
202 
203  ret->index = original->index;
204  structArray[ret->index] = ret;
205 
206  return ret;
207 }
208 
209 
210 static struct vertex *
211 nmg_construct_vertex(const struct vertex *original, void **structArray)
212 {
213  struct vertex *ret;
214 
215  NMG_GETSTRUCT(ret, vertex);
216 
217  ret->magic = NMG_VERTEX_MAGIC;
218 
219  BU_LIST_INIT(&ret->vu_hd);
220 
221  ret->vg_p = (struct vertex_g*)NULL;
222  ret->index = original->index;
223  structArray[ret->index] = ret;
224 
225  if (original->vg_p != NULL) {
226  ret->vg_p = (struct vertex_g *)structArray[original->vg_p->index];
227 
228  if (ret->vg_p == NULL)
229  ret->vg_p = nmg_construct_vertex_g(original->vg_p, structArray);
230  }
231 
232  return ret;
233 }
234 
235 
236 static struct vertexuse_a_plane *
237 nmg_construct_vertexuse_a_plane(const struct vertexuse_a_plane *original, void **structArray)
238 {
239  struct vertexuse_a_plane *ret;
240 
241  NMG_GETSTRUCT(ret, vertexuse_a_plane);
242 
243  ret->magic = NMG_VERTEXUSE_A_PLANE_MAGIC;
244 
245  VMOVE(ret->N, original->N);
246 
247  ret->index = original->index;
248  structArray[ret->index] = ret;
249 
250  return ret;
251 }
252 
253 
254 static struct vertexuse_a_cnurb *
255 nmg_construct_vertexuse_a_cnurb(const struct vertexuse_a_cnurb *original, void **structArray)
256 {
257  struct vertexuse_a_cnurb *ret;
258 
259  NMG_GETSTRUCT(ret, vertexuse_a_cnurb);
260 
261  ret->magic = NMG_VERTEXUSE_A_CNURB_MAGIC;
262 
263  VMOVE(ret->param, original->param);
264 
265  ret->index = original->index;
266  structArray[ret->index] = ret;
267 
268  return ret;
269 }
270 
271 
272 static struct vertexuse *
273 nmg_construct_vertexuse(void *parent, const struct vertexuse *original, void **structArray)
274 {
275  struct vertexuse *ret;
276 
277  NMG_GETSTRUCT(ret, vertexuse);
278 
279  ret->l.magic = NMG_VERTEXUSE_MAGIC;
280  ret->up.magic_p = (uint32_t *)parent;
281  ret->v_p = (struct vertex*)NULL;
282  ret->a.magic_p = NULL;
283  ret->index = original->index;
284  structArray[ret->index] = ret;
285 
286  if (original->v_p != NULL) {
287  ret->v_p = (struct vertex *)structArray[original->v_p->index];
288 
289  if (ret->v_p == NULL)
290  ret->v_p = nmg_construct_vertex(original->v_p, structArray);
291 
292  BU_LIST_INSERT(&ret->v_p->vu_hd, &(ret->l));
293  }
294 
295  if (original->a.magic_p != NULL) {
296  switch (*original->a.magic_p) {
298  ret->a.plane_p = (struct vertexuse_a_plane *)structArray[original->a.plane_p->index];
299  if (ret->a.plane_p == NULL)
300  ret->a.plane_p = nmg_construct_vertexuse_a_plane(original->a.plane_p, structArray);
301  break;
303  ret->a.cnurb_p = (struct vertexuse_a_cnurb *)structArray[original->a.cnurb_p->index];
304  if (ret->a.cnurb_p == NULL)
305  ret->a.cnurb_p = nmg_construct_vertexuse_a_cnurb(original->a.cnurb_p, structArray);
306  break;
307  default:
308  /* FIXME: any more cases? any action to take? */
309  break;
310  }
311  }
312 
313  return ret;
314 }
315 
316 
317 static struct edge *
318 nmg_construct_edge(struct edgeuse *parent, const struct edge *original, void **structArray)
319 {
320  struct edge *ret;
321 
322  NMG_GETSTRUCT(ret, edge);
323 
324  ret->magic = NMG_EDGE_MAGIC;
325  ret->eu_p = parent;
326  ret->is_real = original->is_real;
327  ret->index = original->index;
328  structArray[ret->index] = ret;
329 
330  return ret;
331 }
332 
333 
334 static struct edge_g_lseg *
335 nmg_construct_edge_g_lseg(const struct edge_g_lseg *original, void **structArray)
336 {
337  struct edge_g_lseg *ret;
338 
339  NMG_GETSTRUCT(ret, edge_g_lseg);
340 
341  ret->l.magic = NMG_EDGE_G_LSEG_MAGIC;
342 
343  BU_LIST_INIT(&ret->eu_hd2);
344 
345  VMOVE(ret->e_pt, original->e_pt);
346  VMOVE(ret->e_dir, original->e_dir);
347 
348  ret->index = original->index;
349  structArray[ret->index] = ret;
350 
351  return ret;
352 }
353 
354 
355 static struct edge_g_cnurb *
356 nmg_construct_edge_g_cnurb(const struct edge_g_cnurb *original, void **structArray)
357 {
358  struct edge_g_cnurb *ret;
359 
360  NMG_GETSTRUCT(ret, edge_g_cnurb);
361 
362  ret->l.magic = NMG_EDGE_G_CNURB_MAGIC;
363 
364  BU_LIST_INIT(&ret->eu_hd2);
365 
366  ret->order = original->order;
367 
368  ret->k.magic = NMG_KNOT_VECTOR_MAGIC;
369  ret->k.k_size = original->k.k_size;
370  ret->k.knots = (fastf_t *)bu_malloc(ret->k.k_size * sizeof(fastf_t), "nmg_construct_edge_g_cnurb(): k.knots");
371  memcpy(ret->k.knots, original->k.knots, ret->k.k_size * sizeof(fastf_t));
372 
373  ret->c_size = original->c_size;
374  ret->pt_type = original->pt_type;
375  ret->ctl_points = (fastf_t *)bu_malloc(ret->c_size * RT_NURB_EXTRACT_COORDS(ret->pt_type) * sizeof(fastf_t),
376  "nmg_construct_edge_g_cnurb(): ctl_points");
377  memcpy(ret->ctl_points, original->ctl_points, ret->c_size * RT_NURB_EXTRACT_COORDS(ret->pt_type) * sizeof(fastf_t));
378 
379  ret->index = original->index;
380  structArray[ret->index] = ret;
381 
382  return ret;
383 }
384 
385 
386 static struct edgeuse *
387 nmg_construct_edgeuse(void *parent, const struct edgeuse *original, void **structArray)
388 {
389  struct edgeuse *ret;
390 
391  NMG_GETSTRUCT(ret, edgeuse);
392 
393  ret->l.magic = NMG_EDGEUSE_MAGIC;
394 
395  BU_LIST_INIT(&ret->l2);
396  ret->l2.magic = NMG_EDGEUSE2_MAGIC;
397 
398  ret->up.magic_p = (uint32_t *)parent;
399  ret->eumate_p = (struct edgeuse*)NULL;
400  ret->radial_p = (struct edgeuse*)NULL;
401  ret->e_p = (struct edge*)NULL;
402  ret->orientation = original->orientation;
403  ret->vu_p = (struct vertexuse*) NULL;
404  ret->g.magic_p = NULL;
405  ret->index = original->index;
406  structArray[ret->index] = ret;
407 
408  if (original->eumate_p != NULL) {
409  ret->eumate_p = (struct edgeuse *)structArray[original->eumate_p->index];
410 
411  /* because it's tricky to choose the right parent for the mate
412  * wait until it's created and set eumate_p afterwards
413  */
414  if (ret->eumate_p != NULL)
415  ret->eumate_p->eumate_p = ret;
416  }
417 
418  if (original->radial_p != NULL) {
419  ret->radial_p = (struct edgeuse *)structArray[original->radial_p->index];
420 
421  /* because it's tricky to choose the right parent wait until
422  * it's created and set it afterwards
423  */
424  if (ret->radial_p != NULL)
425  ret->radial_p->radial_p = ret;
426  }
427 
428  if (original->e_p != NULL) {
429  ret->e_p = (struct edge *)structArray[original->e_p->index];
430 
431  if (ret->e_p == 0)
432  ret->e_p = nmg_construct_edge(ret, original->e_p, structArray);
433  }
434 
435  if (original->vu_p != NULL) {
436  ret->vu_p = (struct vertexuse *)structArray[original->vu_p->index];
437 
438  if (ret->vu_p == 0)
439  ret->vu_p = nmg_construct_vertexuse(ret, original->vu_p, structArray);
440  }
441 
442  if (original->g.magic_p != NULL) {
443  switch (*original->g.magic_p) {
445  ret->g.lseg_p = (struct edge_g_lseg *)structArray[original->g.lseg_p->index];
446  if (ret->g.lseg_p == NULL)
447  ret->g.lseg_p = nmg_construct_edge_g_lseg(original->g.lseg_p, structArray);
448  BU_LIST_INSERT(&ret->g.lseg_p->eu_hd2, &(ret->l2));
449  break;
451  ret->g.cnurb_p = (struct edge_g_cnurb *)structArray[original->g.cnurb_p->index];
452  if (ret->g.cnurb_p == NULL)
453  ret->g.cnurb_p = nmg_construct_edge_g_cnurb(original->g.cnurb_p, structArray);
454  BU_LIST_INSERT(&ret->g.cnurb_p->eu_hd2, &(ret->l2));
455  break;
456  default:
457  /* FIXME: any more cases? any action to take? */
458  break;
459  }
460  }
461 
462  return ret;
463 }
464 
465 
466 static struct loop_g *
467 nmg_construct_loop_g(const struct loop_g *original, void **structArray)
468 {
469  struct loop_g *ret;
470 
471  NMG_GETSTRUCT(ret, loop_g);
472 
473  ret->magic = NMG_LOOP_G_MAGIC;
474 
475  VMOVE(ret->min_pt, original->min_pt);
476  VMOVE(ret->max_pt, original->max_pt);
477 
478  ret->index = original->index;
479  structArray[ret->index] = ret;
480 
481  return ret;
482 }
483 
484 
485 static struct loop *
486 nmg_construct_loop(struct loopuse *parent, const struct loop *original, void **structArray)
487 {
488  struct loop *ret;
489 
490  NMG_GETSTRUCT(ret, loop);
491 
492  ret->magic = NMG_LOOP_MAGIC;
493  ret->lu_p = parent;
494  ret->lg_p = (struct loop_g*)NULL;
495  ret->index = original->index;
496  structArray[ret->index] = ret;
497 
498  if (original->lg_p != NULL) {
499  ret->lg_p = (struct loop_g *)structArray[original->lg_p->index];
500 
501  if (ret->lg_p == NULL)
502  ret->lg_p = nmg_construct_loop_g(original->lg_p, structArray);
503  }
504 
505  return ret;
506 }
507 
508 
509 static struct loopuse *
510 nmg_construct_loopuse(void *parent, const struct loopuse *original, void **structArray)
511 {
512  struct loopuse *ret;
513 
514  NMG_GETSTRUCT(ret, loopuse);
515 
516  ret->l.magic = NMG_LOOPUSE_MAGIC;
517  ret->up.magic_p = (uint32_t *)parent;
518  ret->lumate_p = (struct loopuse *)NULL;
519  ret->orientation = original->orientation;
520  ret->l_p = (struct loop *)NULL;
521 
522  BU_LIST_INIT(&ret->down_hd);
523 
524  ret->index = original->index;
525  structArray[ret->index] = ret;
526 
527  if (original->lumate_p != NULL) {
528  ret->lumate_p = (struct loopuse *)structArray[original->lumate_p->index];
529 
530  /* because it's tricky to choose the right parent for the mate
531  * wait until it's created and set eumate_p afterwards
532  */
533  if (ret->lumate_p != NULL)
534  ret->lumate_p->lumate_p = ret;
535  }
536 
537  if (original->l_p != NULL) {
538  ret->l_p = (struct loop *)structArray[original->l_p->index];
539 
540  if (ret->l_p == 0)
541  ret->l_p = nmg_construct_loop(ret, original->l_p, structArray);
542  }
543 
544  switch (BU_LIST_FIRST_MAGIC(&original->down_hd)) {
545  case NMG_VERTEXUSE_MAGIC: {
546  const struct vertexuse *originalVertexUse = BU_LIST_FIRST(vertexuse, &original->down_hd);
547  struct vertexuse *newVertexUse = (struct vertexuse *)structArray[originalVertexUse->index];
548 
549  if (newVertexUse == NULL)
550  newVertexUse = nmg_construct_vertexuse(ret, originalVertexUse, structArray);
551 
552  BU_LIST_INSERT(&ret->down_hd, &newVertexUse->l);
553  }
554  break;
555  case NMG_EDGEUSE_MAGIC: {
556  const struct edgeuse *originalEdgeUse;
557  for (BU_LIST_FOR(originalEdgeUse, edgeuse, &original->down_hd)) {
558  struct edgeuse *newEdgeUse = (struct edgeuse *)structArray[originalEdgeUse->index];
559  if (newEdgeUse == NULL)
560  newEdgeUse = nmg_construct_edgeuse(ret, originalEdgeUse, structArray);
561  BU_LIST_INSERT(&ret->down_hd, &newEdgeUse->l);
562  }
563  }
564  break;
565  default:
566  /* FIXME: any more cases? any action to take? */
567  break;
568  }
569 
570  return ret;
571 }
572 
573 
574 static struct faceuse *
575 nmg_construct_faceuse(struct shell *parent, const struct faceuse *original, void **structArray)
576 {
577  struct faceuse *ret;
578  const struct loopuse *originalLoopUse;
579 
580  NMG_GETSTRUCT(ret, faceuse);
581 
582  ret->l.magic = NMG_FACEUSE_MAGIC;
583  ret->s_p = parent;
584  ret->fumate_p = (struct faceuse *)NULL;
585  ret->orientation = original->orientation;
586  ret->outside = original->outside;
587  ret->f_p = (struct face *)NULL;
588 
589  BU_LIST_INIT(&ret->lu_hd);
590 
591  ret->index = original->index;
592  structArray[ret->index] = ret;
593 
594  if (original->fumate_p != NULL) {
595  ret->fumate_p = (struct faceuse *)structArray[original->fumate_p->index];
596 
597  if (ret->fumate_p == NULL)
598  ret->fumate_p = nmg_construct_faceuse(parent, original->fumate_p, structArray);
599  }
600 
601  if (original->f_p != NULL) {
602  ret->f_p = (struct face *)structArray[original->f_p->index];
603 
604  if (ret->f_p == 0)
605  ret->f_p = nmg_construct_face(ret, original->f_p, structArray);
606  }
607 
608  for (BU_LIST_FOR(originalLoopUse, loopuse, &original->lu_hd)) {
609  struct loopuse *newLoopUse = (struct loopuse *)structArray[originalLoopUse->index];
610 
611  if (newLoopUse == NULL)
612  newLoopUse = nmg_construct_loopuse(ret, originalLoopUse, structArray);
613 
614  BU_LIST_INSERT(&ret->lu_hd, &newLoopUse->l);
615  }
616 
617  return ret;
618 }
619 
620 
621 static struct shell_a *
622 nmg_construct_shell_a(const struct shell_a *original, void **structArray)
623 {
624  struct shell_a *ret;
625 
626  NMG_GETSTRUCT(ret, shell_a);
627 
628  ret->magic = NMG_SHELL_A_MAGIC;
629 
630  VMOVE(ret->min_pt, original->min_pt);
631  VMOVE(ret->max_pt, original->max_pt);
632 
633  ret->index = original->index;
634  structArray[ret->index] = ret;
635 
636  return ret;
637 }
638 
639 
640 static struct shell *
641 nmg_construct_shell(struct nmgregion *parent, const struct shell *original, void **structArray)
642 {
643  struct shell *ret;
644  const struct faceuse *originalFaceUse;
645  const struct loopuse *originalLoopUse;
646  const struct edgeuse *originalEdgeUse;
647 
648  NMG_GETSTRUCT(ret, shell);
649 
650  ret->l.magic = NMG_SHELL_MAGIC;
651  ret->r_p = parent;
652  ret->sa_p = (struct shell_a *)NULL;
653 
654  BU_LIST_INIT(&ret->fu_hd);
655  BU_LIST_INIT(&ret->lu_hd);
656  BU_LIST_INIT(&ret->eu_hd);
657 
658  ret->vu_p = (struct vertexuse *) NULL;
659  ret->index = original->index;
660  structArray[ret->index] = ret;
661 
662  if (original->sa_p != NULL) {
663  const struct shell_a *originalAttributes = original->sa_p;
664  struct shell_a *newAttributes = (struct shell_a *)structArray[originalAttributes->index];
665 
666  if (newAttributes == NULL)
667  newAttributes = nmg_construct_shell_a(originalAttributes, structArray);
668 
669  ret->sa_p = newAttributes;
670  }
671 
672  for (BU_LIST_FOR(originalFaceUse, faceuse, &original->fu_hd)) {
673  struct faceuse *newFaceUse = (struct faceuse *)structArray[originalFaceUse->index];
674 
675  if (newFaceUse == NULL)
676  newFaceUse = nmg_construct_faceuse(ret, originalFaceUse, structArray);
677 
678  BU_LIST_INSERT(&ret->fu_hd, &newFaceUse->l);
679  }
680 
681  for (BU_LIST_FOR(originalLoopUse, loopuse, &original->lu_hd)) {
682  struct loopuse *newLoopUse = (struct loopuse *)structArray[originalLoopUse->index];
683 
684  if (newLoopUse == NULL)
685  newLoopUse = nmg_construct_loopuse(ret, originalLoopUse, structArray);
686 
687  BU_LIST_INSERT(&ret->lu_hd, &newLoopUse->l);
688  }
689 
690  for (BU_LIST_FOR(originalEdgeUse, edgeuse, &original->eu_hd)) {
691  struct edgeuse *newEdgeUse = (struct edgeuse *)structArray[originalEdgeUse->index];
692 
693  if (newEdgeUse == NULL)
694  newEdgeUse = nmg_construct_edgeuse(ret, originalEdgeUse, structArray);
695 
696  BU_LIST_INSERT(&ret->eu_hd, &newEdgeUse->l);
697  }
698 
699  if (original->vu_p != 0) {
700  ret->vu_p = (struct vertexuse *)structArray[original->vu_p->index];
701 
702  if (ret->vu_p == NULL)
703  ret->vu_p = nmg_construct_vertexuse(ret, original->vu_p, structArray);
704  }
705 
706  return ret;
707 }
708 
709 
710 /**
711  * Makes a deep copy of a NMG model structure.
712  */
713 struct model *
714 nmg_clone_model(const struct model *original)
715 {
716  struct model *ret;
717  void * *structArray;
718  const struct nmgregion *originalRegion;
719  struct bn_tol tolerance;
720 
721  NMG_CK_MODEL(original);
722 
723  structArray = (void **)bu_calloc(original->maxindex, sizeof(void *), "nmg_clone_model() structArray");
724 
725  ret = nmg_mm();
726  ret->index = original->index;
727  ret->maxindex = original->maxindex;
728 
729  structArray[ret->index] = ret;
730 
731  tolerance.magic = BN_TOL_MAGIC;
732  tolerance.dist = 0.0005;
733  tolerance.dist_sq = tolerance.dist * tolerance.dist;
734  tolerance.perp = 1e-6;
735  tolerance.para = 1 - tolerance.perp;
736 
737  for (BU_LIST_FOR(originalRegion, nmgregion, &original->r_hd)) {
738  struct nmgregion *newRegion = (struct nmgregion *)structArray[originalRegion->index];
739 
740  if (newRegion == NULL) {
741  const struct shell *originalShell;
742 
743  newRegion = nmg_construct_region(ret, originalRegion, structArray);
744 
745  for (BU_LIST_FOR(originalShell, shell, &originalRegion->s_hd)) {
746  struct shell *newShell = (struct shell *)structArray[originalShell->index];
747 
748  if (newShell == NULL)
749  newShell = nmg_construct_shell(newRegion, originalShell, structArray);
750 
751  BU_LIST_INSERT(&newRegion->s_hd, &newShell->l);
752  }
753 
754  BU_LIST_INSERT(&ret->r_hd, &newRegion->l);
755  }
756  }
757 
758  bu_free(structArray, "nmg_clone_model() structArray");
759 
760  return ret;
761 }
762 
763 
764 /*
765  * Local Variables:
766  * tab-width: 8
767  * mode: C
768  * indent-tabs-mode: t
769  * c-file-style: "stroustrup"
770  * End:
771  * ex: shiftwidth=4 tabstop=8
772  */
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
#define NMG_EDGEUSE_MAGIC
Definition: magic.h:120
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
#define NMG_EDGE_MAGIC
Definition: magic.h:123
#define NMG_SHELL_MAGIC
Definition: magic.h:142
#define NMG_LOOP_G_MAGIC
Definition: magic.h:131
double dist
>= 0
Definition: tol.h:73
#define NMG_VERTEX_MAGIC
Definition: magic.h:147
#define NMG_FACE_G_SNURB_MAGIC
Definition: magic.h:126
#define NMG_KNOT_VECTOR_MAGIC
Definition: magic.h:129
double dist_sq
dist * dist
Definition: tol.h:74
#define BN_TOL_MAGIC
Definition: magic.h:74
Header file for the BRL-CAD common definitions.
#define NMG_LOOPUSE_MAGIC
Definition: magic.h:130
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
if(share_geom)
Definition: nmg_mod.c:3829
#define NMG_EDGEUSE2_MAGIC
Definition: magic.h:119
#define NMG_LOOP_MAGIC
Definition: magic.h:132
#define NMG_FACE_MAGIC
Definition: magic.h:127
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
#define NMG_SHELL_A_MAGIC
Definition: magic.h:141
#define NMG_REGION_MAGIC
Definition: magic.h:137
Support for uniform tolerances.
Definition: tol.h:71
#define BU_LIST_FIRST_MAGIC(hp)
Definition: list.h:416
#define NMG_VERTEXUSE_MAGIC
Definition: magic.h:145
#define NMG_VERTEXUSE_A_CNURB_MAGIC
Definition: magic.h:143
#define NMG_FACE_G_PLANE_MAGIC
Definition: magic.h:125
struct model * nmg_mm(void)
Definition: nmg_mk.c:235
double perp
nearly 0
Definition: tol.h:75
#define NMG_EDGE_G_LSEG_MAGIC
Definition: magic.h:122
#define BU_LIST_INIT(_hp)
Definition: list.h:148
uint32_t magic
Definition: tol.h:72
#define NMG_EDGE_G_CNURB_MAGIC
Definition: magic.h:121
#define NMG_VERTEXUSE_A_PLANE_MAGIC
Definition: magic.h:144
#define NMG_REGION_A_MAGIC
Definition: magic.h:136
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define NMG_VERTEX_G_MAGIC
Definition: magic.h:146
#define NMG_FACEUSE_MAGIC
Definition: magic.h:124
struct model * nmg_clone_model(const struct model *original)
Definition: nmg_copy.c:714
double fastf_t
Definition: defines.h:300
double para
nearly 1
Definition: tol.h:76
#define BU_LIST_FIRST(structure, hp)
Definition: list.h:312