nurb_xsplit.c
Go to the documentation of this file.
1 /* N U R B _ X S P L I T . C
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
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  */
21 /** @{ */
22 /** @file primitives/bspline/nurb_xsplit.c
23  *
24  * Subdivide a nurb surface by inserting a multiple knot of of the
25  * surface order in a given direction and return the resulting
26  * surfaces.
27  *
28  */
29 /** @} */
30
31 #include "common.h"
32
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  * Given a parametric direction (u or v) look at the direction knot
45  * vector and insert a multiple knot of parametric direction surface
46  * order. This is somewhat different than rt_nurb_split in that the
47  * surface is give a parametric value at which to split the surface.
48  * rt_nurb_kvmult does the right thing in inserting a multiple knot
49  * with the correct amount. Separate the surface and return the two
50  * resulting surface.
51  */
52 struct face_g_snurb *
53 rt_nurb_s_xsplit(struct face_g_snurb *srf, fastf_t param, int dir)
54 {
55  struct knot_vector new_kv;
56  struct oslo_mat * oslo;
57  int i;
58  int k_index;
59  struct face_g_snurb * srf1, * srf2;
60
61  NMG_CK_SNURB(srf);
62
63  if (dir == RT_NURB_SPLIT_ROW) {
64  rt_nurb_kvmult(&new_kv, &srf->u, srf->order[0], param, (struct resource *)NULL);
65
66  k_index = srf->order[0];
67
68  oslo = (struct oslo_mat *)
69  rt_nurb_calc_oslo(srf->order[RT_NURB_SPLIT_ROW], &srf->u, &new_kv, (struct resource *)NULL);
70
71  GET_SNURB(srf1);
72  srf1->order[0] = srf->order[0];
73  srf1->order[1] = srf->order[1];
74  srf1->dir = RT_NURB_SPLIT_ROW;
75  rt_nurb_kvextract(&srf1->u, &new_kv, 0, k_index + srf1->order[0], (struct resource *)NULL);
76  rt_nurb_kvcopy(&srf1->v, &srf->v, (struct resource *)NULL);
77
78  srf1->pt_type = srf->pt_type;
79  srf1->s_size[0] = srf1->v.k_size -
80  srf1->order[1];
81  srf1->s_size[1] = srf1->u.k_size -
82  srf1->order[0];
83
84  srf1->ctl_points = (fastf_t *)
85  bu_malloc(sizeof(fastf_t) * srf1->s_size[0] *
86  srf1->s_size[1] *
87  RT_NURB_EXTRACT_COORDS(srf1->pt_type),
88  "rt_nurb_s_xsplit: srf1 row mesh control points");
89
90  GET_SNURB(srf2);
91  srf2->order[0] = srf->order[0];
92  srf2->order[1] = srf->order[1];
93  srf2->dir = RT_NURB_SPLIT_ROW;
94  rt_nurb_kvextract(&srf2->u, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
95  rt_nurb_kvcopy(&srf2->v, &srf->v, (struct resource *)NULL);
96
97  srf2->pt_type = srf->pt_type;
98  srf2->s_size[0] = srf2->v.k_size -
99  srf2->order[1];
100  srf2->s_size[1] = srf2->u.k_size -
101  srf2->order[0];
102
103  srf2->ctl_points = (fastf_t *)
104  bu_malloc(sizeof(fastf_t) * srf2->s_size[0] *
105  srf2->s_size[1] *
106  RT_NURB_EXTRACT_COORDS(srf2->pt_type),
107  "rt_nurb_s_xsplit: srf2 row mesh control points");
108
109  for (i = 0; i < srf->s_size[0]; i++) {
110  fastf_t * old_mesh_ptr;
111  fastf_t * new_mesh_ptr;
112
113  old_mesh_ptr = &srf->ctl_points[
114  i * srf->s_size[1] *
115  RT_NURB_EXTRACT_COORDS(srf->pt_type)];
116  new_mesh_ptr = &srf1->ctl_points[
117  i * srf1->s_size[1] *
118  RT_NURB_EXTRACT_COORDS(srf1->pt_type)];
119  rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
120  RT_NURB_EXTRACT_COORDS(srf->pt_type),
121  RT_NURB_EXTRACT_COORDS(srf1->pt_type),
122  0, k_index, srf1->pt_type);
123  new_mesh_ptr = &srf2->ctl_points[
124  i * srf2->s_size[1] *
125  RT_NURB_EXTRACT_COORDS(srf2->pt_type)];
126  rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
127  RT_NURB_EXTRACT_COORDS(srf->pt_type),
128  RT_NURB_EXTRACT_COORDS(srf2->pt_type),
129  k_index, new_kv.k_size - srf2->order[0],
130  srf2->pt_type);
131  }
132  } else {
133  rt_nurb_kvmult(&new_kv, &srf->v, srf->order[RT_NURB_SPLIT_COL], param, (struct resource *)NULL);
134
135  k_index = srf->order[1];
136
137  oslo = (struct oslo_mat *)
138  rt_nurb_calc_oslo(srf->order[RT_NURB_SPLIT_COL], &srf->v, &new_kv, (struct resource *)NULL);
139
140  GET_SNURB(srf1);
141  srf1->order[0] = srf->order[0];
142  srf1->order[1] = srf->order[1];
143  srf1->dir = RT_NURB_SPLIT_COL;
144  rt_nurb_kvextract(&srf1->v, &new_kv, 0, k_index + srf1->order[RT_NURB_SPLIT_COL], (struct resource *)NULL);
145  rt_nurb_kvcopy(&srf1->u, &srf->u, (struct resource *)NULL);
146
147  srf1->pt_type = srf->pt_type;
148  srf1->s_size[0] = srf1->v.k_size -
149  srf1->order[1];
150  srf1->s_size[1] = srf1->u.k_size -
151  srf1->order[0];
152
153  srf1->ctl_points = (fastf_t *)
154  bu_malloc(sizeof(fastf_t) * srf1->s_size[0] *
155  srf1->s_size[1] *
156  RT_NURB_EXTRACT_COORDS(srf1->pt_type),
157  "rt_nurb_split: srf1 row mesh control points");
158
159  GET_SNURB(srf2);
160  srf2->order[0] = srf->order[0];
161  srf2->order[1] = srf->order[1];
162  srf2->dir = RT_NURB_SPLIT_COL;
163  rt_nurb_kvextract(&srf2->v, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
164  rt_nurb_kvcopy(&srf2->u, &srf->u, (struct resource *)NULL);
165
166  srf2->pt_type = srf->pt_type;
167  srf2->s_size[0] = srf2->v.k_size -
168  srf2->order[1];
169  srf2->s_size[1] = srf2->u.k_size -
170  srf2->order[0];
171
172  srf2->ctl_points = (fastf_t *)
173  bu_malloc(sizeof(fastf_t) * srf2->s_size[0] *
174  srf2->s_size[1] *
175  RT_NURB_EXTRACT_COORDS(srf2->pt_type),
176  "rt_nurb_s_xsplit: srf2 row mesh control points");
177
178  for (i = 0; i < srf->s_size[1]; i++) {
179  fastf_t * old_mesh_ptr;
180  fastf_t * new_mesh_ptr;
181
182  old_mesh_ptr = &srf->ctl_points[
183  i * RT_NURB_EXTRACT_COORDS(srf->pt_type)];
184  new_mesh_ptr = &srf1->ctl_points[
185  i * RT_NURB_EXTRACT_COORDS(srf1->pt_type)];
186  rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
187  srf->s_size[1] *
188  RT_NURB_EXTRACT_COORDS(srf->pt_type),
189  srf1->s_size[1] *
190  RT_NURB_EXTRACT_COORDS(srf1->pt_type),
191  0, k_index, srf1->pt_type);
192  new_mesh_ptr = &srf2->ctl_points[
193  i * RT_NURB_EXTRACT_COORDS(srf2->pt_type)];
194  rt_nurb_map_oslo(oslo, old_mesh_ptr, new_mesh_ptr,
195  srf->s_size[1] *
196  RT_NURB_EXTRACT_COORDS(srf->pt_type),
197  srf2->s_size[1] *
198  RT_NURB_EXTRACT_COORDS(srf2->pt_type),
199  k_index, new_kv.k_size - srf2->order[1],
200  srf2->pt_type);
201  }
202  }
203
204  BU_LIST_APPEND(&srf1->l, &srf2->l);
205
206  bu_free((char *) new_kv.knots, "rt_nurb_s_xsplit: new_kv.knots");
207
208  rt_nurb_free_oslo(oslo, (struct resource *)NULL);
209
210  return srf1;
211 }
212
213
214 /**
215  * rt_nurb_c_xsplit()
216  *
217  * Split a NURB curve by inserting a multiple knot and return the
218  * result of the two curves.
219  *
220  * Algorithm:
221  *
222  * Insert a multiple knot of the curve order. A parameter is give for
223  * the knot value for which the curve will be split.
224  */
225 struct edge_g_cnurb *
226 rt_nurb_c_xsplit(struct edge_g_cnurb *crv, fastf_t param)
227 {
228  struct knot_vector new_kv;
229  struct oslo_mat * oslo;
230  int k_index;
231  struct edge_g_cnurb * crv1, * crv2;
232  int coords;
233
234  NMG_CK_CNURB(crv);
235
236  coords = RT_NURB_EXTRACT_COORDS(crv->pt_type),
237
238  k_index = crv->order;
239  rt_nurb_kvmult(&new_kv, &crv->k, crv->order, param, (struct resource *)NULL);
240
241  oslo = (struct oslo_mat *)
242  rt_nurb_calc_oslo(crv->order, &crv->k, &new_kv, (struct resource *)NULL);
243
244  GET_CNURB(crv1);
245  crv1->order = crv->order;
246  rt_nurb_kvextract(&crv1->k, &new_kv, 0, k_index + crv->order, (struct resource *)NULL);
247  crv1->pt_type = crv->pt_type;
248  crv1->c_size = crv1->k.k_size - crv1->order;
249  crv1->ctl_points = (fastf_t *)
250  bu_malloc(sizeof(fastf_t) * crv1->c_size *
251  RT_NURB_EXTRACT_COORDS(crv1->pt_type),
252  "rt_nurb_c_xsplit: crv1 control points");
253
254  GET_CNURB(crv2);
255  crv2->order = crv->order;
256  rt_nurb_kvextract(&crv2->k, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
257  crv2->pt_type = crv->pt_type;
258  crv2->c_size = crv2->k.k_size - crv2->order;
259  crv2->ctl_points = (fastf_t *)
260  bu_malloc(sizeof(fastf_t) * crv2->c_size *
261  RT_NURB_EXTRACT_COORDS(crv2->pt_type),
262  "rt_nurb_c_xsplit: crv2 row mesh control points");
263
264  rt_nurb_map_oslo(oslo, crv->ctl_points, crv1->ctl_points,
265  coords, coords, 0, k_index, crv->pt_type);
266
267  rt_nurb_map_oslo(oslo, crv->ctl_points, crv2->ctl_points,
268  coords, coords, k_index, new_kv.k_size - crv2->order,
269  crv2->pt_type);
270
271  rt_nurb_free_oslo(oslo, (struct resource *)NULL);
272
273  bu_free((char *) new_kv.knots, "rt_nurb_c_xsplit: new_kv.knots");
274
275  BU_LIST_APPEND(&crv1->l, &crv2->l);
276  return crv1;
277 }
278
279
280 /*
281  * Local Variables:
282  * mode: C
283  * tab-width: 8
284  * indent-tabs-mode: t
285  * c-file-style: "stroustrup"
286  * End:
287  * ex: shiftwidth=4 tabstop=8
288  */
struct face_g_snurb * rt_nurb_s_xsplit(struct face_g_snurb *srf, fastf_t param, int dir)
Definition: nurb_xsplit.c:53
void rt_nurb_map_oslo(struct oslo_mat *oslo, fastf_t *old_pts, fastf_t *new_pts, int o_stride, int n_stride, int lower, int upper, int pt_type)
Definition: oslo_map.c:45
#define BU_LIST_APPEND(old, new)
Definition: list.h:197
void rt_nurb_kvmult(struct knot_vector *new_kv, const struct knot_vector *kv, int num, register fastf_t val, struct resource *res)
Definition: nurb_knot.c:83
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
void rt_nurb_free_oslo(struct oslo_mat *om, struct resource *res)
Definition: oslo_calc.c:214
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
void rt_nurb_kvcopy(struct knot_vector *new_kv, register const struct knot_vector *old_kv, struct resource *res)
Definition: nurb_knot.c:227
void rt_nurb_kvextract(struct knot_vector *new_kv, register const struct knot_vector *kv, int lower, int upper, struct resource *res)
Definition: nurb_knot.c:202
struct edge_g_cnurb * rt_nurb_c_xsplit(struct edge_g_cnurb *crv, fastf_t param)
Definition: nurb_xsplit.c:226
double fastf_t
Definition: defines.h:300
struct oslo_mat * rt_nurb_calc_oslo(register int order, register const struct knot_vector *tau_kv, register struct knot_vector *t_kv, struct resource *res)
Definition: oslo_calc.c:51