BRL-CAD
nurb_eval.c
Go to the documentation of this file.
1 /* N U R B _ E V A L . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1990-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_eval.c
23  *
24  * Evaluate a Non Uniform Rational B-spline curve or at the given (u,
25  * v) values.
26  *
27  */
28 /** @} */
29 
30 #include "common.h"
31 
32 #include <math.h>
33 #include "bio.h"
34 
35 #include "vmath.h"
36 #include "nmg.h"
37 #include "raytrace.h"
38 #include "nurb.h"
39 
40 
41 /**
42  * Algorithm -
43  *
44  * The algorithm uses the traditional COX-deBoor approach found in the
45  * book "Practical Guide to Splines" Carl de Boor, pg 147 to evaluate a
46  * parametric value on a curve. This is expanded to the surface.
47  */
48 void
49 rt_nurb_s_eval(const struct face_g_snurb *srf, fastf_t u, fastf_t v, fastf_t *final_value)
50 {
51  fastf_t * mesh_ptr = srf->ctl_points;
52  fastf_t * curves;
53  int i, j, k;
54  int row_size = srf->s_size[RT_NURB_SPLIT_ROW];
55  int col_size = srf->s_size[RT_NURB_SPLIT_COL];
56  fastf_t * c_ptr;
57  fastf_t * diff_curve, *ev_pt;
58  int k_index;
59  int coords = RT_NURB_EXTRACT_COORDS(srf->pt_type);
60 
61  NMG_CK_SNURB(srf);
62 
63  /* Because the algorithm is destructive in nature, the rows of the
64  * control mesh are copied. The evaluation is then done on each
65  * row curve and then evaluation is then performed on the
66  * resulting curve.
67  */
68 
69  diff_curve = (fastf_t *)
70  bu_malloc(row_size * sizeof(fastf_t) * coords,
71  "rt_nurb_s__eval: diff_curve");
72 
73  c_ptr = diff_curve;
74 
75  k_index = rt_nurb_knot_index(&srf->u, u, srf->order[RT_NURB_SPLIT_ROW]);
76  if (k_index < 0) {
77  bu_log("rt_nurb_s_eval: u value outside parameter range\n");
78  bu_log("\tUV = (%g %g)\n", u, v);
79  rt_nurb_s_print("", srf);
80  bu_bomb("rt_nurb_s_eval: u value outside parameter range\n");
81  }
82 
83  curves = (fastf_t *) bu_malloc(col_size * sizeof(fastf_t) * coords,
84  "rt_nurb_s_eval:crv_ptr");
85 
86  for (i = 0; i < row_size; i++) {
87  fastf_t * rtr_pt;
88  fastf_t * crv_ptr;
89 
90  crv_ptr = curves;
91 
92  for (j = 0; j < (col_size * coords); j++) {
93  *crv_ptr++ = *mesh_ptr++;
94  }
95 
96  rtr_pt = (fastf_t *) rt_nurb_eval_crv(curves, srf->order[RT_NURB_SPLIT_ROW], u,
97  &srf->u, k_index, coords);
98 
99  for (k = 0; k < coords; k++)
100  c_ptr[k] = rtr_pt[k];
101  c_ptr += coords;
102  }
103 
104  bu_free((char *)curves, "rt_nurb_s_eval: curves");
105 
106  k_index = rt_nurb_knot_index(&srf->v, v, srf->order[RT_NURB_SPLIT_COL]);
107  if (k_index < 0) {
108  bu_log("rt_nurb_s_eval: v value outside parameter range\n");
109  bu_log("\tUV = (%g %g)\n", u, v);
110  rt_nurb_s_print("", srf);
111  bu_bomb("rt_nurb_s_eval: v value outside parameter range\n");
112  }
113 
114  ev_pt = (fastf_t *) rt_nurb_eval_crv(diff_curve, srf->order[RT_NURB_SPLIT_COL],
115  v, &srf->v, k_index, coords);
116 
117  for (k = 0; k < coords; k++)
118  final_value[k] = ev_pt[k];
119 
120  bu_free ((char *)diff_curve, "rt_nurb_s_eval: diff curve");
121 }
122 
123 
124 void
125 rt_nurb_c_eval(const struct edge_g_cnurb *crv, fastf_t param, fastf_t *final_value)
126 {
127  fastf_t * pnts;
128  fastf_t * ev_pt;
129  int coords;
130  int i, k_index;
131 
132  NMG_CK_CNURB(crv);
133 
134  coords = RT_NURB_EXTRACT_COORDS(crv->pt_type);
135 
136  k_index = rt_nurb_knot_index(&crv->k, param, crv->order);
137  if (k_index < 0) {
138  bu_log("rt_nurb_c_eval: param value outside parameter range\n");
139  bu_log("\tparam = (%g)\n", param);
140  rt_nurb_c_print(crv);
141  bu_bomb("rt_nurb_c_eval: param value outside parameter range\n");
142  }
143 
144  pnts = (fastf_t *) bu_malloc(coords * sizeof(fastf_t) *
145  crv->c_size, "diff: rt_nurb_c_eval");
146 
147  for (i = 0; i < coords * crv->c_size; i++)
148  pnts[i] = crv->ctl_points[i];
149 
150  ev_pt = (fastf_t *) rt_nurb_eval_crv(
151  pnts, crv->order, param, &crv->k, k_index, coords);
152 
153  for (i = 0; i < coords; i++)
154  final_value[i] = ev_pt[i];
155 
156  bu_free((char *) pnts, "rt_nurb_c_eval");
157 }
158 
159 
160 fastf_t *
161 rt_nurb_eval_crv(register fastf_t *crv, int order, fastf_t param, const struct knot_vector *k_vec, int k_index, int coords)
162 {
163  int i, j;
164 
165  if (order <= 1)
166  return
167  (crv + ((k_index) * coords));
168 
169  j = k_index;
170 
171  while (j > (k_index - order + 1)) {
172  register fastf_t k1, k2;
173 
174  k1 = k_vec->knots[ (j + order - 1)];
175 
176  k2 = k_vec->knots[ (j) ];
177 
178  if (!ZERO(k1 - k2)) {
179  for (i= 0; i < coords; i++) {
180  *((crv + ((j) * coords)) + i) =
181  ((k1 - param) *
182  *((crv + ((j - 1) * coords)) + i)
183  + (param - k2) * *((crv + ((j) *
184  coords)) + i)) / (k1 - k2);
185  }
186  }
187  j--;
188  }
189  return rt_nurb_eval_crv(crv, order - 1, param, k_vec,
190  k_index, coords);
191 }
192 
193 
194 void
195 rt_nurb_pr_crv(fastf_t *crv, int c_size, int coords)
196 {
197  int i;
198 
199  fprintf(stderr, "\n");
200  if (coords == 3)
201  for (i = 0; i < c_size; i++)
202  fprintf(stderr, "p%d %f %f %f\n", i, *((crv + ((i) * coords))),
203  *((crv + ((i) * coords)) + 1),
204  *((crv + ((i) * coords)) + 2));
205 
206  else if (coords == 4)
207  for (i = 0; i < c_size; i++)
208  fprintf(stderr, "p%d %f %f %f %f\n", i,
209  *((crv + ((i) * coords))),
210  *((crv + ((i) * coords)) + 1),
211  *((crv + ((i) * coords)) + 2),
212  *((crv + ((i) * coords)) + 3));
213 }
214 
215 
216 /*
217  * Local Variables:
218  * mode: C
219  * tab-width: 8
220  * indent-tabs-mode: t
221  * c-file-style: "stroustrup"
222  * End:
223  * ex: shiftwidth=4 tabstop=8
224  */
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
fastf_t * rt_nurb_eval_crv(register fastf_t *crv, int order, fastf_t param, const struct knot_vector *k_vec, int k_index, int coords)
Definition: nurb_eval.c:161
int rt_nurb_knot_index(const struct knot_vector *kv, fastf_t k_value, int order)
Definition: nurb_knot.c:275
Header file for the BRL-CAD common definitions.
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
void rt_nurb_pr_crv(fastf_t *crv, int c_size, int coords)
Definition: nurb_eval.c:195
void rt_nurb_s_print(char *c, const struct face_g_snurb *srf)
Definition: nurb_util.c:214
#define ZERO(val)
Definition: units.c:38
void rt_nurb_s_eval(const struct face_g_snurb *srf, fastf_t u, fastf_t v, fastf_t *final_value)
Definition: nurb_eval.c:49
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
void rt_nurb_c_eval(const struct edge_g_cnurb *crv, fastf_t param, fastf_t *final_value)
Definition: nurb_eval.c:125
void rt_nurb_c_print(const struct edge_g_cnurb *crv)
Definition: nurb_util.c:181
void bu_bomb(const char *str) _BU_ATTR_NORETURN
Definition: bomb.c:91
double fastf_t
Definition: defines.h:300