nurb_xsplit.c

Go to the documentation of this file.
00001 /*                   N U R B _ X S P L I T . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 1990-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup nurb */
00023 /*@{*/
00024 /** @file nurb_xsplit.c
00025  *      Subdivide a nurb surface by inserting a multiple knot of
00026  *      of the surface order in a given direction and return the
00027  *      resulting surfaces.
00028  *
00029  * Author-
00030  *      Paul Randal Stay
00031  *
00032  * Source
00033  *      SECAD/VLD Computing Consortium, Bldg 394
00034  *      The US Army Ballistic Research Laboratory
00035  *      Aberdeen Proving Ground, Maryland 21005
00036  */
00037 /*@}*/
00038 
00039 #include "common.h"
00040 
00041 
00042 
00043 #include <stdio.h>
00044 #include "machine.h"
00045 #include "vmath.h"
00046 #include "nmg.h"
00047 #include "raytrace.h"
00048 #include "nurb.h"
00049 
00050 /* Algorithm
00051  *
00052  *      Given a parametric direction (u or v) look at the direction
00053  * knot vector and insert a multiple knot of parametric direction surface
00054  * order. This is somewhat different than rt_nurb_split in that the surface is
00055  * give a parametric value at which to split the surface.
00056  * rt_nurb_kvmult does the right thing in inserting a multiple knot with the
00057  * correct amount. Separate the surface and return the two resulting surface.
00058  */
00059 
00060 struct face_g_snurb *
00061 rt_nurb_s_xsplit(struct face_g_snurb *srf, fastf_t param, int dir)
00062 {
00063         struct knot_vector new_kv;
00064         struct oslo_mat * oslo;
00065         int i;
00066         int k_index;
00067         struct face_g_snurb * srf1, * srf2;
00068 
00069         NMG_CK_SNURB(srf);
00070 
00071         if ( dir == RT_NURB_SPLIT_ROW )
00072         {
00073                 rt_nurb_kvmult(&new_kv, &srf->u, srf->order[0], param, (struct resource *)NULL);
00074 
00075                 k_index = srf->order[0];
00076 
00077                 oslo = ( struct oslo_mat *)
00078                         rt_nurb_calc_oslo( srf->order[RT_NURB_SPLIT_ROW], &srf->u, &new_kv, (struct resource *)NULL);
00079 
00080                 GET_SNURB(srf1);
00081                 srf1->order[0]  = srf->order[0];
00082                 srf1->order[1]  = srf->order[1];
00083                 srf1->dir = RT_NURB_SPLIT_ROW;
00084                 rt_nurb_kvextract(&srf1->u, &new_kv, 0, k_index + srf1->order[0], (struct resource *)NULL);
00085                 rt_nurb_kvcopy(&srf1->v, &srf->v, (struct resource *)NULL);
00086 
00087                 srf1->pt_type = srf->pt_type;
00088                 srf1->s_size[0] = srf1->v.k_size -
00089                         srf1->order[1];
00090                 srf1->s_size[1] = srf1->u.k_size -
00091                         srf1->order[0];
00092 
00093                 srf1->ctl_points = (fastf_t *)
00094                         bu_malloc( sizeof(fastf_t) * srf1->s_size[0] *
00095                                 srf1->s_size[1] *
00096                                 RT_NURB_EXTRACT_COORDS( srf1->pt_type),
00097                                 "rt_nurb_s_xsplit: srf1 row mesh control points");
00098 
00099                 GET_SNURB(srf2);
00100                 srf2->order[0]  = srf->order[0];
00101                 srf2->order[1]  = srf->order[1];
00102                 srf2->dir = RT_NURB_SPLIT_ROW;
00103                 rt_nurb_kvextract(&srf2->u, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
00104                 rt_nurb_kvcopy(&srf2->v, &srf->v, (struct resource *)NULL);
00105 
00106                 srf2->pt_type = srf->pt_type;
00107                 srf2->s_size[0] = srf2->v.k_size -
00108                         srf2->order[1];
00109                 srf2->s_size[1] = srf2->u.k_size -
00110                         srf2->order[0];
00111 
00112                 srf2->ctl_points = (fastf_t *)
00113                         bu_malloc( sizeof(fastf_t) * srf2->s_size[0] *
00114                                 srf2->s_size[1] *
00115                                 RT_NURB_EXTRACT_COORDS( srf2->pt_type),
00116                                 "rt_nurb_s_xsplit: srf2 row mesh control points");
00117 
00118                 for( i = 0; i < srf->s_size[0]; i++)
00119                 {
00120                         fastf_t * old_mesh_ptr;
00121                         fastf_t * new_mesh_ptr;
00122 
00123                         old_mesh_ptr = &srf->ctl_points[
00124                                 i * srf->s_size[1] *
00125                                 RT_NURB_EXTRACT_COORDS( srf->pt_type)];
00126                         new_mesh_ptr = &srf1->ctl_points[
00127                                 i * srf1->s_size[1] *
00128                                 RT_NURB_EXTRACT_COORDS( srf1->pt_type)];
00129                         rt_nurb_map_oslo( oslo, old_mesh_ptr, new_mesh_ptr,
00130                                 RT_NURB_EXTRACT_COORDS( srf->pt_type ),
00131                                 RT_NURB_EXTRACT_COORDS( srf1->pt_type ),
00132                                 0, k_index, srf1->pt_type);
00133                         new_mesh_ptr = &srf2->ctl_points[
00134                                 i * srf2->s_size[1] *
00135                                 RT_NURB_EXTRACT_COORDS( srf2->pt_type)];
00136                         rt_nurb_map_oslo( oslo, old_mesh_ptr, new_mesh_ptr,
00137                                 RT_NURB_EXTRACT_COORDS( srf->pt_type ),
00138                                 RT_NURB_EXTRACT_COORDS( srf2->pt_type ),
00139                                 k_index, new_kv.k_size - srf2->order[0],
00140                                 srf2->pt_type);
00141                 }
00142         }
00143         else
00144         {
00145                 rt_nurb_kvmult(&new_kv, &srf->v, srf->order[RT_NURB_SPLIT_COL], param, (struct resource *)NULL);
00146 
00147                 k_index = srf->order[1];
00148 
00149                 oslo = ( struct oslo_mat *)
00150                         rt_nurb_calc_oslo( srf->order[RT_NURB_SPLIT_COL], &srf->v, &new_kv, (struct resource *)NULL);
00151 
00152                 GET_SNURB(srf1);
00153                 srf1->order[0]  = srf->order[0];
00154                 srf1->order[1]  = srf->order[1];
00155                 srf1->dir = RT_NURB_SPLIT_COL;
00156                 rt_nurb_kvextract(&srf1->v, &new_kv, 0, k_index + srf1->order[RT_NURB_SPLIT_COL], (struct resource *)NULL);
00157                 rt_nurb_kvcopy(&srf1->u, &srf->u, (struct resource *)NULL);
00158 
00159                 srf1->pt_type = srf->pt_type;
00160                 srf1->s_size[0] = srf1->v.k_size -
00161                         srf1->order[1];
00162                 srf1->s_size[1] = srf1->u.k_size -
00163                         srf1->order[0];
00164 
00165                 srf1->ctl_points = (fastf_t *)
00166                         bu_malloc( sizeof(fastf_t) * srf1->s_size[0] *
00167                                 srf1->s_size[1] *
00168                                 RT_NURB_EXTRACT_COORDS( srf1->pt_type),
00169                                 "rt_nurb_split: srf1 row mesh control points");
00170 
00171                 GET_SNURB(srf2);
00172                 srf2->order[0]  = srf->order[0];
00173                 srf2->order[1]  = srf->order[1];
00174                 srf2->dir = RT_NURB_SPLIT_COL;
00175                 rt_nurb_kvextract(&srf2->v, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
00176                 rt_nurb_kvcopy(&srf2->u, &srf->u, (struct resource *)NULL);
00177 
00178                 srf2->pt_type = srf->pt_type;
00179                 srf2->s_size[0] = srf2->v.k_size -
00180                         srf2->order[1];
00181                 srf2->s_size[1] = srf2->u.k_size -
00182                         srf2->order[0];
00183 
00184                 srf2->ctl_points = (fastf_t *)
00185                         bu_malloc( sizeof(fastf_t) * srf2->s_size[0] *
00186                                 srf2->s_size[1] *
00187                                 RT_NURB_EXTRACT_COORDS( srf2->pt_type),
00188                                 "rt_nurb_s_xsplit: srf2 row mesh control points");
00189 
00190                 for( i = 0; i < srf->s_size[1]; i++)
00191                 {
00192                         fastf_t * old_mesh_ptr;
00193                         fastf_t * new_mesh_ptr;
00194 
00195                         old_mesh_ptr = &srf->ctl_points[
00196                                 i * RT_NURB_EXTRACT_COORDS( srf->pt_type)];
00197                         new_mesh_ptr = &srf1->ctl_points[
00198                                 i * RT_NURB_EXTRACT_COORDS( srf1->pt_type)];
00199                         rt_nurb_map_oslo( oslo, old_mesh_ptr, new_mesh_ptr,
00200                                 srf->s_size[1] *
00201                                 RT_NURB_EXTRACT_COORDS( srf->pt_type ),
00202                                 srf1->s_size[1] *
00203                                 RT_NURB_EXTRACT_COORDS( srf1->pt_type ),
00204                                 0, k_index, srf1->pt_type);
00205                         new_mesh_ptr = &srf2->ctl_points[
00206                                 i * RT_NURB_EXTRACT_COORDS( srf2->pt_type)];
00207                         rt_nurb_map_oslo( oslo, old_mesh_ptr, new_mesh_ptr,
00208                                 srf->s_size[1] *
00209                                 RT_NURB_EXTRACT_COORDS( srf->pt_type ),
00210                                 srf2->s_size[1] *
00211                                 RT_NURB_EXTRACT_COORDS( srf2->pt_type ),
00212                                 k_index, new_kv.k_size - srf2->order[1],
00213                                 srf2->pt_type);
00214                 }
00215         }
00216 
00217         BU_LIST_APPEND( &srf1->l, &srf2->l );
00218 
00219         bu_free( (char *) new_kv.knots, "rt_nurb_s_xsplit: new_kv.knots");
00220 
00221         rt_nurb_free_oslo(oslo, (struct resource *)NULL);
00222 
00223         return srf1;
00224 }
00225 
00226 /* rt_nurb_c_xsplit()
00227  * Split a NURB curve by inserting a multiple knot and return
00228  * the result of the two curves.
00229  *
00230  * Algorithm
00231  *
00232  * Insert a multiple knot of the curve order. A parameter is give for the
00233  * knot value for which the curve will be split.
00234  */
00235 
00236 struct edge_g_cnurb *
00237 rt_nurb_c_xsplit(struct edge_g_cnurb *crv, fastf_t param)
00238 {
00239         struct knot_vector new_kv;
00240         struct oslo_mat * oslo;
00241         int k_index;
00242         struct edge_g_cnurb * crv1, * crv2;
00243         int coords;
00244 
00245         NMG_CK_CNURB(crv);
00246 
00247         coords = RT_NURB_EXTRACT_COORDS( crv->pt_type ),
00248 
00249         k_index = crv->order;
00250         rt_nurb_kvmult(&new_kv, &crv->k, crv->order, param, (struct resource *)NULL);
00251 
00252         oslo = ( struct oslo_mat *)
00253                 rt_nurb_calc_oslo( crv->order, &crv->k, &new_kv, (struct resource *)NULL);
00254 
00255         GET_CNURB(crv1);
00256         crv1->order  = crv->order;
00257         rt_nurb_kvextract(&crv1->k, &new_kv, 0, k_index + crv->order, (struct resource *)NULL);
00258         crv1->pt_type = crv->pt_type;
00259         crv1->c_size = crv1->k.k_size - crv1->order;
00260         crv1->ctl_points = (fastf_t *)
00261                 bu_malloc( sizeof(fastf_t) * crv1->c_size *
00262                         RT_NURB_EXTRACT_COORDS( crv1->pt_type),
00263                         "rt_nurb_c_xsplit: crv1 control points");
00264 
00265         GET_CNURB(crv2);
00266         crv2->order  = crv->order;
00267         rt_nurb_kvextract(&crv2->k, &new_kv, k_index, new_kv.k_size, (struct resource *)NULL);
00268         crv2->pt_type = crv->pt_type;
00269         crv2->c_size = crv2->k.k_size - crv2->order;
00270         crv2->ctl_points = (fastf_t *)
00271                 bu_malloc( sizeof(fastf_t) * crv2->c_size *
00272                         RT_NURB_EXTRACT_COORDS( crv2->pt_type),
00273                         "rt_nurb_c_xsplit: crv2 row mesh control points");
00274 
00275         rt_nurb_map_oslo( oslo, crv->ctl_points, crv1->ctl_points,
00276                 coords, coords, 0, k_index, crv->pt_type );
00277 
00278         rt_nurb_map_oslo( oslo, crv->ctl_points, crv2->ctl_points,
00279                 coords, coords, k_index, new_kv.k_size - crv2->order,
00280                 crv2->pt_type );
00281 
00282         rt_nurb_free_oslo( oslo, (struct resource *)NULL );
00283 
00284         bu_free( (char *) new_kv.knots, "rt_nurb_c_xsplit: new_kv.knots");
00285 
00286         BU_LIST_APPEND( &crv1->l, &crv2->l );
00287         return crv1;
00288 }
00289 
00290 /*
00291  * Local Variables:
00292  * mode: C
00293  * tab-width: 8
00294  * c-basic-offset: 4
00295  * indent-tabs-mode: t
00296  * End:
00297  * ex: shiftwidth=4 tabstop=8
00298  */

Generated on Mon Sep 18 01:24:56 2006 for BRL-CAD by  doxygen 1.4.6