BRL-CAD
bspline.cpp
Go to the documentation of this file.
1 /* B S P L I N E . C P P
2  * BRL-CAD
3  *
4  * Copyright (c) 1991-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 primitives */
21 /** @{ */
22 /** @file bspline.cpp
23  *
24  * Intersect a ray with a Non Uniform Rational B-Spline.
25  *
26  */
27 /** @} */
28 
29 /* define to use new brep ray-tracing */
30 #define CONVERT_TO_BREP 1
31 
32 /* define to display old nurbs wireframe plot */
33 //#define OLD_WIREFRAME 1
34 
35 /* define to display new brep wireframe plot */
36 #define NEW_WIREFRAME 1
37 
38 #include "common.h"
39 
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <string.h>
43 #include <math.h>
44 #include "bnetwork.h"
45 
46 #include "bu/cv.h"
47 #include "vmath.h"
48 #include "db.h"
49 #include "rtgeom.h"
50 #include "raytrace.h"
51 #include "nurb.h" /* before nmg.h */
52 #include "nmg.h"
53 
54 #ifdef CONVERT_TO_BREP
55 # include "opennurbs.h"
56 #endif /* CONVERT_TO_BREP */
57 
58 #include "../../librt_private.h"
59 
60 
61 #ifdef __cplusplus
62 extern "C" {
63 #endif
64 
65 struct nurb_specific {
66  struct nurb_specific *next; /* next surface in the solid */
67  struct face_g_snurb *srf; /* Original surface description */
68  struct bu_list bez_hd; /* List of Bezier face_g_snurbs */
69 };
70 
71 struct nurb_hit {
72  struct nurb_hit *next;
73  struct nurb_hit *prev;
74  fastf_t hit_dist; /* Distance from the r_pt to surface */
75  point_t hit_point; /* intersection point */
76  vect_t hit_normal; /* Surface normal */
77  fastf_t hit_uv[2]; /* Surface parametric u, v */
78  int hit_surfno; /* index for the surface hit */
79  char *hit_private; /* Store current nurb root */
80 };
81 
82 #define NULL_HIT (struct nurb_hit *)0
83 
84 
85 #ifdef CONVERT_TO_BREP
86  extern void rt_nurb_brep(ON_Brep **b, struct rt_db_internal *ip, const struct bn_tol *tol);
87 
88  extern int rt_brep_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip);
89  extern void rt_brep_print(register const struct soltab *stp);
90  extern int rt_brep_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead);
91  extern void rt_brep_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp);
92  extern void rt_brep_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp);
93  extern void rt_brep_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp);
94  extern void rt_brep_free(register struct soltab *stp);
95  extern int rt_brep_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *UNUSED(info));
96 
97 #endif /* CONVERT_TO_BREP */
98 
99 
100 HIDDEN int
101 rt_nurb_grans(struct face_g_snurb *srf)
102 {
103  int total_knots, total_points;
104  int k_gran;
105  int p_gran;
106 
107  total_knots = srf->u.k_size + srf->v.k_size;
108  k_gran = ((total_knots * sizeof(dbfloat_t)) + sizeof(union record)-1)
109  / sizeof(union record);
110 
111  total_points = RT_NURB_EXTRACT_COORDS(srf->pt_type) *
112  (srf->s_size[0] * srf->s_size[1]);
113  p_gran = ((total_points * sizeof(dbfloat_t)) + sizeof(union record)-1)
114  / sizeof(union record);
115 
116  return 1 + k_gran + p_gran;
117 }
118 
119 /**
120  * Calculate the bounding RPP of a bspline
121  */
122 int
123 rt_nurb_bbox(struct rt_db_internal *ip, point_t *min, point_t *max) {
124  int i;
125  struct nurb_specific *nurbs = NULL;
126  struct nurb_specific *next;
127  struct rt_nurb_internal *sip;
128 
129  sip = (struct rt_nurb_internal *) ip->idb_ptr;
130  VSETALL((*min), INFINITY);
131  VSETALL((*max), -INFINITY);
132 
133  for (i = 0; i < sip->nsrf; i++) {
134  struct face_g_snurb * s;
135  struct nurb_specific * n;
136 
137  BU_GET(n, struct nurb_specific);
138 
139  /* Store off the original face_g_snurb */
140  s = rt_nurb_scopy(sip->srfs[i], (struct resource *)NULL);
141  NMG_CK_SNURB(s);
142  rt_nurb_s_bound(s, s->min_pt, s->max_pt);
143 
144  n->srf = s;
145  BU_LIST_INIT(&n->bez_hd);
146 
147  /* Grind up the original surf into a list of Bezier face_g_snurbs */
148  (void)rt_nurb_bezier(&n->bez_hd, sip->srfs[i], (struct resource *)NULL);
149 
150  /* Compute bounds of each Bezier face_g_snurb */
151  for (BU_LIST_FOR(s, face_g_snurb, &n->bez_hd)) {
152  NMG_CK_SNURB(s);
153  rt_nurb_s_bound(s, s->min_pt, s->max_pt);
154  VMINMAX((*min), (*max), s->min_pt);
155  VMINMAX((*min), (*max), s->max_pt);
156  }
157 
158  n->next = nurbs;
159  nurbs = n;
160  }
161  /* zero thickness will get missed by the raytracer */
162  if (NEAR_EQUAL((*min)[X], (*max)[X], SMALL_FASTF)) {
163  (*min)[X] -= SMALL_FASTF;
164  (*max)[X] += SMALL_FASTF;
165  }
166  if (NEAR_EQUAL((*min)[Y], (*max)[Y], SMALL_FASTF)) {
167  (*min)[Y] -= SMALL_FASTF;
168  (*max)[Y] += SMALL_FASTF;
169  }
170  if (NEAR_EQUAL((*min)[Z], (*max)[Z], SMALL_FASTF)) {
171  (*min)[Z] -= SMALL_FASTF;
172  (*max)[Z] += SMALL_FASTF;
173  }
174 
175  for (; nurbs != (struct nurb_specific *)0; nurbs = next) {
176  register struct face_g_snurb *s;
177 
178  next = nurbs->next;
179 
180  /* There is a linked list of surfaces to free for each nurb */
181  while (BU_LIST_WHILE (s, face_g_snurb, &nurbs->bez_hd)) {
182  NMG_CK_SNURB(s);
183  BU_LIST_DEQUEUE(&(s->l));
184  rt_nurb_free_snurb(s, (struct resource *)NULL);
185  }
186  rt_nurb_free_snurb(nurbs->srf, (struct resource *)NULL); /* original surf */
187  BU_PUT(nurbs, struct nurb_specific);
188  }
189 
190  return 0;
191 }
192 
193 
194 /**
195  * Given a pointer of a GED database record, and a transformation
196  * matrix, determine if this is a valid NURB, and if so, prepare the
197  * surface so the intersections will work.
198  */
199 int
200 rt_nurb_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
201 {
202 #ifndef CONVERT_TO_BREP
203  struct nurb_specific *nurbs = NULL;
204 #endif
205 
206  struct rt_nurb_internal *sip;
207  const struct bn_tol *tol = &rtip->rti_tol;
208  fastf_t los = tol->dist;
209 
210  if (los < SMALL_FASTF)
211  los = SMALL_FASTF;
212 
213  sip = (struct rt_nurb_internal *) ip->idb_ptr;
214  RT_NURB_CK_MAGIC(sip);
215 
216 #ifdef CONVERT_TO_BREP
217  ON_Brep *brep = ON_Brep::New();
218  rt_nurb_brep(&brep, ip, tol);
219  sip->brep = brep;
220 
221  struct rt_brep_internal bi;
222  bi.magic = RT_BREP_INTERNAL_MAGIC;
223  bi.brep = brep;
224 
225  struct rt_db_internal di;
226  RT_DB_INTERNAL_INIT(&di);
227  di.idb_ptr = (void *)&bi;
228 
229  return rt_brep_prep(stp, &di, rtip);
230 #else
231 
232  for (i = 0; i < sip->nsrf; i++) {
233  struct face_g_snurb * s;
234  struct nurb_specific * n;
235 
236  BU_GET(n, struct nurb_specific);
237 
238  /* Store off the original face_g_snurb */
239  s = rt_nurb_scopy(sip->srfs[i], (struct resource *)NULL);
240  NMG_CK_SNURB(s);
241  rt_nurb_s_bound(s, s->min_pt, s->max_pt);
242 
243  n->srf = s;
244  BU_LIST_INIT(&n->bez_hd);
245 
246  /* Grind up the original surf into a list of Bezier face_g_snurbs */
247  (void)rt_nurb_bezier(&n->bez_hd, sip->srfs[i], (struct resource *)NULL);
248 
249  /* Compute bounds of each Bezier face_g_snurb */
250  for (BU_LIST_FOR(s, face_g_snurb, &n->bez_hd)) {
251  NMG_CK_SNURB(s);
252  rt_nurb_s_bound(s, s->min_pt, s->max_pt);
253  VMINMAX(stp->st_min, stp->st_max, s->min_pt);
254  VMINMAX(stp->st_min, stp->st_max, s->max_pt);
255  }
256 
257  n->next = nurbs;
258  nurbs = n;
259  }
260 
261  stp->st_specific = (void *)nurbs;
262 
263  /* zero thickness will get missed by the raytracer */
264  if (NEAR_EQUAL(stp->st_min[X], stp->st_max[X], los)) {
265  stp->st_min[X] -= los;
266  stp->st_max[X] += los;
267  }
268  if (NEAR_EQUAL(stp->st_min[Y], stp->st_max[Y], los)) {
269  stp->st_min[Y] -= los;
270  stp->st_max[Y] += los;
271  }
272  if (NEAR_EQUAL(stp->st_min[Z], stp->st_max[Z], los)) {
273  stp->st_min[Z] -= los;
274  stp->st_max[Z] += los;
275  }
276 
277  VADD2SCALE(stp->st_center, stp->st_max, stp->st_min, 0.5);
278  {
279  fastf_t f, dx, dy, dz;
280  dx = (stp->st_max[0] - stp->st_min[0])/2;
281  f = dx;
282  dy = (stp->st_max[1] - stp->st_min[1])/2;
283  if (dy > f) f = dy;
284  dz = (stp->st_max[2] - stp->st_min[2])/2;
285  if (dz > f) f = dz;
286  stp->st_aradius = f;
287  stp->st_bradius = sqrt(dx*dx + dy*dy + dz*dz);
288  }
289 
290  return 0;
291 #endif /* CONVERT_TO_BREP */
292 }
293 
294 
295 void
296 rt_nurb_print(register const struct soltab *stp)
297 {
298 #ifdef CONVERT_TO_BREP
299  return rt_brep_print(stp);
300 #else
301  register struct nurb_specific *nurb =
302  (struct nurb_specific *)stp->st_specific;
303 
304  if (nurb == (struct nurb_specific *)0) {
305  bu_log("rt_nurb_print: no surfaces\n");
306  return;
307  }
308 
309  for (; nurb != (struct nurb_specific *)0; nurb = nurb->next) {
310  /* XXX There is a linked list of Bezier surfaces to print here too */
311  rt_nurb_s_print("NURB", nurb->srf);
312  }
313 #endif /* CONVERT_TO_BREP */
314 }
315 
316 
317 /**
318  * Intersect a ray with a nurb. If an intersection occurs, a struct
319  * seg will be acquired and filled in.
320  *
321  * Returns -
322  * 0 MISS
323  * >0 HIT
324  */
325 int
326 rt_nurb_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
327 {
328 #ifdef CONVERT_TO_BREP
329  return rt_brep_shot(stp, rp, ap, seghead);
330 #else
331  register struct nurb_specific *nurb =
332  (struct nurb_specific *)stp->st_specific;
333  register struct seg *segp;
334  const struct bn_tol *tol = &ap->a_rt_i->rti_tol;
335  point_t p1, p2, p3, p4;
336  vect_t dir1, dir2;
337  plane_t plane1, plane2;
338  struct nurb_hit * hit;
339  struct nurb_hit hit_list;
340  vect_t invdir;
341  int hit_num;
342  int surface = 0;
343 
344  invdir[0] = invdir[1] = invdir[2] = INFINITY;
345  if (!ZERO(rp->r_dir[0]))
346  invdir[0] = 1.0 / rp->r_dir[0];
347  if (!ZERO(rp->r_dir[1]))
348  invdir[1] = 1.0 / rp->r_dir[1];
349  if (!ZERO(rp->r_dir[2]))
350  invdir[2] = 1.0 / rp->r_dir[2];
351 
352  /* Create two orthogonal Planes their intersection contains the
353  * ray so we can project the surface into a 2 dimensional problem
354  */
355 
356  bn_vec_ortho(dir1, rp->r_dir);
357  VCROSS(dir2, rp->r_dir, dir1);
358 
359  VMOVE(p1, rp->r_pt);
360  VADD2(p2, rp->r_pt, rp->r_dir);
361  VADD2(p3, rp->r_pt, dir1);
362  VADD2(p4, rp->r_pt, dir2);
363 
364  /* Note: the equation of the plane in BRL-CAD is
365  * Ax + By + Cz = D represented by [A B C D]
366  */
367  bn_mk_plane_3pts(plane1, p1, p3, p2, tol);
368  bn_mk_plane_3pts(plane2, p1, p2, p4, tol);
369 
370  /* make sure that the hit_list is zero */
371 
372  hit_list.next = (struct nurb_hit *)0;
373  hit_list.prev = (struct nurb_hit *)0;
374  hit_list.hit_dist = 0;
375  VSET(hit_list.hit_point, 0.0, 0.0, 0.0);
376  VSET(hit_list.hit_normal, 0.0, 0.0, 0.0);
377  hit_list.hit_uv[0] = hit_list.hit_uv[1] = 0.0;
378  hit_list.hit_surfno = -1;
379  hit_list.hit_private = (char *)0;
380 
381  while (nurb != (struct nurb_specific *) 0) {
382  struct face_g_snurb * s;
383  struct rt_nurb_uv_hit *hp;
384 
385  for (BU_LIST_FOR (s, face_g_snurb, &nurb->bez_hd)) {
386  if (!rt_in_rpp(rp, invdir, s->min_pt, s->max_pt))
387  continue;
388 
389 #define UV_TOL 1.0e-6 /* Paper says 1.0e-4 is reasonable for 1k images, not close up */
390  hp = rt_nurb_intersect(
391  s, plane1, plane2, UV_TOL, (struct resource *)ap->a_resource, NULL);
392  while (hp != (struct rt_nurb_uv_hit *)0) {
393  struct rt_nurb_uv_hit * o;
394 
395  if (RT_G_DEBUG & DEBUG_SPLINE)
396  bu_log("hit at %d %d sub = %d u = %f v = %f\n",
397  ap->a_x, ap->a_y, hp->sub, hp->u, hp->v);
398 
399  hit = (struct nurb_hit *)
400  rt_conv_uv(nurb, rp, hp);
401  hit->hit_surfno = surface;
402 
403  o = hp;
404  hp = hp->next;
405  bu_free((char *)o,
406  "rt_nurb_shot:rt_nurb_uv_hit structure");
407 
408  rt_nurb_add_hit(&hit_list, hit, tol);
409  }
410 
411  /* surfaces are incrementally numbered based on the
412  * face_g_snurb list for all nurbs in this nurb_specific.
413  */
414  surface++;
415  }
416  nurb = nurb->next;
417  /* Insert Trimming routines here */
418  }
419 
420  /* Convert hits to segments for rt */
421 
422  hit_num = 0;
423 
424  while (hit_list.next != NULL_HIT) {
425  struct nurb_hit * h1, * h2;
426 
427  RT_GET_SEG(segp, ap->a_resource);
428 
429  h1 = (struct nurb_hit *) rt_return_nurb_hit(&hit_list);
430  h2 = (struct nurb_hit *) rt_return_nurb_hit(&hit_list);
431 
432  segp->seg_stp = stp;
433  segp->seg_in.hit_dist = h1->hit_dist;
434  VMOVE(segp->seg_in.hit_point, h1->hit_point);
435  segp->seg_in.hit_vpriv[0] = h1->hit_uv[0];
436  segp->seg_in.hit_vpriv[1] = h1->hit_uv[1];
437  segp->seg_in.hit_vpriv[2] = 0;
438  segp->seg_in.hit_private = h1->hit_private;
439  segp->seg_in.hit_surfno = h1->hit_surfno;
440  hit_num++;
441 
442  if (h2 != NULL_HIT) {
443  segp->seg_out.hit_dist = h2->hit_dist;
444  VMOVE(segp->seg_out.hit_point, h2->hit_point);
445  segp->seg_out.hit_vpriv[0] = h2->hit_uv[0];
446  segp->seg_out.hit_vpriv[1] = h2->hit_uv[1];
447  segp->seg_out.hit_private = h2->hit_private;
448  bu_free((char *)h2, "rt_nurb_shot: nurb hit");
449  hit_num++;
450  } else {
451  segp->seg_out.hit_dist = h1->hit_dist + .01;
452  VJOIN1(segp->seg_out.hit_point,
453  rp->r_pt, segp->seg_out.hit_dist, rp->r_dir);
454  segp->seg_out.hit_vpriv[0] = h1->hit_uv[0];
455  segp->seg_out.hit_vpriv[1] = h1->hit_uv[1];
456  segp->seg_out.hit_vpriv[2] = 1;
457  segp->seg_out.hit_private = h1->hit_private;
458  }
459 
460  bu_free((char *)h1, "rt_nurb_shot:nurb hit");
461 
462  BU_LIST_INSERT(&(seghead->l), &(segp->l));
463  }
464 
465  return hit_num; /* not hit */
466 #endif /* CONVERT_TO_BREP */
467 }
468 
469 
470 #define SEG_MISS(SEG) (SEG).seg_stp=(struct soltab *) 0;
471 
472 
473 /**
474  * Given ONE ray distance, return the normal and entry/exit point.
475  */
476 void
477 rt_nurb_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
478 {
479 #ifdef CONVERT_TO_BREP
480  return rt_brep_norm(hitp, stp, rp);
481 #else
482 /* register struct nurb_specific *nurb =
483  (struct nurb_specific *)stp->st_specific; */
484 
485  struct face_g_snurb *n = (struct face_g_snurb *) hitp->hit_private;
486  fastf_t u = hitp->hit_vpriv[0];
487  fastf_t v = hitp->hit_vpriv[1];
488  fastf_t norm[4];
489 
490  rt_nurb_s_norm(n, u, v, norm);
491 
492  VMOVE(hitp->hit_normal, norm);
493 
494  if (hitp->hit_vpriv[2] == 1) {
495  VREVERSE(hitp->hit_normal, norm);
496  }
497 
498  return;
499 #endif /* CONVERT_TO_BREP */
500 }
501 
502 
503 /**
504  * Return the curvature of the nurb.
505  */
506 void
507 rt_nurb_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
508 {
509 #ifdef CONVERT_TO_BREP
510  return rt_brep_curve(cvp, hitp, stp);
511 #else
512 /* register struct nurb_specific *nurb =
513  (struct nurb_specific *)stp->st_specific; */
514  struct face_g_snurb *srf = (struct face_g_snurb *) hitp->hit_private;
515  fastf_t u, v;
516 
517  if (srf->order[0] <= 2 && srf->order[1] <= 2) {
518  cvp->crv_c1 = cvp->crv_c2 = 0;
519 
520  /* any tangent direction */
521  bn_vec_ortho(cvp->crv_pdir, hitp->hit_normal);
522  return;
523  }
524 
525  u = hitp->hit_vpriv[0];
526  v = hitp->hit_vpriv[1];
527 
528  rt_nurb_curvature(cvp, srf, u, v);
529 #endif /* CONVERT_TO_BREP */
530 }
531 
532 
533 /**
534  * For a hit on the surface of an nurb, return the (u, v) coordinates
535  * of the hit point, 0 <= u, v <= 1.
536  * u = azimuth
537  * v = elevation
538  */
539 void
540 rt_nurb_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
541 {
542 #ifdef CONVERT_TO_BREP
543  return rt_brep_uv(ap, stp, hitp, uvp);
544 #else
545 /* register struct nurb_specific *nurb =
546  (struct nurb_specific *)stp->st_specific; */
547  uvp->uv_u = hitp->hit_vpriv[0];
548  uvp->uv_v = hitp->hit_vpriv[1];
549  return;
550 #endif /* CONVERT_TO_BREP */
551 }
552 
553 
554 void
555 rt_nurb_free(register struct soltab *stp)
556 {
557 #ifdef CONVERT_TO_BREP
558  return rt_brep_free(stp);
559 #else
560 
561  register struct nurb_specific *nurb =
562  (struct nurb_specific *)stp->st_specific;
563  register struct nurb_specific *next;
564 
565  if (nurb == (struct nurb_specific *)0)
566  bu_bomb("rt_nurb_free: no surfaces\n");
567 
568  for (; nurb != (struct nurb_specific *)0; nurb = next) {
569  register struct face_g_snurb *s;
570 
571  next = nurb->next;
572 
573  /* There is a linked list of surfaces to free for each nurb */
574  while (BU_LIST_WHILE (s, face_g_snurb, &nurb->bez_hd)) {
575  NMG_CK_SNURB(s);
576  BU_LIST_DEQUEUE(&(s->l));
577  rt_nurb_free_snurb(s, (struct resource *)NULL);
578  }
579  rt_nurb_free_snurb(nurb->srf, (struct resource *)NULL); /* original surf */
580  BU_PUT(nurb, struct nurb_specific);
581  }
582  return;
583 #endif /* CONVERT_TO_BREP */
584 }
585 
586 
587 int
589 {
590  return 0;
591 }
592 
593 
594 int
595 rt_nurb_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *UNUSED(info))
596 {
597  struct rt_nurb_internal *sip;
598 
599  BU_CK_LIST_HEAD(vhead);
600  RT_CK_DB_INTERNAL(ip);
601  sip = (struct rt_nurb_internal *) ip->idb_ptr;
602  RT_NURB_CK_MAGIC(sip);
603 
604 #ifdef OLD_WIREFRAME
605  for (s=0; s < sip->nsrf; s++) {
606  struct face_g_snurb * n, *r, *c;
607  int coords;
608  fastf_t bound;
609  point_t tmp_pt;
610  fastf_t dtol;
611  struct knot_vector tkv1,
612  tkv2;
613  fastf_t tess;
614  int num_knots;
615  int refined_col = 0;
616  int refined_row = 0;
617  fastf_t rt_nurb_par_edge(const struct face_g_snurb *srf, fastf_t epsilon);
618 
619  n = (struct face_g_snurb *) sip->srfs[s];
620 
621  VSUB2(tmp_pt, n->min_pt, n->max_pt);
622  bound = MAGNITUDE(tmp_pt)/ 2.0;
623 
624  dtol = primitive_get_absolute_tolerance(ttol, 2.0 * bound);
625 
626  if (n->order[0] < 3 || n->order[1] < 3) {
627  /* cannot use rt_nurb_par_edge() in this case */
628  tess = 0.25; /* hack for now */
629  } else
630  tess = (fastf_t) rt_nurb_par_edge(n, dtol);
631 
632  num_knots = (int)floor(1.0/((M_SQRT1_2 / 2.0) * tess));
633 
634  if (num_knots < 2) num_knots = 2;
635 
636  rt_nurb_kvknot(&tkv1, n->order[0],
637  n->u.knots[0],
638  n->u.knots[n->u.k_size-1], num_knots, (struct resource *)NULL);
639 
640  rt_nurb_kvknot(&tkv2, n->order[1],
641  n->v.knots[0],
642  n->v.knots[n->v.k_size-1], num_knots, (struct resource *)NULL);
643 
644 
645  if (tkv2.k_size > n->v.k_size) {
646  r = (struct face_g_snurb *) rt_nurb_s_refine(n, RT_NURB_SPLIT_COL, &tkv2, (struct resource *)NULL);
647  refined_col = 1;
648  } else {
649  r = n;
650  }
651  if (tkv1.k_size > r->u.k_size) {
652  c = (struct face_g_snurb *) rt_nurb_s_refine(r, RT_NURB_SPLIT_ROW, &tkv1, (struct resource *)NULL);
653  refined_row = 1;
654  } else {
655  c = r;
656  }
657 
658  coords = RT_NURB_EXTRACT_COORDS(n->pt_type);
659 
660  if (RT_NURB_IS_PT_RATIONAL(n->pt_type)) {
661  vp = c->ctl_points;
662  for (i= 0; i < c->s_size[0] * c->s_size[1]; i++) {
663  vp[0] /= vp[3];
664  vp[1] /= vp[3];
665  vp[2] /= vp[3];
666  vp[3] /= vp[3];
667  vp += coords;
668  }
669  }
670 
671 
672  vp = c->ctl_points;
673  for (i = 0; i < c->s_size[0]; i++) {
674  RT_ADD_VLIST(vhead, vp, BN_VLIST_LINE_MOVE);
675  vp += coords;
676  for (j = 1; j < c->s_size[1]; j++) {
677  RT_ADD_VLIST(vhead, vp, BN_VLIST_LINE_DRAW);
678  vp += coords;
679  }
680  }
681 
682  for (j = 0; j < c->s_size[1]; j++) {
683  int stride;
684 
685  stride = c->s_size[1] * coords;
686  vp = &c->ctl_points[j * coords];
687  RT_ADD_VLIST(vhead, vp, BN_VLIST_LINE_MOVE);
688  for (i = 0; i < c->s_size[0]; i++) {
689  RT_ADD_VLIST(vhead, vp, BN_VLIST_LINE_DRAW);
690  vp += stride;
691  }
692  }
693  if (refined_col) {
694  rt_nurb_free_snurb(r, (struct resource *)NULL);
695  }
696  if (refined_row) {
697  rt_nurb_free_snurb(c, (struct resource *)NULL);
698  }
699  bu_free((char *) tkv1.knots, "rt_nurb_plot:tkv1>knots");
700  bu_free((char *) tkv2.knots, "rt_nurb_plot:tkv2.knots");
701  }
702 #endif
703 
704 #ifdef NEW_WIREFRAME
705  ON_Brep *brep = ON_Brep::New();
706  rt_nurb_brep(&brep, ip, tol);
707 
708  struct rt_brep_internal bi;
709  bi.magic = RT_BREP_INTERNAL_MAGIC;
710  bi.brep = brep;
711 
712  struct rt_db_internal di;
713  RT_DB_INTERNAL_INIT(&di);
714  di.idb_ptr = (void *)&bi;
715 
716  return rt_brep_plot(vhead, &di, ttol, tol, NULL);
717 #else
718  return 0;
719 #endif /* CONVERT_TO_BREP */
720 }
721 
722 
723 int
724 rt_nurb_tess(struct nmgregion **, struct model *, struct rt_db_internal *, const struct rt_tess_tol *, const struct bn_tol *)
725 {
726  return -1;
727 }
728 
729 
730 int
731 rt_nurb_import4(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
732 {
733  struct rt_nurb_internal *sip;
734  union record *rp;
735  register int i;
736  int s;
737 
738  if (dbip) RT_CK_DBI(dbip);
739 
740  BU_CK_EXTERNAL(ep);
741  rp = (union record *)ep->ext_buf;
742  if (rp->u_id != ID_BSOLID) {
743  bu_log("rt_nurb_import4: defective header record");
744  return -1;
745  }
746 
747  RT_CK_DB_INTERNAL(ip);
748  ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
749  ip->idb_type = ID_BSPLINE;
750  ip->idb_meth = &OBJ[ID_BSPLINE];
751  BU_ALLOC(ip->idb_ptr, struct rt_nurb_internal);
752 
753  sip = (struct rt_nurb_internal *)ip->idb_ptr;
754  sip->magic = RT_NURB_INTERNAL_MAGIC;
755 
756  if (dbip->dbi_version < 0) {
757  sip->nsrf = flip_short(rp->B.B_nsurf);
758  } else {
759  sip->nsrf = rp->B.B_nsurf;
760  }
761 
762  sip->srfs = (struct face_g_snurb **) bu_malloc(sip->nsrf * sizeof(struct face_g_snurb), "nurb srfs[]");
763  rp++;
764 
765  for (s = 0; s < sip->nsrf; s++) {
766  register fastf_t * m;
767  int coords;
768  register dbfloat_t *vp;
769  int pt_type;
770  union record d;
771 
772  if (rp->d.d_id != ID_BSURF) {
773  bu_log("rt_nurb_import4() surf %d bad ID\n", s);
774  return -1;
775  }
776 
777  if (rp->d.d_geom_type == 3)
778  pt_type = RT_NURB_MAKE_PT_TYPE(3, RT_NURB_PT_XYZ, RT_NURB_PT_NONRAT);
779  else
780  pt_type = RT_NURB_MAKE_PT_TYPE(4, RT_NURB_PT_XYZ, RT_NURB_PT_RATIONAL);
781 
782  /* fix endianness */
783  d.d.d_id = rp->d.d_id;
784  if (dbip->dbi_version < 0) {
785  d.d.d_order[0] = flip_short(rp->d.d_order[0]);
786  d.d.d_order[1] = flip_short(rp->d.d_order[1]);
787  d.d.d_kv_size[0] = flip_short(rp->d.d_kv_size[0]);
788  d.d.d_kv_size[1] = flip_short(rp->d.d_kv_size[1]);
789  d.d.d_ctl_size[0] = flip_short(rp->d.d_ctl_size[0]);
790  d.d.d_ctl_size[1] = flip_short(rp->d.d_ctl_size[1]);
791  d.d.d_geom_type = flip_short(rp->d.d_geom_type);
792  d.d.d_nknots = flip_short(rp->d.d_nknots);
793  d.d.d_nctls = flip_short(rp->d.d_nctls);
794  } else {
795  d.d.d_order[0] = rp->d.d_order[0];
796  d.d.d_order[1] = rp->d.d_order[1];
797  d.d.d_kv_size[0] = rp->d.d_kv_size[0];
798  d.d.d_kv_size[1] = rp->d.d_kv_size[1];
799  d.d.d_ctl_size[0] = rp->d.d_ctl_size[0];
800  d.d.d_ctl_size[1] = rp->d.d_ctl_size[1];
801  d.d.d_geom_type = rp->d.d_geom_type;
802  d.d.d_nknots = rp->d.d_nknots;
803  d.d.d_nctls = rp->d.d_nctls;
804  }
805 
806  sip->srfs[s] = (struct face_g_snurb *) rt_nurb_new_snurb(
807  d.d.d_order[0], d.d.d_order[1],
808  d.d.d_kv_size[0], d.d.d_kv_size[1],
809  d.d.d_ctl_size[0], d.d.d_ctl_size[1],
810  pt_type, (struct resource *)NULL);
811 
812  vp = (dbfloat_t *) &rp[1];
813 
814  if (dbip->dbi_version < 0) {
815  for (i = 0; i < d.d.d_kv_size[0]; i++) {
816  sip->srfs[s]->u.knots[i] = flip_dbfloat(*vp++);
817  }
818  for (i = 0; i < d.d.d_kv_size[1]; i++) {
819  sip->srfs[s]->v.knots[i] = flip_dbfloat(*vp++);
820  }
821  } else {
822  for (i = 0; i < d.d.d_kv_size[0]; i++) {
823  sip->srfs[s]->u.knots[i] = (fastf_t) *vp++;
824  }
825  for (i = 0; i < d.d.d_kv_size[1]; i++) {
826  sip->srfs[s]->v.knots[i] = (fastf_t) *vp++;
827  }
828  }
829 
830  rt_nurb_kvnorm(&sip->srfs[s]->u);
831  rt_nurb_kvnorm(&sip->srfs[s]->v);
832 
833  vp = (dbfloat_t *) &rp[d.d.d_nknots+1];
834  m = sip->srfs[s]->ctl_points;
835  coords = d.d.d_geom_type;
836  i = (d.d.d_ctl_size[0] * d.d.d_ctl_size[1]);
837 
838  if (mat == NULL)
839  mat = bn_mat_identity;
840 
841  if (coords == 3) {
842  for (; i> 0; i--) {
843  vect_t f;
844 
845  if (dbip->dbi_version < 0) {
846  f[0] = flip_dbfloat(vp[0]);
847  f[1] = flip_dbfloat(vp[1]);
848  f[2] = flip_dbfloat(vp[2]);
849  } else {
850  VMOVE(f, vp);
851  }
852 
853  MAT4X3PNT(m, mat, f);
854  m += 3;
855  vp += 3;
856  }
857  } else if (coords == 4) {
858  for (; i> 0; i--) {
859  hvect_t f;
860 
861  if (dbip->dbi_version < 0) {
862  f[0] = flip_dbfloat(vp[0]);
863  f[1] = flip_dbfloat(vp[1]);
864  f[2] = flip_dbfloat(vp[2]);
865  f[3] = flip_dbfloat(vp[3]);
866  } else {
867  HMOVE(f, vp);
868  }
869 
870  MAT4X4PNT(m, mat, f);
871  m += 4;
872  vp += 4;
873  }
874  } else {
875  bu_log("rt_nurb_internal: %d invalid elements per vect\n", d.d.d_geom_type);
876  return -1;
877  }
878 
879  /* bound the surface for tolerancing and other bounding box tests */
880  rt_nurb_s_bound(sip->srfs[s], sip->srfs[s]->min_pt,
881  sip->srfs[s]->max_pt);
882 
883  rp += 1 + d.d.d_nknots + d.d.d_nctls;
884  }
885  return 0;
886 }
887 
888 
889 int
890 rt_nurb_export4(struct bu_external *ep, const struct rt_db_internal *ip, double UNUSED(local2mm), const struct db_i *dbip)
891 {
892  register int rec_ptr;
893  struct rt_nurb_internal *sip;
894  union record *rec;
895  int s;
896  int grans;
897  int total_grans;
898  dbfloat_t *vp;
899  int n;
900 
901  if (dbip) RT_CK_DBI(dbip);
902 
903  RT_CK_DB_INTERNAL(ip);
904  if (ip->idb_type != ID_BSPLINE) return -1;
905  sip = (struct rt_nurb_internal *) ip->idb_ptr;
906  RT_NURB_CK_MAGIC(sip);
907 
908  /* Figure out how many recs to buffer by
909  * walking through the surfaces and
910  * calculating the number of granules
911  * needed for storage and add it to the total
912  */
913  total_grans = 1; /* First gran for BSOLID record */
914  for (s = 0; s < sip->nsrf; s++) {
915  total_grans += rt_nurb_grans(sip->srfs[s]);
916  }
917 
918  BU_CK_EXTERNAL(ep);
919  ep->ext_nbytes = total_grans * sizeof(union record);
920  ep->ext_buf = (uint8_t *)bu_calloc(1, ep->ext_nbytes, "nurb external");
921  rec = (union record *)ep->ext_buf;
922 
923  rec[0].B.B_id = ID_BSOLID;
924  rec[0].B.B_nsurf = sip->nsrf;
925 
926  rec_ptr = 1;
927 
928  for (s = 0; s < sip->nsrf; s++) {
929  register struct face_g_snurb *srf = sip->srfs[s];
930  NMG_CK_SNURB(srf);
931 
932  grans = rt_nurb_grans(srf);
933 
934  rec[rec_ptr].d.d_id = ID_BSURF;
935  rec[rec_ptr].d.d_nknots = (short)(((srf->u.k_size + srf->v.k_size)
936  * sizeof(dbfloat_t)) + sizeof(union record)-1)/ sizeof(union record);
937  rec[rec_ptr].d.d_nctls = (short)((
938  RT_NURB_EXTRACT_COORDS(srf->pt_type)
939  * (srf->s_size[0] * srf->s_size[1])
940  * sizeof(dbfloat_t)) + sizeof(union record)-1)
941  / sizeof(union record);
942 
943  rec[rec_ptr].d.d_order[0] = srf->order[0];
944  rec[rec_ptr].d.d_order[1] = srf->order[1];
945  rec[rec_ptr].d.d_kv_size[0] = srf->u.k_size;
946  rec[rec_ptr].d.d_kv_size[1] = srf->v.k_size;
947  rec[rec_ptr].d.d_ctl_size[0] = srf->s_size[0];
948  rec[rec_ptr].d.d_ctl_size[1] = srf->s_size[1];
949  rec[rec_ptr].d.d_geom_type =
950  RT_NURB_EXTRACT_COORDS(srf->pt_type);
951 
952  vp = (dbfloat_t *) &rec[rec_ptr +1];
953  for (n = 0; n < rec[rec_ptr].d.d_kv_size[0]; n++) {
954  *vp++ = srf->u.knots[n];
955  }
956 
957  for (n = 0; n < rec[rec_ptr].d.d_kv_size[1]; n++) {
958  *vp++ = srf->v.knots[n];
959  }
960 
961  vp = (dbfloat_t *) &rec[rec_ptr + 1 +
962  rec[rec_ptr].d.d_nknots];
963 
964  for (n = 0; n < (srf->s_size[0] * srf->s_size[1]) *
965  rec[rec_ptr].d.d_geom_type; n++)
966  *vp++ = srf->ctl_points[n];
967 
968  rec_ptr += grans;
969  total_grans -= grans;
970  }
971 
972  bu_log("DEPRECATED: The 'bspline' primitive is no longer supported. Use 'brep' NURBS instead.\n");
973 
974  return 0;
975 }
976 
977 int
978 rt_nurb_bytes(struct face_g_snurb *srf)
979 {
980  int total_bytes=0;
981 
982  total_bytes = 3 * SIZEOF_NETWORK_LONG /* num_coords and order */
983  + 2 * SIZEOF_NETWORK_LONG /* k_size in both knot vectors */
984  + srf->u.k_size * SIZEOF_NETWORK_DOUBLE /* u knot vector knots */
985  + srf->v.k_size * SIZEOF_NETWORK_DOUBLE /* v knot vector knots */
986  + 2 * SIZEOF_NETWORK_LONG /* mesh size */
987  + RT_NURB_EXTRACT_COORDS(srf->pt_type) *
988  (srf->s_size[0] * srf->s_size[1]) * SIZEOF_NETWORK_DOUBLE; /* control point mesh */
989 
990  return total_bytes;
991 }
992 
993 
994 int
995 rt_nurb_export5(struct bu_external *ep, const struct rt_db_internal *ip, double UNUSED(local2mm), const struct db_i *dbip)
996 {
997  struct rt_nurb_internal *sip;
998  int s;
999  unsigned char *cp;
1000  int coords;
1001 
1002  if (dbip) RT_CK_DBI(dbip);
1003 
1004  RT_CK_DB_INTERNAL(ip);
1005  if (ip->idb_type != ID_BSPLINE) return -1;
1006  sip = (struct rt_nurb_internal *) ip->idb_ptr;
1007  RT_NURB_CK_MAGIC(sip);
1008 
1009  /* Figure out how many bytes are needed by
1010  * walking through the surfaces and
1011  * calculating the number of bytes
1012  * needed for storage and add it to the total
1013  */
1014  BU_EXTERNAL_INIT(ep);
1015  ep->ext_nbytes = SIZEOF_NETWORK_LONG; /* number of surfaces */
1016  for (s = 0; s < sip->nsrf; s++) {
1017  ep->ext_nbytes += rt_nurb_bytes(sip->srfs[s]);
1018  }
1019 
1020  ep->ext_buf = (uint8_t *)bu_malloc(ep->ext_nbytes, "nurb external");
1021  cp = (unsigned char *)ep->ext_buf;
1022 
1023  *(uint32_t *)cp = htonl(sip->nsrf);
1024  cp += SIZEOF_NETWORK_LONG;
1025 
1026  for (s = 0; s < sip->nsrf; s++) {
1027  int i;
1028  struct face_g_snurb *srf = sip->srfs[s];
1029 
1030  /* must be double for import and export */
1031  double *uknots;
1032  double *vknots;
1033  double *points;
1034 
1035  NMG_CK_SNURB(srf);
1036 
1037  coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
1038  *(uint32_t *)cp = htonl(coords);
1039  cp += SIZEOF_NETWORK_LONG;
1040  *(uint32_t *)cp = htonl(srf->order[0]);
1041  cp += SIZEOF_NETWORK_LONG;
1042  *(uint32_t *)cp = htonl(srf->order[1]);
1043  cp += SIZEOF_NETWORK_LONG;
1044  *(uint32_t *)cp = htonl(srf->u.k_size);
1045  cp += SIZEOF_NETWORK_LONG;
1046  *(uint32_t *)cp = htonl(srf->v.k_size);
1047  cp += SIZEOF_NETWORK_LONG;
1048  *(uint32_t *)cp = htonl(srf->s_size[0]);
1049  cp += SIZEOF_NETWORK_LONG;
1050  *(uint32_t *)cp = htonl(srf->s_size[1]);
1051  cp += SIZEOF_NETWORK_LONG;
1052 
1053  /* allocate for export */
1054  uknots = (double *)bu_malloc(srf->u.k_size * sizeof(double), "uknots");
1055  vknots = (double *)bu_malloc(srf->v.k_size * sizeof(double), "vknots");
1056  points = (double *)bu_malloc(coords * srf->s_size[0] * srf->s_size[1] * sizeof(double), "points");
1057 
1058  /* convert fastf_t to double */
1059  for (i=0; i<srf->u.k_size; i++) {
1060  uknots[i] = srf->u.knots[i];
1061  }
1062  for (i=0; i<srf->v.k_size; i++) {
1063  vknots[i] = srf->v.knots[i];
1064  }
1065  for (i=0; i<coords * srf->s_size[0] * srf->s_size[1]; i++) {
1066  points[i] = srf->ctl_points[i];
1067  }
1068 
1069  /* serialize */
1070  bu_cv_htond(cp, (unsigned char *)uknots, srf->u.k_size);
1071  cp += srf->u.k_size * SIZEOF_NETWORK_DOUBLE;
1072  bu_cv_htond(cp, (unsigned char *)vknots, srf->v.k_size);
1073  cp += srf->v.k_size * SIZEOF_NETWORK_DOUBLE;
1074  bu_cv_htond(cp, (unsigned char *)srf->ctl_points,
1075  coords * srf->s_size[0] * srf->s_size[1]);
1076  cp += coords * srf->s_size[0] * srf->s_size[1] * SIZEOF_NETWORK_DOUBLE;
1077 
1078  /* release our arrays */
1079  bu_free(uknots, "uknots");
1080  bu_free(vknots, "vknots");
1081  bu_free(points, "points");
1082  }
1083 
1084  bu_log("DEPRECATED: The 'bspline' primitive is no longer supported. Use 'brep' NURBS instead.\n");
1085 
1086  return 0;
1087 }
1088 
1089 
1090 int
1091 rt_nurb_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
1092 {
1093 
1094  struct rt_nurb_internal *sip;
1095  register int i;
1096  int s;
1097  unsigned char *cp;
1098  fastf_t tmp_vec[4];
1099 
1100  if (dbip) RT_CK_DBI(dbip);
1101  BU_CK_EXTERNAL(ep);
1102 
1103  RT_CK_DB_INTERNAL(ip);
1104  ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
1105  ip->idb_type = ID_BSPLINE;
1106  ip->idb_meth = &OBJ[ID_BSPLINE];
1107  BU_ALLOC(ip->idb_ptr, struct rt_nurb_internal);
1108 
1109  sip = (struct rt_nurb_internal *)ip->idb_ptr;
1110  sip->magic = RT_NURB_INTERNAL_MAGIC;
1111 
1112  cp = (unsigned char *)ep->ext_buf;
1113 
1114  sip->nsrf = ntohl(*(uint32_t *)cp);
1115  cp += SIZEOF_NETWORK_LONG;
1116  sip->srfs = (struct face_g_snurb **) bu_calloc(sip->nsrf, sizeof(struct face_g_snurb *), "nurb srfs[]");
1117 
1118  for (s = 0; s < sip->nsrf; s++) {
1119  register struct face_g_snurb *srf;
1120  int coords;
1121  int pt_type;
1122  int order[2], u_size, v_size;
1123  int s_size[2];
1124 
1125  /* must be double for import and export */
1126  double *uknots;
1127  double *vknots;
1128  double *points;
1129 
1130  pt_type = ntohl(*(uint32_t *)cp);
1131  cp += SIZEOF_NETWORK_LONG;
1132  order[0] = ntohl(*(uint32_t *)cp);
1133  cp += SIZEOF_NETWORK_LONG;
1134  order[1] = ntohl(*(uint32_t *)cp);
1135  cp += SIZEOF_NETWORK_LONG;
1136  u_size = ntohl(*(uint32_t *)cp);
1137  cp += SIZEOF_NETWORK_LONG;
1138  v_size = ntohl(*(uint32_t *)cp);
1139  cp += SIZEOF_NETWORK_LONG;
1140  s_size[0] = ntohl(*(uint32_t *)cp);
1141  cp += SIZEOF_NETWORK_LONG;
1142  s_size[1] = ntohl(*(uint32_t *)cp);
1143  cp += SIZEOF_NETWORK_LONG;
1144  if (pt_type == 3)
1145  pt_type = RT_NURB_MAKE_PT_TYPE(3, RT_NURB_PT_XYZ, RT_NURB_PT_NONRAT);
1146  else
1147  pt_type = RT_NURB_MAKE_PT_TYPE(4, RT_NURB_PT_XYZ, RT_NURB_PT_RATIONAL);
1148 
1149  sip->srfs[s] = (struct face_g_snurb *) rt_nurb_new_snurb(
1150  order[0], order[1],
1151  u_size, v_size,
1152  s_size[0], s_size[1],
1153  pt_type, (struct resource *)NULL);
1154 
1155  srf = sip->srfs[s];
1156  coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
1157 
1158  uknots = (double *)bu_malloc(srf->u.k_size * sizeof(double), "uknots");
1159  vknots = (double *)bu_malloc(srf->v.k_size * sizeof(double), "vknots");
1160 
1161  bu_cv_ntohd((unsigned char *)uknots, cp, srf->u.k_size);
1162  cp += srf->u.k_size * SIZEOF_NETWORK_DOUBLE;
1163  bu_cv_ntohd((unsigned char *)vknots, cp, srf->v.k_size);
1164  cp += srf->v.k_size * SIZEOF_NETWORK_DOUBLE;
1165 
1166  /* convert double to fastf_t */
1167  for (i=0; i<srf->u.k_size; i++) {
1168  srf->u.knots[i] = uknots[i];
1169  }
1170  for (i=0; i<srf->v.k_size; i++) {
1171  srf->v.knots[i] = vknots[i];
1172  }
1173 
1174  bu_free(uknots, "uknots");
1175  bu_free(vknots, "vknots");
1176 
1177  rt_nurb_kvnorm(&srf->u);
1178  rt_nurb_kvnorm(&srf->v);
1179 
1180  points = (double *)bu_malloc(coords * srf->s_size[0] * srf->s_size[1] * sizeof(double), "points");
1181 
1182  bu_cv_ntohd((unsigned char *)points, cp, coords * srf->s_size[0] * srf->s_size[1]);
1183 
1184  /* convert double to fastf_t */
1185  for (i=0; i < coords * srf->s_size[0] * srf->s_size[1]; i++) {
1186  srf->ctl_points[i] = points[i];
1187  }
1188 
1189  bu_free(points, "points");
1190 
1191  cp += coords * srf->s_size[0] * srf->s_size[1] * SIZEOF_NETWORK_DOUBLE;
1192 
1193  if (mat == NULL) mat = bn_mat_identity;
1194  for (i=0; i<srf->s_size[0] * srf->s_size[1]; i++) {
1195  if (coords == 3) {
1196  VMOVE(tmp_vec, &srf->ctl_points[i*coords]);
1197  MAT4X3PNT(&srf->ctl_points[i*coords], mat, tmp_vec);
1198  } else if (coords == 4) {
1199  HMOVE(tmp_vec, &srf->ctl_points[i*coords]);
1200  MAT4X4PNT(&srf->ctl_points[i*coords], mat, tmp_vec);
1201  } else {
1202  bu_log("rt_nurb_internal: %d invalid elements per vect\n", coords);
1203  return -1;
1204  }
1205  }
1206 
1207  /* bound the surface for tolerancing and other bounding box tests */
1208  rt_nurb_s_bound(sip->srfs[s], sip->srfs[s]->min_pt,
1209  sip->srfs[s]->max_pt);
1210  }
1211  return 0;
1212 }
1213 
1214 
1215 void
1217 {
1218  register struct rt_nurb_internal *sip;
1219  register int i;
1220 
1221  RT_CK_DB_INTERNAL(ip);
1222 
1223  sip = (struct rt_nurb_internal *) ip->idb_ptr;
1224  RT_NURB_CK_MAGIC(sip);
1225 
1226  /* Free up storage for the nurb surfaces */
1227  for (i = 0; i < sip->nsrf; i++) {
1228  rt_nurb_free_snurb(sip->srfs[i], (struct resource *)NULL);
1229  }
1230  sip->magic = 0;
1231  sip->nsrf = 0;
1232  bu_free(sip->srfs, "nurb surfs[]");
1233  sip->srfs = (struct face_g_snurb**)((void *)0);
1234 
1235  bu_free(ip->idb_ptr, "sip ifree");
1236  ip->idb_ptr = ((void *)0);
1237 }
1238 
1239 
1240 int
1241 rt_nurb_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
1242 {
1243  register int j;
1244  register struct rt_nurb_internal *sip =
1245  (struct rt_nurb_internal *) ip->idb_ptr;
1246  int i;
1247  int surf;
1248 
1249  RT_NURB_CK_MAGIC(sip);
1250  bu_vls_strcat(str, "Non-Uniform Rational B-Spline (NURBS) solid\n");
1251 
1252  bu_vls_printf(str, "\t%d surfaces\n", sip->nsrf);
1253  if (verbose < 2) return 0;
1254 
1255  for (surf = 0; surf < sip->nsrf; surf++) {
1256  register struct face_g_snurb *np;
1257  register fastf_t *mp;
1258  int ncoord;
1259 
1260  np = sip->srfs[surf];
1261  NMG_CK_SNURB(np);
1262  mp = np->ctl_points;
1263  ncoord = RT_NURB_EXTRACT_COORDS(np->pt_type);
1264 
1265  bu_vls_printf(str,
1266  "\tSurface %d: order %d x %d, mesh %d x %d\n",
1267  surf, np->order[0], np->order[1],
1268  np->s_size[0], np->s_size[1]);
1269 
1270  bu_vls_printf(str, "\t\tVert (%g, %g, %g)\n",
1271  INTCLAMP(mp[X] * mm2local),
1272  INTCLAMP(mp[Y] * mm2local),
1273  INTCLAMP(mp[Z] * mm2local));
1274 
1275  if (verbose < 3) continue;
1276 
1277  /* Print out the knot vectors */
1278  bu_vls_printf(str, "\tU: ");
1279  for (i=0; i < np->u.k_size; i++)
1280  bu_vls_printf(str, "%g, ", INTCLAMP(np->u.knots[i]));
1281  bu_vls_printf(str, "\n\tV: ");
1282  for (i=0; i < np->v.k_size; i++)
1283  bu_vls_printf(str, "%g, ", INTCLAMP(np->v.knots[i]));
1284  bu_vls_printf(str, "\n");
1285 
1286  /* print out all the points */
1287  for (i=0; i < np->s_size[0]; i++) {
1288  bu_vls_printf(str, "\tRow %d:\n", i);
1289  for (j = 0; j < np->s_size[1]; j++) {
1290  if (ncoord == 3) {
1291  bu_vls_printf(str, "\t\t(%g, %g, %g)\n",
1292  INTCLAMP(mp[X] * mm2local),
1293  INTCLAMP(mp[Y] * mm2local),
1294  INTCLAMP(mp[Z] * mm2local));
1295  } else {
1296  bu_vls_printf(str, "\t\t(%g, %g, %g, %g)\n",
1297  INTCLAMP(mp[X] * mm2local),
1298  INTCLAMP(mp[Y] * mm2local),
1299  INTCLAMP(mp[Z] * mm2local),
1300  INTCLAMP(mp[W]));
1301  }
1302  mp += ncoord;
1303  }
1304  }
1305  }
1306  return 0;
1307 }
1308 
1309 
1310 int
1311 rt_nurb_get(struct bu_vls *logstr, const struct rt_db_internal *intern, const char *attr)
1312 {
1313  struct rt_nurb_internal *nurb=(struct rt_nurb_internal *)intern->idb_ptr;
1314  struct face_g_snurb *srf;
1315  int i, j, k;
1316  int coords;
1317 
1318  RT_NURB_CK_MAGIC(nurb);
1319 
1320  if (attr == (char *)NULL) {
1321  bu_vls_strcpy(logstr, "bspline");
1322  bu_vls_printf(logstr, " N %d S {", nurb->nsrf);
1323  for (i=0; i<nurb->nsrf; i++) {
1324  srf = nurb->srfs[i];
1325  bu_vls_printf(logstr, " { O {%d %d} s {%d %d} T %d u {",
1326  srf->order[0], srf->order[1],
1327  srf->s_size[0], srf->s_size[1],
1328  srf->pt_type/* !!! -- export this?, srf->u.k_size */);
1329  for (j=0; j<srf->u.k_size; j++) {
1330  bu_vls_printf(logstr, " %.25G", srf->u.knots[j]);
1331  }
1332  bu_vls_printf(logstr, "} v {"/* !!! -- export this?, srf->v.k_size */);
1333  for (j=0; j<srf->v.k_size; j++) {
1334  bu_vls_printf(logstr, " %.25G", srf->v.knots[j]);
1335  }
1336  bu_vls_strcat(logstr, "} P {");
1337 
1338  coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
1339  for (j=0; j<srf->s_size[0]*srf->s_size[1]; j++) {
1340  for (k=0; k<coords; k++) {
1341  bu_vls_printf(logstr, " %.25G",
1342  srf->ctl_points[j*coords + k]);
1343  }
1344  }
1345  bu_vls_strcat(logstr, " } }");
1346  }
1347  bu_vls_printf(logstr, " }");
1348  return BRLCAD_OK;
1349  }
1350 
1351  bu_vls_printf(logstr, "Nurb has no attribute '%s'", attr);
1352  return BRLCAD_ERROR;
1353 }
1354 
1355 int
1356 rt_nurb_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc, const char **argv)
1357 {
1358  struct rt_nurb_internal *nurb;
1359  int srf_no;
1360  Tcl_Obj *obj, *list, **srf_array, **srf_param_array;
1361  struct face_g_snurb *srf;
1362  int i;
1363  char *key;
1364  int len;
1365 
1366  RT_CK_DB_INTERNAL(intern);
1367  nurb = (struct rt_nurb_internal *)intern->idb_ptr;
1368  RT_NURB_CK_MAGIC(nurb);
1369 
1370  while (argc >= 2) {
1371  obj = Tcl_NewStringObj(argv[1], -1);
1372  list = Tcl_NewListObj(0, NULL);
1373  if (Tcl_ListObjAppendList(brlcad_interp, list, obj) != TCL_OK) {
1374  return BRLCAD_ERROR;
1375  }
1376 
1377  if (BU_STR_EQUAL(argv[0], "N")) {
1378  if (nurb->srfs) {
1379  for (i=0; i<nurb->nsrf; i++)
1380  rt_nurb_free_snurb(nurb->srfs[i], NULL);
1381  bu_free((char *)nurb->srfs, "nurb surfaces");
1382  }
1383  nurb->nsrf = atoi(argv[1]);
1384  nurb->srfs = (struct face_g_snurb **) bu_calloc(
1385  nurb->nsrf, sizeof(struct face_g_snurb *), "nurb srfs[]");
1386  } else if (BU_STR_EQUAL(argv[0], "S")) {
1387  (void)Tcl_ListObjGetElements(brlcad_interp, list, &len, &srf_array);
1388  for (srf_no=0; srf_no < nurb->nsrf; srf_no++) {
1389  int n_params=0;
1390  int *order=NULL, *s_size=NULL, u_size=0, v_size=0, pt_type=0;
1391  fastf_t *u_pts=NULL, *v_pts=NULL;
1392 
1393  (void)Tcl_ListObjGetElements(brlcad_interp, srf_array[srf_no], &n_params,
1394  &srf_param_array);
1395 
1396  for (i=0; i<n_params; i+= 2) {
1397  int tmp_len;
1398 
1399  key = Tcl_GetStringFromObj(srf_param_array[i], NULL);
1400  if (BU_STR_EQUAL(key, "O")) {
1401  tmp_len = 0;
1402  if (tcl_obj_to_int_array(brlcad_interp, srf_param_array[i+1],
1403  &order, &tmp_len) != 2) {
1404  bu_vls_printf(logstr,
1405  "ERROR: unable to parse surface\n");
1406  return BRLCAD_ERROR;
1407  }
1408  } else if (BU_STR_EQUAL(key, "s")) {
1409  tmp_len = 0;
1410  if (tcl_obj_to_int_array(brlcad_interp, srf_param_array[i+1],
1411  &s_size, &tmp_len) != 2) {
1412  bu_vls_printf(logstr,
1413  "ERROR: unable to parse surface\n");
1414  return BRLCAD_ERROR;
1415  }
1416  } else if (BU_STR_EQUAL(key, "T")) {
1417  pt_type = atoi(Tcl_GetStringFromObj(
1418  srf_param_array[i+1], NULL));
1419  } else if (BU_STR_EQUAL(key, "u")) {
1420  tcl_obj_to_fastf_array(brlcad_interp, srf_param_array[i+1], &u_pts,
1421  &u_size);
1422  } else if (BU_STR_EQUAL(key, "v")) {
1423  tcl_obj_to_fastf_array(brlcad_interp, srf_param_array[i+1], &v_pts,
1424  &v_size);
1425  } else if (BU_STR_EQUAL(key, "P")) {
1426  int tmp2;
1427 
1428  if (!order || !s_size || !u_pts || !v_pts ||
1429  u_size == 0 || v_size == 0 || pt_type == 0) {
1430  bu_vls_printf(logstr,
1431  "ERROR: Need all other details set before ctl points\n");
1432  return BRLCAD_ERROR;
1433  }
1434  nurb->srfs[srf_no] = (struct face_g_snurb *) rt_nurb_new_snurb(
1435  order[0], order[1],
1436  u_size, v_size,
1437  s_size[0], s_size[1],
1438  pt_type, (struct resource *)NULL);
1439  srf = nurb->srfs[srf_no];
1440  bu_free((char *)order, "order");
1441  bu_free((char *)s_size, "s_size");
1442  (void)memcpy(srf->u.knots, u_pts,
1443  srf->u.k_size * sizeof(fastf_t));
1444  (void)memcpy(srf->v.knots, v_pts,
1445  srf->v.k_size * sizeof(fastf_t));
1446  bu_free((char *)u_pts, "u_pts");
1447  bu_free((char *)v_pts, "v_pts");
1448  tmp_len = srf->s_size[0] * srf->s_size[1] *
1449  RT_NURB_EXTRACT_COORDS(srf->pt_type);
1450  tmp2 = tmp_len;
1451  if (tcl_obj_to_fastf_array(brlcad_interp, srf_param_array[i+1],
1452  &srf->ctl_points, &tmp_len) != tmp2) {
1453  bu_vls_printf(logstr,
1454  "ERROR: unable to parse surface\n");
1455  return BRLCAD_ERROR;
1456  }
1457  }
1458  }
1459  }
1460  }
1461 
1462  Tcl_DecrRefCount(list);
1463 
1464  argc -= 2;
1465  argv += 2;
1466  }
1467 
1468  return BRLCAD_OK;
1469 }
1470 
1471 
1472 int
1473 rt_nurb_params(struct pc_pc_set *, const struct rt_db_internal *)
1474 {
1475  return 0; /* OK */
1476 }
1477 
1478 #ifdef __cplusplus
1479 }
1480 #endif
1481 
1482 /*
1483  * Local Variables:
1484  * mode: C
1485  * tab-width: 8
1486  * indent-tabs-mode: t
1487  * c-file-style: "stroustrup"
1488  * End:
1489  * ex: shiftwidth=4 tabstop=8
1490  */
int rt_nurb_bytes(struct face_g_snurb *srf)
Definition: bspline.cpp:978
#define BU_LIST_FOR(p, structure, hp)
Definition: list.h:365
Definition: raytrace.h:800
void rt_nurb_free_snurb(struct face_g_snurb *srf, struct resource *res)
Definition: nurb_util.c:127
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
#define BU_LIST_INSERT(old, new)
Definition: list.h:183
#define SIZEOF_NETWORK_DOUBLE
Definition: cv.h:48
struct bu_list bez_hd
Definition: bspline.cpp:68
struct nurb_specific * next
Definition: bspline.cpp:66
struct face_g_snurb * rt_nurb_scopy(const struct face_g_snurb *srf, struct resource *res)
Definition: nurb_copy.c:39
Definition: list.h:118
struct nurb_hit * next
Definition: bspline.cpp:72
void * hit_private
PRIVATE handle for xxx_shot()
Definition: raytrace.h:254
struct nurb_hit * prev
Definition: bspline.cpp:73
int rt_nurb_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *info)
Definition: bspline.cpp:595
int rt_nurb_export4(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
Definition: bspline.cpp:890
void rt_nurb_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
Definition: bspline.cpp:477
void rt_nurb_ifree(struct rt_db_internal *ip)
Definition: bspline.cpp:1216
int rt_brep_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol, const struct rt_view_info *info)
Definition: brep.cpp:4245
double dist
>= 0
Definition: tol.h:73
vect_t crv_pdir
Principle direction.
Definition: raytrace.h:307
const mat_t bn_mat_identity
Matrix and vector functionality.
Definition: mat.c:46
fastf_t uv_u
Range 0..1.
Definition: raytrace.h:341
#define RT_NURB_INTERNAL_MAGIC
Definition: magic.h:101
if lu s
Definition: nmg_mod.c:3860
struct face_g_snurb * rt_nurb_s_refine(const struct face_g_snurb *srf, int dir, struct knot_vector *kv, struct resource *res)
Definition: nurb_refine.c:45
void bu_vls_strcat(struct bu_vls *vp, const char *s)
Definition: vls.c:368
#define VSET(a, b, c, d)
Definition: color.c:53
#define VSETALL(a, s)
Definition: color.c:54
Definition: raytrace.h:215
#define SIZEOF_NETWORK_LONG
Definition: cv.h:46
Definition: pc.h:108
Definition: raytrace.h:368
int rt_nurb_bezier(struct bu_list *bezier_hd, const struct face_g_snurb *orig_surf, struct resource *res)
Definition: nurb_bezier.c:53
void rt_nurb_brep(ON_Brep **b, struct rt_db_internal *ip, const struct bn_tol *tol)
Definition: raytrace.h:248
void rt_nurb_curvature(struct curvature *cvp, const struct face_g_snurb *srf, fastf_t u, fastf_t v)
Definition: nurb_c2.c:40
void rt_brep_print(register const struct soltab *stp)
#define SMALL_FASTF
Definition: defines.h:342
fastf_t st_aradius
Radius of APPROXIMATING sphere.
Definition: raytrace.h:433
struct face_g_snurb * rt_nurb_new_snurb(int u_order, int v_order, int n_u, int n_v, int n_rows, int n_cols, int pt_type, struct resource *res)
Definition: nurb_util.c:42
int rt_brep_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
Definition: brep.cpp:1186
void rt_brep_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
Header file for the BRL-CAD common definitions.
fastf_t hit_uv[2]
Definition: bspline.cpp:77
point_t hit_point
Definition: bspline.cpp:75
#define ID_BSPLINE
B-spline object.
Definition: raytrace.h:467
struct resource * a_resource
dynamic memory resources
Definition: raytrace.h:1591
int rt_in_rpp(struct xray *rp, const fastf_t *invdir, const fastf_t *min, const fastf_t *max)
void bu_cv_htond(unsigned char *out, const unsigned char *in, size_t count)
int rt_nurb_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
Definition: bspline.cpp:995
#define HIDDEN
Definition: common.h:86
fastf_t hit_dist
Definition: bspline.cpp:74
struct bu_list l
Definition: raytrace.h:369
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
int rt_nurb_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
Definition: bspline.cpp:1091
if(share_geom)
Definition: nmg_mod.c:3829
int idb_major_type
Definition: raytrace.h:192
#define RT_BREP_INTERNAL_MAGIC
Definition: magic.h:86
Definition: color.c:49
struct rt_i * a_rt_i
this librt instance
Definition: raytrace.h:1588
#define RT_G_DEBUG
Definition: raytrace.h:1718
vect_t hit_vpriv
PRIVATE vector for xxx_*()
Definition: raytrace.h:253
#define RT_ADD_VLIST(hd, pnt, draw)
Definition: raytrace.h:1865
#define RT_CK_DB_INTERNAL(_p)
Definition: raytrace.h:207
#define BU_ALLOC(_ptr, _type)
Definition: malloc.h:223
void * bu_calloc(size_t nelem, size_t elsize, const char *str)
Definition: malloc.c:321
fastf_t st_bradius
Radius of BOUNDING sphere.
Definition: raytrace.h:434
int rt_brep_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
Definition: brep.cpp:453
fastf_t crv_c2
curvature in other direction
Definition: raytrace.h:309
void rt_nurb_free(register struct soltab *stp)
Definition: bspline.cpp:555
int hit_surfno
Definition: bspline.cpp:78
void rt_nurb_s_norm(struct face_g_snurb *srf, fastf_t u, fastf_t v, fastf_t *norm)
Definition: nurb_norm.c:44
#define RT_DB_INTERNAL_INIT(_p)
Definition: raytrace.h:199
#define BN_VLIST_LINE_MOVE
Definition: vlist.h:82
const struct rt_functab * idb_meth
for ft_ifree(), etc.
Definition: raytrace.h:194
fastf_t primitive_get_absolute_tolerance(const struct rt_tess_tol *ttol, fastf_t rel_to_abs)
int a_x
Screen X of ray, if applicable.
Definition: raytrace.h:1596
#define BRLCAD_OK
Definition: defines.h:71
uint8_t * ext_buf
Definition: parse.h:216
#define BU_GET(_ptr, _type)
Definition: malloc.h:201
point_t st_max
max X, Y, Z of bounding RPP
Definition: raytrace.h:438
char * hit_private
Definition: bspline.cpp:79
#define BN_VLIST_LINE_DRAW
Definition: vlist.h:83
int rt_nurb_class(void)
Definition: bspline.cpp:588
void rt_brep_free(register struct soltab *stp)
Definition: brep.cpp:1713
fastf_t flip_dbfloat(dbfloat_t d)
Definition: db_flip.c:58
#define UNUSED(parameter)
Definition: common.h:239
int rt_nurb_bbox(struct rt_db_internal *ip, point_t *min, point_t *max)
Definition: bspline.cpp:123
#define BU_PUT(_ptr, _type)
Definition: malloc.h:215
HIDDEN int rt_nurb_grans(struct face_g_snurb *srf)
Definition: bspline.cpp:101
Support for uniform tolerances.
Definition: tol.h:71
void rt_nurb_s_print(char *c, const struct face_g_snurb *srf)
Definition: nurb_util.c:214
int rt_nurb_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
Definition: bspline.cpp:200
int rt_nurb_tess(struct nmgregion **, struct model *, struct rt_db_internal *, const struct rt_tess_tol *, const struct bn_tol *)
Definition: bspline.cpp:724
#define BU_LIST_WHILE(p, structure, hp)
Definition: list.h:410
void rt_nurb_kvnorm(register struct knot_vector *kv)
Definition: nurb_knot.c:251
vect_t r_dir
Direction of ray (UNIT Length)
Definition: raytrace.h:219
struct bn_tol rti_tol
Math tolerances for this model.
Definition: raytrace.h:1765
struct face_g_snurb * srf
Definition: bspline.cpp:67
#define RT_CK_DBI(_p)
Definition: raytrace.h:829
#define RT_GET_SEG(p, res)
Definition: raytrace.h:379
int tcl_obj_to_fastf_array(Tcl_Interp *interp, Tcl_Obj *list, fastf_t **array, int *array_len)
Definition: tcl.c:802
int rt_nurb_params(struct pc_pc_set *, const struct rt_db_internal *)
Definition: bspline.cpp:1473
#define ZERO(val)
Definition: units.c:38
#define BU_LIST_INIT(_hp)
Definition: list.h:148
void * idb_ptr
Definition: raytrace.h:195
point_t r_pt
Point at which ray starts.
Definition: raytrace.h:218
void rt_nurb_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
Definition: bspline.cpp:540
point_t st_min
min X, Y, Z of bounding RPP
Definition: raytrace.h:437
void bu_cv_ntohd(unsigned char *out, const unsigned char *in, size_t count)
const struct rt_functab OBJ[]
Definition: table.c:159
#define UV_TOL
void bn_vec_ortho(vect_t out, const vect_t in)
int a_y
Screen Y of ray, if applicable.
Definition: raytrace.h:1597
short flip_short(short s)
Definition: db_flip.c:47
void rt_brep_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
Definition: brep.cpp:1695
void bu_vls_printf(struct bu_vls *vls, const char *fmt,...) _BU_ATTR_PRINTF23
Definition: vls.c:694
int rt_nurb_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
Definition: bspline.cpp:1241
#define BU_EXTERNAL_INIT(_p)
Definition: parse.h:229
void * st_specific
-> ID-specific (private) struct
Definition: raytrace.h:435
vect_t hit_normal
Definition: bspline.cpp:76
void rt_nurb_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
Definition: bspline.cpp:507
fastf_t crv_c1
curvature in principle dir
Definition: raytrace.h:308
Definition: color.c:51
void rt_nurb_print(register const struct soltab *stp)
Definition: bspline.cpp:296
int dbi_version
PRIVATE: use db_version()
Definition: raytrace.h:824
int rt_nurb_adjust(struct bu_vls *logstr, struct rt_db_internal *intern, int argc, const char **argv)
Definition: bspline.cpp:1356
void bu_vls_strcpy(struct bu_vls *vp, const char *s)
Definition: vls.c:310
int hit_surfno
solid-specific surface indicator
Definition: raytrace.h:255
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
vect_t hit_normal
DEPRECATED: Surface Normal at hit_point, use RT_HIT_NORMAL.
Definition: raytrace.h:252
#define BU_CK_LIST_HEAD(_p)
Definition: list.h:142
#define BU_CK_EXTERNAL(_p)
Definition: parse.h:224
#define DEBUG_SPLINE
9 Splines
Definition: raytrace.h:92
void rt_brep_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
size_t ext_nbytes
Definition: parse.h:210
#define NULL_HIT
Definition: bspline.cpp:82
int rt_nurb_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
Definition: bspline.cpp:326
fastf_t rt_nurb_par_edge(const struct face_g_snurb *srf, fastf_t epsilon)
Definition: nurb_tess.c:59
struct rt_nurb_uv_hit * rt_nurb_intersect(const struct face_g_snurb *srf, fastf_t *plane1, fastf_t *plane2, double uv_tol, struct resource *res, struct bu_list *plist)
Definition: nurb_ray.c:322
int rt_nurb_get(struct bu_vls *logstr, const struct rt_db_internal *intern, const char *attr)
Definition: bspline.cpp:1311
HIDDEN void verbose(struct human_data_t *dude)
Definition: human.c:2008
Definition: vls.h:56
#define BRLCAD_ERROR
Definition: defines.h:72
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
int rt_nurb_import4(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
Definition: bspline.cpp:731
#define M_SQRT1_2
Definition: fft.h:38
double fastf_t
Definition: defines.h:300
int bn_mk_plane_3pts(plane_t plane, const point_t a, const point_t b, const point_t c, const struct bn_tol *tol)
void rt_nurb_kvknot(register struct knot_vector *new_knots, int order, fastf_t lower, fastf_t upper, int num, struct resource *res)
Definition: nurb_knot.c:47
Tcl_Interp * brlcad_interp
Definition: tcl.c:41
int tcl_obj_to_int_array(Tcl_Interp *interp, Tcl_Obj *list, int **array, int *array_len)
Definition: tcl.c:762
Definition: color.c:50
fastf_t uv_v
Range 0..1.
Definition: raytrace.h:342
int rt_nurb_s_bound(struct face_g_snurb *srf, fastf_t *bmin, fastf_t *bmax)
Definition: nurb_bound.c:48
point_t st_center
Centroid of solid.
Definition: raytrace.h:432
#define BU_STR_EQUAL(s1, s2)
Definition: str.h:126