BRL-CAD
nurb_bezier.c
Go to the documentation of this file.
1 /* N U R B _ B E Z I E R . C
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 nurb */
21 /** @{ */
22 /** @file primitives/bspline/nurb_bezier.c
23  *
24  * Convert a NURB surface or curve into Bezier form, with no internal
25  * knots.
26  *
27  */
28 /** @} */
29 
30 #include "common.h"
31 
32 #include "bio.h"
33 
34 #include "vmath.h"
35 #include "nmg.h"
36 #include "raytrace.h"
37 #include "nurb.h"
38 
39 
40 /**
41  * Given a single snurb, if it is in Bezier form, duplicate the snurb,
42  * and enqueue it on the bezier_hd list. If the original snurb is NOT
43  * in Bezier form, subdivide it a set of snurbs which are, each of
44  * which are enqueued on the bezier_hd list.
45  *
46  * In either case, the original surface remains untouched.
47  *
48  * Returns -
49  * 0 Surface splitting was done.
50  * 1 Original surface was Bezier, only a copy was done.
51  */
52 int
53 rt_nurb_bezier(struct bu_list *bezier_hd, const struct face_g_snurb *orig_surf, struct resource *res)
54 {
55  struct face_g_snurb *s;
56  int dir;
57  struct bu_list todo;
58 
59  NMG_CK_SNURB(orig_surf);
60 
61  if ((dir = rt_bez_check(orig_surf)) == -1) {
62  s = rt_nurb_scopy(orig_surf, res);
63  BU_LIST_APPEND(bezier_hd, &s->l);
64  return 1; /* Was already Bezier, nothing done */
65  }
66 
67  BU_LIST_INIT(&todo);
68  rt_nurb_s_split(&todo, orig_surf, dir, res);
69 
70  while (BU_LIST_WHILE(s, face_g_snurb, &todo)) {
71  if ((dir = rt_bez_check(s)) == -1) {
72  /* This snurb is now a Bezier */
73  BU_LIST_DEQUEUE(&s->l);
74  BU_LIST_APPEND(bezier_hd, &s->l);
75  } else {
76  /* Split, and keep going */
77  BU_LIST_DEQUEUE(&s->l);
78  rt_nurb_s_split(&todo, s, dir, res);
79  rt_nurb_free_snurb(s, res);
80  }
81  }
82  return 0; /* Bezier snurbs on bezier_hd list */
83 }
84 
85 
86 int
87 rt_bez_check(const struct face_g_snurb *srf)
88 {
89  NMG_CK_SNURB(srf);
90 
91  if (srf->u.k_size > (2.0 * srf->order[0]))
92  return 0;
93  if (srf->v.k_size > (2.0 * srf->order[1]))
94  return 1;
95 
96  return -1;
97 }
98 
99 
100 /**
101  * Check if a NURB curve is in Bezier form.
102  *
103  * returns:
104  * 1 - curve is Bezier
105  * 0 - curve is not Bezier
106  */
107 int
108 nurb_crv_is_bezier(const struct edge_g_cnurb *crv)
109 {
110  int i;
111  fastf_t knot_min, knot_max;
112  int bezier=1;
113 
114  knot_min = crv->k.knots[0];
115  knot_max = crv->k.knots[crv->k.k_size-1];
116 
117  for (i=1; i<crv->k.k_size-1; i++) {
118  if (!ZERO(crv->k.knots[i] - knot_min) && !ZERO(crv->k.knots[i] - knot_max)) {
119  bezier = 0;
120  break;
121  }
122  }
123 
124  return bezier;
125 }
126 
127 
128 /**
129  * Split NURB curve into list of Bezier curves.
130  *
131  * If curve is already Bezier, return NULL
132  */
133 void
134 nurb_c_to_bezier(struct bu_list *clist, struct edge_g_cnurb *crv)
135 {
136  fastf_t knot_min, knot_max;
137  int i;
138  struct edge_g_cnurb *crv1, *crv_copy;
139  int done;
140 
141  /* make a copy of original curve */
142  crv_copy = rt_nurb_crv_copy(crv);
143 
144  /* split curve at each knot value */
145  done = 0;
146  while (!done) {
147  fastf_t split;
148 
149  knot_min = crv_copy->k.knots[0];
150  knot_max = crv_copy->k.knots[crv_copy->k.k_size-1];
151 
152  split = MAX_FASTF;
153  for (i=1; i<crv_copy->k.k_size-1; i++) {
154  if (!ZERO(crv_copy->k.knots[i] - knot_min) && !ZERO(crv_copy->k.knots[i] - knot_max)) {
155  split = crv_copy->k.knots[i];
156  break;
157  }
158  }
159 
160  if (ZERO(split - MAX_FASTF)) {
161  done = 1;
162  BU_LIST_APPEND(clist, &crv_copy->l);
163  break;
164  }
165 
166  crv1 = rt_nurb_c_xsplit(crv_copy, split);
167 
168  rt_nurb_free_cnurb(crv_copy);
169  crv_copy = BU_LIST_PNEXT(edge_g_cnurb, &crv1->l);
170  BU_LIST_DEQUEUE(&crv_copy->l);
171 
172  BU_LIST_APPEND(clist, &crv1->l);
173  }
174 }
175 
176 
177 /*
178  * Local Variables:
179  * mode: C
180  * tab-width: 8
181  * indent-tabs-mode: t
182  * c-file-style: "stroustrup"
183  * End:
184  * ex: shiftwidth=4 tabstop=8
185  */
void rt_nurb_free_snurb(struct face_g_snurb *srf, struct resource *res)
Definition: nurb_util.c:127
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
if lu s
Definition: nmg_mod.c:3860
int rt_nurb_bezier(struct bu_list *bezier_hd, const struct face_g_snurb *orig_surf, struct resource *res)
Definition: nurb_bezier.c:53
Header file for the BRL-CAD common definitions.
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
#define MAX_FASTF
Definition: defines.h:340
void nurb_c_to_bezier(struct bu_list *clist, struct edge_g_cnurb *crv)
Definition: nurb_bezier.c:134
int nurb_crv_is_bezier(const struct edge_g_cnurb *crv)
Definition: nurb_bezier.c:108
#define BU_LIST_PNEXT(structure, p)
Definition: list.h:422
int rt_bez_check(const struct face_g_snurb *srf)
Definition: nurb_bezier.c:87
#define BU_LIST_WHILE(p, structure, hp)
Definition: list.h:410
#define ZERO(val)
Definition: units.c:38
#define BU_LIST_INIT(_hp)
Definition: list.h:148
void bezier(point2d_t *V, int degree, double t, point2d_t *Left, point2d_t *Right, point2d_t eval_pt, point2d_t normal)
Definition: bezier.c:192
void rt_nurb_s_split(struct bu_list *split_hd, const struct face_g_snurb *srf, int dir, struct resource *res)
Definition: nurb_split.c:56
void rt_nurb_free_cnurb(struct edge_g_cnurb *crv)
Definition: nurb_util.c:170
struct edge_g_cnurb * rt_nurb_c_xsplit(struct edge_g_cnurb *crv, fastf_t param)
Definition: nurb_xsplit.c:226
#define BU_LIST_DEQUEUE(cur)
Definition: list.h:209
double fastf_t
Definition: defines.h:300
struct edge_g_cnurb * rt_nurb_crv_copy(const struct edge_g_cnurb *crv)
Definition: nurb_copy.c:69