BRL-CAD
nurb_diff.c
Go to the documentation of this file.
1 /* N U R B _ D I F F . C
2  * BRL-CAD
3  *
4  * Copyright (c) 1986-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_diff.c
23  *
24  * Differentiate a Non Uniform Rational B-Spline (NURB) Surface.
25  *
26  */
27 /** @} */
28 
29 #include "common.h"
30 
31 #include "bio.h"
32 
33 #include "vmath.h"
34 #include "nmg.h"
35 #include "raytrace.h"
36 #include "nurb.h"
37 
38 
39 /**
40  * Given a NURB surface and a direction, differentiate the surface and
41  * return a new surface which is the derivative of the original
42  * surface.
43  *
44  * The algorithm is found in the following reference:
45  *
46  * Carl De Boor, "A Practical Guide To Splines", page 139
47  *
48  * The algorithm deals mainly with the new control mesh, but the new
49  * knot vector is a subset of the original. (subtract a knot from each
50  * of the ends).
51  *
52  * Arguments to rt_nurb_s_diff() --
53  * srf - NURB surface
54  * dir - parametric direction of the split.
55  */
56 
57 struct face_g_snurb *
58 rt_nurb_s_diff(const struct face_g_snurb *srf, int dir)
59 {
60  struct face_g_snurb *nsrf;
61  int i;
62 
63  NMG_CK_SNURB(srf);
64 
65  if (dir == RT_NURB_SPLIT_ROW) {
66  nsrf = (struct face_g_snurb *)
67  rt_nurb_new_snurb(srf->order[0] - 1, srf->order[1],
68  srf->u.k_size - 2, srf->v.k_size,
69  srf->s_size[0], srf->s_size[1] - 1,
70  srf->pt_type, (struct resource *)NULL);
71 
72  for (i = 0; i < srf->s_size[0]; i++) {
73  fastf_t * old_points, *new_points;
74 
75  old_points = srf->ctl_points +
76  i * RT_NURB_EXTRACT_COORDS(srf->pt_type)
77  *srf->s_size[1];
78 
79  new_points = nsrf->ctl_points +
80  i * RT_NURB_EXTRACT_COORDS(nsrf->pt_type)
81  *nsrf->s_size[1];
82 
83  rt_nurb_mesh_diff(srf->order[0],
84  old_points, new_points, srf->u.knots,
85  RT_NURB_EXTRACT_COORDS(srf->pt_type),
86  RT_NURB_EXTRACT_COORDS(nsrf->pt_type),
87  srf->s_size[1], srf->pt_type);
88  }
89 
90  for (i = 1; i < srf->u.k_size - 1; i++)
91  nsrf->u.knots[i - 1] = srf->u.knots[i];
92 
93  for (i = 0; i < srf->v.k_size; i++)
94  nsrf->v.knots[i] = srf->v.knots[i];
95  } else {
96  nsrf = (struct face_g_snurb *) rt_nurb_new_snurb(
97  srf->order[0], srf->order[1] - 1,
98  srf->u.k_size, srf->v.k_size - 2,
99  srf->s_size[0] - 1, srf->s_size[1],
100  srf->pt_type, (struct resource *)NULL);
101 
102  for (i = 0; i < srf->s_size[1]; i++) {
103  fastf_t * old_points, *new_points;
104 
105  old_points = srf->ctl_points +
106  i * RT_NURB_EXTRACT_COORDS(srf->pt_type);
107 
108  new_points = nsrf->ctl_points +
109  i * RT_NURB_EXTRACT_COORDS(nsrf->pt_type);
110 
111  rt_nurb_mesh_diff(srf->order[1],
112  old_points, new_points, srf->v.knots,
113  RT_NURB_EXTRACT_COORDS(srf->pt_type) *
114  srf->s_size[1],
115  RT_NURB_EXTRACT_COORDS(nsrf->pt_type) *
116  nsrf->s_size[1],
117  srf->s_size[0], srf->pt_type);
118  }
119 
120  for (i = 0; i < srf->u.k_size; i++)
121  nsrf->u.knots[i] = srf->u.knots[i];
122 
123  for (i = 1; i < srf->v.k_size - 1; i++)
124  nsrf->v.knots[i-1] = srf->v.knots[i];
125  }
126  return nsrf;
127 }
128 
129 
130 /* Do the same thing for a curve. */
131 
132 struct edge_g_cnurb *
133 rt_nurb_c_diff(const struct edge_g_cnurb *crv)
134 {
135 
136  struct edge_g_cnurb *ncrv;
137  fastf_t * opts, *npts;
138  int i;
139 
140  NMG_CK_CNURB(crv);
141 
142  ncrv = (struct edge_g_cnurb *) rt_nurb_new_cnurb(crv->order - 1,
143  crv->k.k_size - 2, crv->c_size - 1,
144  crv->pt_type);
145 
146  opts = (fastf_t *) crv->ctl_points;
147  npts = (fastf_t *) ncrv->ctl_points;
148 
149  rt_nurb_mesh_diff(crv->order, opts, npts, crv->k.knots,
150  RT_NURB_EXTRACT_COORDS(crv->pt_type),
151  RT_NURB_EXTRACT_COORDS(ncrv->pt_type),
152  crv->c_size, crv->pt_type);
153 
154  for (i = 1; i < crv->k.k_size - 1; i++)
155  ncrv->k.knots[ i - 1] = crv->k.knots[i];
156 
157  return ncrv;
158 
159 }
160 
161 
162 void
163 rt_nurb_mesh_diff(int order, const fastf_t *o_pts, fastf_t *n_pts, const fastf_t *knots, int o_stride, int n_stride, int o_size, int pt_type)
164 {
165  int i, k;
166  int coords;
167  fastf_t denom;
168 
169  coords = RT_NURB_EXTRACT_COORDS(pt_type);
170 
171  for (i = 1; i < o_size; i++) {
172  denom = knots[ i + order - 1] - knots[i];
173  for (k = 0; k < coords; k++) {
174  if (ZERO(denom))
175  n_pts[k] = 0.0;
176  else
177  n_pts[k] = (order - 1) *
178  (o_pts[k+o_stride] - o_pts[k]) /
179  denom;
180  }
181  n_pts += n_stride;
182  o_pts += o_stride;
183  }
184 }
185 
186 
187 /*
188  * Local Variables:
189  * mode: C
190  * tab-width: 8
191  * indent-tabs-mode: t
192  * c-file-style: "stroustrup"
193  * End:
194  * ex: shiftwidth=4 tabstop=8
195  */
struct edge_g_cnurb * rt_nurb_new_cnurb(int order, int n_knots, int n_pts, int pt_type)
Definition: nurb_util.c:77
void rt_nurb_mesh_diff(int order, const fastf_t *o_pts, fastf_t *n_pts, const fastf_t *knots, int o_stride, int n_stride, int o_size, int pt_type)
Definition: nurb_diff.c:163
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
Header file for the BRL-CAD common definitions.
#define ZERO(val)
Definition: units.c:38
struct face_g_snurb * rt_nurb_s_diff(const struct face_g_snurb *srf, int dir)
Definition: nurb_diff.c:58
struct edge_g_cnurb * rt_nurb_c_diff(const struct edge_g_cnurb *crv)
Definition: nurb_diff.c:133
double fastf_t
Definition: defines.h:300