00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef lint
00037 static const char RCSsketch[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/g_sketch.c,v 14.16 2006/09/16 02:04:24 lbutler Exp $ (BRL)";
00038 #endif
00039
00040 #include "common.h"
00041
00042 #include <stdlib.h>
00043 #include <stdio.h>
00044 #ifdef HAVE_STRING_H
00045 # include <string.h>
00046 #else
00047 # include <strings.h>
00048 #endif
00049 #include <math.h>
00050 #include <ctype.h>
00051
00052 #include "tcl.h"
00053 #include "machine.h"
00054 #include "vmath.h"
00055 #include "db.h"
00056 #include "nmg.h"
00057 #include "raytrace.h"
00058 #include "nurb.h"
00059 #include "rtgeom.h"
00060 #include "./debug.h"
00061
00062
00063 fastf_t rt_cnurb_par_edge(const struct edge_g_cnurb *crv, fastf_t epsilon);
00064 extern void get_indices( genptr_t seg, int *start, int *end );
00065
00066 int
00067 rt_check_curve(struct curve *crv, struct rt_sketch_internal *skt, int noisey)
00068 {
00069 int i, j;
00070 int ret=0;
00071
00072 for( i=0 ; i<crv->seg_count ; i++ )
00073 {
00074 struct line_seg *lsg;
00075 struct carc_seg *csg;
00076 struct nurb_seg *nsg;
00077 struct bezier_seg *bsg;
00078 long *lng;
00079
00080 lng = (long *)crv->segments[i];
00081
00082 switch( *lng )
00083 {
00084 case CURVE_LSEG_MAGIC:
00085 lsg = (struct line_seg *)lng;
00086 if( lsg->start >= skt->vert_count ||
00087 lsg->end >= skt->vert_count )
00088 ret++;
00089 break;
00090 case CURVE_CARC_MAGIC:
00091 csg = (struct carc_seg *)lng;
00092 if( csg->start >= skt->vert_count ||
00093 csg->end >= skt->vert_count )
00094 ret++;
00095 break;
00096 case CURVE_NURB_MAGIC:
00097 nsg = (struct nurb_seg *)lng;
00098 for( j=0 ; j<nsg->c_size ; j++ )
00099 {
00100 if( nsg->ctl_points[j] >= skt->vert_count )
00101 {
00102 ret++;
00103 break;
00104 }
00105 }
00106 break;
00107 case CURVE_BEZIER_MAGIC:
00108 bsg = (struct bezier_seg *)lng;
00109 for( j=0 ; j<=bsg->degree ; j++ ) {
00110 if( bsg->ctl_points[j] >= skt->vert_count ) {
00111 ret++;
00112 break;
00113 }
00114 }
00115 break;
00116 default:
00117 ret++;
00118 if( noisey )
00119 bu_log( "Unrecognized segment type in sketch\n");
00120 break;
00121 }
00122 }
00123 if( ret && noisey )
00124 bu_log( "sketch references non-existent vertices!!!\n" );
00125 return( ret );
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 int
00145 rt_sketch_prep(struct soltab *stp, struct rt_db_internal *ip, struct rt_i *rtip)
00146 {
00147 stp->st_specific = (genptr_t)NULL;
00148 return( 0 );
00149 }
00150
00151
00152
00153
00154
00155 void
00156 rt_sketch_print(register const struct soltab *stp)
00157 {
00158 }
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 int
00172 rt_sketch_shot(struct soltab *stp, register struct xray *rp, struct application *ap, struct seg *seghead)
00173 {
00174 return(0);
00175 }
00176
00177 #define RT_SKETCH_SEG_MISS(SEG) (SEG).seg_stp=RT_SOLTAB_NULL
00178
00179
00180
00181
00182
00183
00184
00185 void
00186 rt_sketch_vshot(struct soltab **stp, struct xray **rp, struct seg *segp, int n, struct application *ap)
00187
00188
00189
00190
00191
00192 {
00193 rt_vstub( stp, rp, segp, n, ap );
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 void
00203 rt_sketch_norm(register struct hit *hitp, struct soltab *stp, register struct xray *rp)
00204 {
00205
00206 VJOIN1( hitp->hit_point, rp->r_pt, hitp->hit_dist, rp->r_dir );
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 void
00216 rt_sketch_curve(register struct curvature *cvp, register struct hit *hitp, struct soltab *stp)
00217 {
00218 cvp->crv_c1 = cvp->crv_c2 = 0;
00219
00220
00221 bn_vec_ortho( cvp->crv_pdir, hitp->hit_normal );
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 void
00234 rt_sketch_uv(struct application *ap, struct soltab *stp, register struct hit *hitp, register struct uvcoord *uvp)
00235 {
00236 }
00237
00238
00239
00240
00241
00242 void
00243 rt_sketch_free(register struct soltab *stp)
00244 {
00245 }
00246
00247
00248
00249
00250
00251 int
00252 rt_sketch_class(void)
00253 {
00254 return(0);
00255 }
00256
00257 int
00258 seg_to_vlist(struct bu_list *vhead, const struct rt_tess_tol *ttol, fastf_t *V, fastf_t *u_vec, fastf_t *v_vec, struct rt_sketch_internal *sketch_ip, genptr_t seg)
00259 {
00260 int ret=0;
00261 int i;
00262 long *lng;
00263 struct line_seg *lsg;
00264 struct carc_seg *csg;
00265 struct nurb_seg *nsg;
00266 struct bezier_seg *bsg;
00267 fastf_t delta;
00268 point_t center, start_pt;
00269 fastf_t pt[4];
00270 vect_t semi_a, semi_b;
00271 fastf_t radius;
00272 vect_t norm;
00273
00274 lng = (long *)seg;
00275 switch( *lng )
00276 {
00277 case CURVE_LSEG_MAGIC:
00278 lsg = (struct line_seg *)lng;
00279 if( lsg->start >= sketch_ip->vert_count ||
00280 lsg->end >= sketch_ip->vert_count )
00281 {
00282 ret++;
00283 break;
00284 }
00285 VJOIN2( pt, V, sketch_ip->verts[lsg->start][0], u_vec, sketch_ip->verts[lsg->start][1], v_vec);
00286 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_MOVE )
00287 VJOIN2( pt, V, sketch_ip->verts[lsg->end][0], u_vec, sketch_ip->verts[lsg->end][1], v_vec);
00288 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_DRAW );
00289 break;
00290 case CURVE_CARC_MAGIC:
00291 {
00292 point2d_t mid_pt, start2d, end2d, center2d, s2m, dir;
00293 fastf_t s2m_len_sq, len_sq, tmp_len, cross_z;
00294 fastf_t start_ang, end_ang, tot_ang, cosdel, sindel;
00295 fastf_t oldu, oldv, newu, newv;
00296 int nsegs;
00297
00298 csg = (struct carc_seg *)lng;
00299 if( csg->start >= sketch_ip->vert_count ||
00300 csg->end >= sketch_ip->vert_count )
00301 {
00302 ret++;
00303 break;
00304 }
00305
00306 delta = M_PI/4.0;
00307 if( csg->radius <= 0.0 )
00308 {
00309 VJOIN2( center, V, sketch_ip->verts[csg->end][0], u_vec, sketch_ip->verts[csg->end][1], v_vec);
00310 VJOIN2( pt, V, sketch_ip->verts[csg->start][0], u_vec, sketch_ip->verts[csg->start][1], v_vec);
00311 VSUB2( semi_a, pt, center );
00312 VCROSS( norm, u_vec, v_vec );
00313 VCROSS( semi_b, norm, semi_a );
00314 VUNITIZE( semi_b );
00315 radius = MAGNITUDE( semi_a );
00316 VSCALE( semi_b, semi_b, radius );
00317 }
00318 else if( csg->radius < SMALL_FASTF )
00319 {
00320 bu_log( "Radius too small in sketch!\n" );
00321 break;
00322 }
00323 else
00324 radius = csg->radius;
00325
00326 if( ttol->abs > 0.0 )
00327 {
00328 fastf_t tmp_delta, ratio;
00329
00330 ratio = ttol->abs / radius;
00331 if( ratio < 1.0 )
00332 {
00333 tmp_delta = 2.0 * acos( 1.0 - ratio);
00334 if( tmp_delta < delta )
00335 delta = tmp_delta;
00336 }
00337 }
00338 if( ttol->rel > 0.0 && ttol->rel < 1.0 )
00339 {
00340 fastf_t tmp_delta;
00341
00342 tmp_delta = 2.0 * acos( 1.0 - ttol->rel );
00343 if( tmp_delta < delta )
00344 delta = tmp_delta;
00345 }
00346 if( ttol->norm > 0.0 )
00347 {
00348 fastf_t norm;
00349
00350 norm = ttol->norm * M_PI / 180.0;
00351 if( norm < delta )
00352 delta = norm;
00353 }
00354 if( csg->radius <= 0.0 )
00355 {
00356
00357 nsegs = ceil( 2.0 * M_PI / delta );
00358 delta = 2.0 * M_PI / (double)nsegs;
00359 cosdel = cos( delta );
00360 sindel = sin( delta );
00361 oldu = 1.0;
00362 oldv = 0.0;
00363 VJOIN2( start_pt, center, oldu, semi_a, oldv, semi_b );
00364 RT_ADD_VLIST( vhead, start_pt, BN_VLIST_LINE_MOVE );
00365 for( i=1 ; i<nsegs ; i++ )
00366 {
00367 newu = oldu * cosdel - oldv * sindel;
00368 newv = oldu * sindel + oldv * cosdel;
00369 VJOIN2( pt, center, newu, semi_a, newv, semi_b );
00370 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_DRAW );
00371 oldu = newu;
00372 oldv = newv;
00373 }
00374 RT_ADD_VLIST( vhead, start_pt, BN_VLIST_LINE_DRAW );
00375 break;
00376 }
00377
00378
00379 V2MOVE( start2d, sketch_ip->verts[csg->start] );
00380 V2MOVE( end2d, sketch_ip->verts[csg->end] );
00381 mid_pt[0] = (start2d[0] + end2d[0]) * 0.5;
00382 mid_pt[1] = (start2d[1] + end2d[1]) * 0.5;
00383 V2SUB2( s2m, mid_pt, start2d )
00384 dir[0] = -s2m[1];
00385 dir[1] = s2m[0];
00386 s2m_len_sq = s2m[0]*s2m[0] + s2m[1]*s2m[1];
00387 if( s2m_len_sq < SMALL_FASTF )
00388 {
00389 bu_log( "start and end points are too close together in circular arc of sketch\n" );
00390 break;
00391 }
00392 len_sq = radius*radius - s2m_len_sq;
00393 if( len_sq < 0.0 )
00394 {
00395 bu_log( "Impossible radius for specified start and end points in circular arc\n");
00396 break;
00397 }
00398 tmp_len = sqrt( dir[0]*dir[0] + dir[1]*dir[1] );
00399 dir[0] = dir[0] / tmp_len;
00400 dir[1] = dir[1] / tmp_len;
00401 tmp_len = sqrt( len_sq );
00402 V2JOIN1( center2d, mid_pt, tmp_len, dir )
00403
00404
00405 cross_z = ( end2d[X] - start2d[X] )*( center2d[Y] - start2d[Y] ) -
00406 ( end2d[Y] - start2d[Y] )*( center2d[X] - start2d[X] );
00407 if( !(cross_z > 0.0 && csg->center_is_left) )
00408 V2JOIN1( center2d, mid_pt, -tmp_len, dir );
00409 start_ang = atan2( start2d[Y]-center2d[Y], start2d[X]-center2d[X] );
00410 end_ang = atan2( end2d[Y]-center2d[Y], end2d[X]-center2d[X] );
00411 if( csg->orientation )
00412 {
00413 while( end_ang > start_ang )
00414 end_ang -= 2.0 * M_PI;
00415 }
00416 else
00417 {
00418 while( end_ang < start_ang )
00419 end_ang += 2.0 * M_PI;
00420 }
00421 tot_ang = end_ang - start_ang;
00422 nsegs = ceil( tot_ang / delta );
00423 if( nsegs < 0 )
00424 nsegs = -nsegs;
00425 if( nsegs < 3 )
00426 nsegs = 3;
00427 delta = tot_ang / nsegs;
00428 cosdel = cos( delta );
00429 sindel = sin( delta );
00430 VJOIN2( center, V, center2d[0], u_vec, center2d[1], v_vec );
00431 VJOIN2( start_pt, V, start2d[0], u_vec, start2d[1], v_vec );
00432 oldu = (start2d[0] - center2d[0]);
00433 oldv = (start2d[1] - center2d[1]);
00434 RT_ADD_VLIST( vhead, start_pt, BN_VLIST_LINE_MOVE );
00435 for( i=0 ; i<nsegs ; i++ )
00436 {
00437 newu = oldu * cosdel - oldv * sindel;
00438 newv = oldu * sindel + oldv * cosdel;
00439 VJOIN2( pt, center, newu, u_vec, newv, v_vec );
00440 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_DRAW );
00441 oldu = newu;
00442 oldv = newv;
00443 }
00444 break;
00445 }
00446 case CURVE_NURB_MAGIC:
00447 {
00448 struct edge_g_cnurb eg;
00449 int coords;
00450 fastf_t inv_weight;
00451 int num_intervals;
00452 fastf_t param_delta, epsilon;
00453
00454 nsg = (struct nurb_seg *)lng;
00455 for( i=0 ; i<nsg->c_size ; i++ )
00456 {
00457 if( nsg->ctl_points[i] >= sketch_ip->vert_count )
00458 {
00459 ret++;
00460 break;
00461 }
00462 }
00463 if( nsg->order < 3 )
00464 {
00465
00466 VJOIN2( start_pt, V, sketch_ip->verts[nsg->ctl_points[0]][0], u_vec, sketch_ip->verts[nsg->ctl_points[0]][1], v_vec );
00467 if( RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) )
00468 {
00469 inv_weight = 1.0/nsg->weights[0];
00470 VSCALE( start_pt, start_pt, inv_weight );
00471 }
00472 RT_ADD_VLIST( vhead, start_pt, BN_VLIST_LINE_MOVE );
00473 for( i=1 ; i<nsg->c_size ; i++ )
00474 {
00475 VJOIN2( pt, V, sketch_ip->verts[nsg->ctl_points[i]][0], u_vec, sketch_ip->verts[nsg->ctl_points[i]][1], v_vec );
00476 if( RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) )
00477 {
00478 inv_weight = 1.0/nsg->weights[i];
00479 VSCALE( pt, pt, inv_weight );
00480 }
00481 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_DRAW );
00482 }
00483 break;
00484 }
00485 eg.l.magic = NMG_EDGE_G_CNURB_MAGIC;
00486 eg.order = nsg->order;
00487 eg.k.k_size = nsg->k.k_size;
00488 eg.k.knots = nsg->k.knots;
00489 eg.c_size = nsg->c_size;
00490 coords = 3 + RT_NURB_IS_PT_RATIONAL( nsg->pt_type );
00491 eg.pt_type = RT_NURB_MAKE_PT_TYPE( coords, 2, RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) );
00492 eg.ctl_points = (fastf_t *)bu_malloc( nsg->c_size * coords * sizeof( fastf_t ), "eg.ctl_points" );
00493 if( RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) )
00494 {
00495 for( i=0 ; i<nsg->c_size ; i++ )
00496 {
00497 VJOIN2( &eg.ctl_points[i*coords], V, sketch_ip->verts[nsg->ctl_points[i]][0], u_vec, sketch_ip->verts[nsg->ctl_points[i]][1], v_vec );
00498 eg.ctl_points[(i+1)*coords - 1] = nsg->weights[i];
00499 }
00500 }
00501 else
00502 {
00503 for( i=0 ; i<nsg->c_size ; i++ )
00504 VJOIN2( &eg.ctl_points[i*coords], V, sketch_ip->verts[nsg->ctl_points[i]][0], u_vec, sketch_ip->verts[nsg->ctl_points[i]][1], v_vec );
00505 }
00506 epsilon = MAX_FASTF;
00507 if( ttol->abs > 0.0 && ttol->abs < epsilon )
00508 epsilon = ttol->abs;
00509 if( ttol->rel > 0.0 )
00510 {
00511 point2d_t min_pt, max_pt, tmp_pt;
00512 point2d_t diff;
00513 fastf_t tmp_epsilon;
00514
00515 min_pt[0] = MAX_FASTF;
00516 min_pt[1] = MAX_FASTF;
00517 max_pt[0] = -MAX_FASTF;
00518 max_pt[1] = -MAX_FASTF;
00519
00520 for( i=0 ; i<nsg->c_size ; i++ )
00521 {
00522 V2MOVE( tmp_pt, sketch_ip->verts[nsg->ctl_points[i]] );
00523 if( tmp_pt[0] > max_pt[0] )
00524 max_pt[0] = tmp_pt[0];
00525 if( tmp_pt[1] > max_pt[1] )
00526 max_pt[1] = tmp_pt[1];
00527 if( tmp_pt[0] < min_pt[0] )
00528 min_pt[0] = tmp_pt[0];
00529 if( tmp_pt[1] < min_pt[1] )
00530 min_pt[1] = tmp_pt[1];
00531 }
00532
00533 V2SUB2( diff, max_pt, min_pt )
00534 tmp_epsilon = ttol->rel * sqrt( MAG2SQ( diff ) );
00535 if( tmp_epsilon < epsilon )
00536 epsilon = tmp_epsilon;
00537
00538 }
00539 param_delta = rt_cnurb_par_edge( &eg, epsilon );
00540 num_intervals = ceil( (nsg->k.knots[nsg->k.k_size-1] - nsg->k.knots[0])/param_delta );
00541 if( num_intervals < 3 )
00542 num_intervals = 3;
00543 if( num_intervals > 500 )
00544 {
00545 bu_log( "num_intervals was %d, clamped to 500\n", num_intervals );
00546 num_intervals = 500;
00547 }
00548 param_delta = (nsg->k.knots[nsg->k.k_size-1] - nsg->k.knots[0])/(double)num_intervals;
00549 for( i=0 ; i<=num_intervals ; i++ )
00550 {
00551 fastf_t t;
00552 int j;
00553
00554 t = nsg->k.knots[0] + i*param_delta;
00555 rt_nurb_c_eval( &eg, t, pt );
00556 if( RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) )
00557 {
00558 for( j=0 ; j<coords-1 ; j++ )
00559 pt[j] /= pt[coords-1];
00560 }
00561 if( i == 0 )
00562 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_MOVE )
00563 else
00564 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_DRAW );
00565 }
00566 bu_free( (char *)eg.ctl_points, "eg.ctl_points" );
00567 break;
00568 }
00569 case CURVE_BEZIER_MAGIC: {
00570 struct bezier_2d_list *bezier_hd, *bz;
00571 fastf_t epsilon;
00572
00573 bsg = (struct bezier_seg *)lng;
00574
00575 for( i=0 ; i<=bsg->degree ; i++ ) {
00576 if( bsg->ctl_points[i] >= sketch_ip->vert_count ) {
00577 ret++;
00578 break;
00579 }
00580 }
00581
00582 if( bsg->degree < 1 ) {
00583 bu_log( "g_sketch: ERROR: Bezier curve with illegal degree (%d)\n",
00584 bsg->degree );
00585 ret++;
00586 break;
00587 }
00588
00589 if( bsg->degree == 1 ) {
00590
00591 VJOIN2( start_pt, V, sketch_ip->verts[bsg->ctl_points[0]][0],
00592 u_vec, sketch_ip->verts[bsg->ctl_points[0]][1], v_vec );
00593 RT_ADD_VLIST( vhead, start_pt, BN_VLIST_LINE_MOVE );
00594 for( i=1 ; i<=bsg->degree ; i++ ) {
00595 VJOIN2( pt, V, sketch_ip->verts[bsg->ctl_points[i]][0],
00596 u_vec, sketch_ip->verts[bsg->ctl_points[i]][1], v_vec );
00597 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_DRAW );
00598 }
00599 break;
00600 }
00601
00602
00603 epsilon = MAX_FASTF;
00604 if( ttol->abs > 0.0 && ttol->abs < epsilon )
00605 epsilon = ttol->abs;
00606 if( ttol->rel > 0.0 )
00607 {
00608 point2d_t min_pt, max_pt, tmp_pt;
00609 point2d_t diff;
00610 fastf_t tmp_epsilon;
00611
00612 min_pt[0] = MAX_FASTF;
00613 min_pt[1] = MAX_FASTF;
00614 max_pt[0] = -MAX_FASTF;
00615 max_pt[1] = -MAX_FASTF;
00616
00617 for( i=0 ; i<=bsg->degree ; i++ )
00618 {
00619 V2MOVE( tmp_pt, sketch_ip->verts[bsg->ctl_points[i]] );
00620 if( tmp_pt[0] > max_pt[0] )
00621 max_pt[0] = tmp_pt[0];
00622 if( tmp_pt[1] > max_pt[1] )
00623 max_pt[1] = tmp_pt[1];
00624 if( tmp_pt[0] < min_pt[0] )
00625 min_pt[0] = tmp_pt[0];
00626 if( tmp_pt[1] < min_pt[1] )
00627 min_pt[1] = tmp_pt[1];
00628 }
00629
00630 V2SUB2( diff, max_pt, min_pt )
00631 tmp_epsilon = ttol->rel * sqrt( MAG2SQ( diff ) );
00632 if( tmp_epsilon < epsilon )
00633 epsilon = tmp_epsilon;
00634
00635 }
00636
00637
00638
00639 bezier_hd = (struct bezier_2d_list *)bu_malloc( sizeof( struct bezier_2d_list ),
00640 "g_sketch.c: bezier_hd" );
00641 BU_LIST_INIT( &bezier_hd->l );
00642 bezier_hd->ctl = (point2d_t *)bu_calloc( bsg->degree + 1, sizeof( point2d_t ),
00643 "g_sketch.c: bezier_hd->ctl" );
00644 for( i=0 ; i<=bsg->degree ; i++ ) {
00645 V2MOVE( bezier_hd->ctl[i], sketch_ip->verts[bsg->ctl_points[i]] );
00646 }
00647
00648
00649 bezier_hd = subdivide_bezier( bezier_hd, bsg->degree, epsilon, 0 );
00650
00651
00652 bz = BU_LIST_FIRST( bezier_2d_list, &bezier_hd->l );
00653 VJOIN2( pt, V, bz->ctl[0][0], u_vec, bz->ctl[0][1], v_vec);
00654 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_MOVE );
00655
00656 while( BU_LIST_WHILE( bz, bezier_2d_list, &(bezier_hd->l) ) ) {
00657 BU_LIST_DEQUEUE( &bz->l );
00658 for( i=1 ; i<=bsg->degree ; i++ ) {
00659 VJOIN2( pt, V, bz->ctl[i][0], u_vec,
00660 bz->ctl[i][1], v_vec);
00661 RT_ADD_VLIST( vhead, pt, BN_VLIST_LINE_DRAW );
00662 }
00663 bu_free( (char *)bz->ctl, "g_sketch.c: bz->ctl" );
00664 bu_free( (char *)bz, "g_sketch.c: bz" );
00665 }
00666 bu_free( (char *)bezier_hd, "g_sketch.c: bezier_hd" );
00667 break;
00668 }
00669 default:
00670 bu_log( "seg_to_vlist: ERROR: unrecognized segment type!!!!\n" );
00671 break;
00672 }
00673
00674 return( ret );
00675 }
00676
00677
00678
00679
00680
00681 int
00682 curve_to_vlist(struct bu_list *vhead, const struct rt_tess_tol *ttol, fastf_t *V, fastf_t *u_vec, fastf_t *v_vec, struct rt_sketch_internal *sketch_ip, struct curve *crv)
00683 {
00684 int seg_no;
00685 int ret=0;
00686
00687 if( bu_debug&BU_DEBUG_MEM_CHECK )
00688 {
00689 bu_log( "Barrier check at start of curve_to_vlist():\n" );
00690 bu_mem_barriercheck();
00691 }
00692
00693 for( seg_no=0 ; seg_no < crv->seg_count ; seg_no++ )
00694 {
00695 ret += seg_to_vlist( vhead, ttol, V, u_vec, v_vec, sketch_ip, crv->segments[seg_no] );
00696 }
00697
00698 if( bu_debug&BU_DEBUG_MEM_CHECK )
00699 {
00700 bu_log( "Barrier check at end of curve_to_vlist():\n" );
00701 bu_mem_barriercheck();
00702 }
00703
00704 return( ret );
00705 }
00706
00707
00708
00709
00710
00711 int
00712 rt_sketch_plot(struct bu_list *vhead, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00713 {
00714 LOCAL struct rt_sketch_internal *sketch_ip;
00715 int ret;
00716 int myret=0;
00717
00718 RT_CK_DB_INTERNAL(ip);
00719 sketch_ip = (struct rt_sketch_internal *)ip->idb_ptr;
00720 RT_SKETCH_CK_MAGIC(sketch_ip);
00721
00722 if( (ret=curve_to_vlist( vhead, ttol, sketch_ip->V, sketch_ip->u_vec, sketch_ip->v_vec, sketch_ip, &sketch_ip->skt_curve )) )
00723 {
00724 myret--;
00725 bu_log( "WARNING: Errors in sketch (%d segments reference non-existent vertices)\n",
00726 ret );
00727 }
00728
00729 return( myret );
00730 }
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740 int
00741 rt_sketch_tess(struct nmgregion **r, struct model *m, struct rt_db_internal *ip, const struct rt_tess_tol *ttol, const struct bn_tol *tol)
00742 {
00743 return(-1);
00744 }
00745
00746
00747
00748
00749
00750
00751
00752
00753 int
00754 rt_sketch_import(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
00755 {
00756 LOCAL struct rt_sketch_internal *sketch_ip;
00757 union record *rp;
00758 vect_t v;
00759 int seg_no;
00760 unsigned char *ptr;
00761 struct curve *crv;
00762 int i;
00763
00764 BU_CK_EXTERNAL( ep );
00765 rp = (union record *)ep->ext_buf;
00766
00767 if( rp->u_id != DBID_SKETCH ) {
00768 bu_log("rt_sketch_import: defective record\n");
00769 return(-1);
00770 }
00771
00772 if( bu_debug&BU_DEBUG_MEM_CHECK )
00773 {
00774 bu_log( "Barrier check at start of sketch_import():\n" );
00775 bu_mem_barriercheck();
00776 }
00777
00778 RT_CK_DB_INTERNAL( ip );
00779 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
00780 ip->idb_type = ID_SKETCH;
00781 ip->idb_meth = &rt_functab[ID_SKETCH];
00782 ip->idb_ptr = bu_calloc( 1, sizeof(struct rt_sketch_internal), "rt_sketch_internal");
00783 sketch_ip = (struct rt_sketch_internal *)ip->idb_ptr;
00784 sketch_ip->magic = RT_SKETCH_INTERNAL_MAGIC;
00785
00786 ntohd( (unsigned char *)v, rp->skt.skt_V, 3 );
00787 MAT4X3PNT( sketch_ip->V, mat, v );
00788 ntohd( (unsigned char *)v, rp->skt.skt_uvec, 3 );
00789 MAT4X3VEC( sketch_ip->u_vec, mat, v );
00790 ntohd( (unsigned char *)v, rp->skt.skt_vvec, 3 );
00791 MAT4X3VEC( sketch_ip->v_vec, mat, v );
00792 sketch_ip->vert_count = bu_glong( rp->skt.skt_vert_count );
00793 sketch_ip->skt_curve.seg_count = bu_glong( rp->skt.skt_seg_count );
00794
00795 ptr = (unsigned char *)rp;
00796 ptr += sizeof( struct sketch_rec );
00797 if( sketch_ip->vert_count )
00798 sketch_ip->verts = (point2d_t *)bu_calloc( sketch_ip->vert_count, sizeof( point2d_t ), "sketch_ip->vert" );
00799 ntohd( (unsigned char *)sketch_ip->verts, ptr, sketch_ip->vert_count*2 );
00800 ptr += 16 * sketch_ip->vert_count;
00801
00802 if( sketch_ip->skt_curve.seg_count )
00803 sketch_ip->skt_curve.segments = (genptr_t *)bu_calloc( sketch_ip->skt_curve.seg_count, sizeof( genptr_t ), "segs" );
00804 else
00805 sketch_ip->skt_curve.segments = (genptr_t *)NULL;
00806 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
00807 {
00808 long magic;
00809 struct line_seg *lsg;
00810 struct carc_seg *csg;
00811 struct nurb_seg *nsg;
00812 struct bezier_seg *bsg;
00813 int i;
00814
00815 magic = bu_glong( ptr );
00816 ptr += 4;
00817 switch( magic )
00818 {
00819 case CURVE_LSEG_MAGIC:
00820 lsg = (struct line_seg *)bu_malloc( sizeof( struct line_seg ), "lsg" );
00821 lsg->magic = magic;
00822 lsg->start = bu_glong( ptr );
00823 ptr += 4;
00824 lsg->end = bu_glong( ptr );
00825 ptr += 4;
00826 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)lsg;
00827 break;
00828 case CURVE_CARC_MAGIC:
00829 csg = (struct carc_seg *)bu_malloc( sizeof( struct carc_seg ), "csg" );
00830 csg->magic = magic;
00831 csg->start = bu_glong( ptr );
00832 ptr += 4;
00833 csg->end = bu_glong( ptr );
00834 ptr += 4;
00835 csg->orientation = bu_glong( ptr );
00836 ptr += 4;
00837 csg->center_is_left = bu_glong( ptr );
00838 ptr += 4;
00839 ntohd( (unsigned char *)&csg->radius, ptr, 1 );
00840 ptr += 8;
00841 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)csg;
00842 break;
00843 case CURVE_NURB_MAGIC:
00844 nsg = (struct nurb_seg *)bu_malloc( sizeof( struct nurb_seg ), "nsg" );
00845 nsg->magic = magic;
00846 nsg->order = bu_glong( ptr );
00847 ptr += 4;
00848 nsg->pt_type = bu_glong( ptr );
00849 ptr += 4;
00850 nsg->k.k_size = bu_glong( ptr );
00851 ptr += 4;
00852 nsg->k.knots = (fastf_t *)bu_malloc( nsg->k.k_size * sizeof( fastf_t ), "nsg->k.knots" );
00853 ntohd( (unsigned char *)nsg->k.knots, ptr, nsg->k.k_size );
00854 ptr += 8 * nsg->k.k_size;
00855 nsg->c_size = bu_glong( ptr );
00856 ptr += 4;
00857 nsg->ctl_points = (int *)bu_malloc( nsg->c_size * sizeof( int ), "nsg->ctl_points" );
00858 for( i=0 ; i<nsg->c_size ; i++ )
00859 {
00860 nsg->ctl_points[i] = bu_glong( ptr );
00861 ptr += 4;
00862 }
00863 if( RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) )
00864 {
00865 nsg->weights = (fastf_t *)bu_malloc( nsg->c_size * sizeof( fastf_t ), "nsg->weights" );
00866 ntohd( (unsigned char *)nsg->weights, ptr, nsg->c_size );
00867 ptr += 8 * nsg->c_size;
00868 }
00869 else
00870 nsg->weights = (fastf_t *)NULL;
00871 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)nsg;
00872 break;
00873 case CURVE_BEZIER_MAGIC:
00874 bsg = (struct bezier_seg *)bu_malloc( sizeof( struct bezier_seg ), "bsg" );
00875 bsg->magic = magic;
00876 bsg->degree = bu_glong( ptr );
00877 ptr += 4;
00878 bsg->ctl_points = (int *)bu_calloc( bsg->degree + 1, sizeof( int ), "bsg->ctl_points" );
00879 for( i=0 ; i<=bsg->degree ; i++ ) {
00880 bsg->ctl_points[i] = bu_glong( ptr );
00881 ptr += 4;
00882 }
00883 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)bsg;
00884 break;
00885 default:
00886 bu_bomb( "rt_sketch_import: ERROR: unrecognized segment type!!!\n" );
00887 break;
00888 }
00889 }
00890
00891 crv = &sketch_ip->skt_curve;
00892
00893 crv->reverse = (int *)bu_calloc( crv->seg_count, sizeof(int), "crv->reverse" );
00894 for( i=0 ; i<crv->seg_count ; i++ )
00895 {
00896 crv->reverse[i] = bu_glong( ptr );
00897 ptr += 4;
00898 }
00899
00900 if( bu_debug&BU_DEBUG_MEM_CHECK )
00901 {
00902 bu_log( "Barrier check at end of sketch_import():\n" );
00903 bu_mem_barriercheck();
00904 }
00905
00906 return(0);
00907 }
00908
00909
00910
00911
00912
00913
00914
00915 int
00916 rt_sketch_export(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
00917 {
00918 struct rt_sketch_internal *sketch_ip;
00919 union record *rec;
00920 int i, seg_no, nbytes=0, ngran;
00921 vect_t tmp_vec;
00922 unsigned char *ptr;
00923
00924 RT_CK_DB_INTERNAL(ip);
00925 if( ip->idb_type != ID_SKETCH ) return(-1);
00926 sketch_ip = (struct rt_sketch_internal *)ip->idb_ptr;
00927 RT_SKETCH_CK_MAGIC(sketch_ip);
00928
00929 if( bu_debug&BU_DEBUG_MEM_CHECK )
00930 {
00931 bu_log( "Barrier check at start of sketch_export():\n" );
00932 bu_mem_barriercheck();
00933 }
00934
00935 BU_CK_EXTERNAL(ep);
00936
00937 nbytes = sizeof(union record);
00938 nbytes += sketch_ip->vert_count*(8*2);
00939
00940 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
00941 {
00942 long *lng;
00943 struct nurb_seg *nseg;
00944 struct bezier_seg *bseg;
00945
00946 lng = (long *)sketch_ip->skt_curve.segments[seg_no];
00947 switch( *lng )
00948 {
00949 case CURVE_LSEG_MAGIC:
00950 nbytes += 12;
00951 break;
00952 case CURVE_CARC_MAGIC:
00953 nbytes += 28;
00954 break;
00955 case CURVE_NURB_MAGIC:
00956 nseg = (struct nurb_seg *)lng;
00957 nbytes += 16 + sizeof( struct knot_vector) + nseg->k.k_size * 8 + nseg->c_size * 4;
00958 if( RT_NURB_IS_PT_RATIONAL( nseg->pt_type ) )
00959 nbytes += nseg->c_size * 8;
00960 break;
00961 case CURVE_BEZIER_MAGIC:
00962 bseg = (struct bezier_seg *)lng;
00963 nbytes += 8 + (bseg->degree + 1) * 4;
00964 break;
00965 default:
00966 bu_log( "rt_sketch_export: unsupported segement type (x%x)\n", *lng );
00967 bu_bomb( "rt_sketch_export: unsupported segement type\n" );
00968 }
00969 }
00970
00971 ngran = ceil((double)(nbytes + sizeof(union record)) / sizeof(union record));
00972 ep->ext_nbytes = ngran * sizeof(union record);
00973 ep->ext_buf = (genptr_t)bu_calloc( 1, ep->ext_nbytes, "sketch external");
00974
00975 rec = (union record *)ep->ext_buf;
00976
00977 rec->skt.skt_id = DBID_SKETCH;
00978
00979
00980
00981
00982 VSCALE( tmp_vec, sketch_ip->V, local2mm );
00983 htond( rec->skt.skt_V, (unsigned char *)tmp_vec, 3 );
00984
00985
00986 htond( rec->skt.skt_uvec, (unsigned char *)sketch_ip->u_vec, 3 );
00987 htond( rec->skt.skt_vvec, (unsigned char *)sketch_ip->v_vec, 3 );
00988
00989 (void)bu_plong( rec->skt.skt_vert_count, sketch_ip->vert_count );
00990 (void)bu_plong( rec->skt.skt_seg_count, sketch_ip->skt_curve.seg_count );
00991 (void)bu_plong( rec->skt.skt_count, ngran-1 );
00992
00993 ptr = (unsigned char *)rec;
00994 ptr += sizeof( struct sketch_rec );
00995
00996 for( i=0 ; i<sketch_ip->vert_count ; i++ )
00997 {
00998 point2d_t pt2d;
00999
01000 V2SCALE( pt2d, sketch_ip->verts[i], local2mm )
01001 htond( ptr, (const unsigned char *)pt2d, 2 );
01002 ptr += 16;
01003 }
01004
01005 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
01006 {
01007 struct line_seg *lseg;
01008 struct carc_seg *cseg;
01009 struct nurb_seg *nseg;
01010 struct bezier_seg *bseg;
01011 long *lng;
01012 fastf_t tmp_fastf;
01013
01014
01015 lng = (long *)sketch_ip->skt_curve.segments[seg_no];
01016 switch (*lng )
01017 {
01018 case CURVE_LSEG_MAGIC:
01019 lseg = (struct line_seg *)lng;
01020 (void)bu_plong( ptr, CURVE_LSEG_MAGIC );
01021 ptr += 4;
01022 (void)bu_plong( ptr, lseg->start );
01023 ptr += 4;
01024 (void)bu_plong( ptr, lseg->end );
01025 ptr += 4;
01026 break;
01027 case CURVE_CARC_MAGIC:
01028 cseg = (struct carc_seg *)lng;
01029 (void)bu_plong( ptr, CURVE_CARC_MAGIC );
01030 ptr += 4;
01031 (void)bu_plong( ptr, cseg->start );
01032 ptr += 4;
01033 (void)bu_plong( ptr, cseg->end );
01034 ptr += 4;
01035 (void) bu_plong( ptr, cseg->orientation );
01036 ptr += 4;
01037 (void) bu_plong( ptr, cseg->center_is_left );
01038 ptr += 4;
01039 tmp_fastf = cseg->radius * local2mm;
01040 htond( ptr, (unsigned char *)&tmp_fastf, 1 );
01041 ptr += 8;
01042 break;
01043 case CURVE_NURB_MAGIC:
01044 nseg = (struct nurb_seg *)lng;
01045 (void)bu_plong( ptr, CURVE_NURB_MAGIC );
01046 ptr += 4;
01047 (void)bu_plong( ptr, nseg->order );
01048 ptr += 4;
01049 (void)bu_plong( ptr, nseg->pt_type );
01050 ptr += 4;
01051 (void)bu_plong( ptr, nseg->k.k_size );
01052 ptr += 4;
01053 htond( ptr, (const unsigned char *)nseg->k.knots, nseg->k.k_size );
01054 ptr += nseg->k.k_size * 8;
01055 (void)bu_plong( ptr, nseg->c_size );
01056 ptr += 4;
01057 for( i=0 ; i<nseg->c_size ; i++ )
01058 {
01059 (void)bu_plong( ptr, nseg->ctl_points[i] );
01060 ptr += 4;
01061 }
01062 if( RT_NURB_IS_PT_RATIONAL( nseg->pt_type ) )
01063 {
01064 htond( ptr, (const unsigned char *)nseg->weights, nseg->c_size );
01065 ptr += 8 * nseg->c_size;
01066 }
01067 break;
01068 case CURVE_BEZIER_MAGIC:
01069 bseg = (struct bezier_seg *)lng;
01070 (void)bu_plong( ptr, CURVE_BEZIER_MAGIC );
01071 ptr += 4;
01072 (void)bu_plong( ptr, bseg->degree );
01073 ptr += 4;
01074 for( i=0 ; i<=bseg->degree ; i++ ) {
01075 (void)bu_plong( ptr, bseg->ctl_points[i] );
01076 ptr += 4;
01077 }
01078 break;
01079 default:
01080 bu_bomb( "rt_sketch_export: ERROR: unrecognized curve type!!!!\n" );
01081 break;
01082
01083 }
01084 }
01085
01086 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
01087 {
01088 (void)bu_plong( ptr, sketch_ip->skt_curve.reverse[seg_no] );
01089 ptr += 4;
01090 }
01091 if( bu_debug&BU_DEBUG_MEM_CHECK )
01092 {
01093 bu_log( "Barrier check at end of sketch_export():\n" );
01094 bu_mem_barriercheck();
01095 }
01096
01097 return(0);
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107 int
01108 rt_sketch_import5(struct rt_db_internal *ip, const struct bu_external *ep, register const fastf_t *mat, const struct db_i *dbip)
01109 {
01110 LOCAL struct rt_sketch_internal *sketch_ip;
01111 vect_t v;
01112 int seg_no;
01113 unsigned char *ptr;
01114 struct curve *crv;
01115 int i;
01116
01117 BU_CK_EXTERNAL( ep );
01118
01119 if( bu_debug&BU_DEBUG_MEM_CHECK )
01120 {
01121 bu_log( "Barrier check at start of sketch_import5():\n" );
01122 bu_mem_barriercheck();
01123 }
01124
01125 RT_CK_DB_INTERNAL( ip );
01126 ip->idb_major_type = DB5_MAJORTYPE_BRLCAD;
01127 ip->idb_type = ID_SKETCH;
01128 ip->idb_meth = &rt_functab[ID_SKETCH];
01129 ip->idb_ptr = bu_calloc( 1, sizeof(struct rt_sketch_internal), "rt_sketch_internal");
01130 sketch_ip = (struct rt_sketch_internal *)ip->idb_ptr;
01131 sketch_ip->magic = RT_SKETCH_INTERNAL_MAGIC;
01132
01133 ptr = ep->ext_buf;
01134 ntohd( (unsigned char *)v, ptr, 3 );
01135 MAT4X3PNT( sketch_ip->V, mat, v );
01136 ptr += SIZEOF_NETWORK_DOUBLE * 3;
01137 ntohd( (unsigned char *)v, ptr, 3 );
01138 MAT4X3VEC( sketch_ip->u_vec, mat, v );
01139 ptr += SIZEOF_NETWORK_DOUBLE * 3;
01140 ntohd( (unsigned char *)v, ptr, 3 );
01141 MAT4X3VEC( sketch_ip->v_vec, mat, v );
01142 ptr += SIZEOF_NETWORK_DOUBLE * 3;
01143 sketch_ip->vert_count = bu_glong( ptr );
01144 ptr += SIZEOF_NETWORK_LONG;
01145 sketch_ip->skt_curve.seg_count = bu_glong( ptr );
01146 ptr += SIZEOF_NETWORK_LONG;
01147
01148 if( sketch_ip->vert_count )
01149 sketch_ip->verts = (point2d_t *)bu_calloc( sketch_ip->vert_count, sizeof( point2d_t ), "sketch_ip->vert" );
01150 ntohd( (unsigned char *)sketch_ip->verts, ptr, sketch_ip->vert_count*2 );
01151 ptr += SIZEOF_NETWORK_DOUBLE * 2 * sketch_ip->vert_count;
01152
01153 if( sketch_ip->skt_curve.seg_count )
01154 sketch_ip->skt_curve.segments = (genptr_t *)bu_calloc( sketch_ip->skt_curve.seg_count, sizeof( genptr_t ), "segs" );
01155 else
01156 sketch_ip->skt_curve.segments = (genptr_t *)NULL;
01157 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
01158 {
01159 long magic;
01160 struct line_seg *lsg;
01161 struct carc_seg *csg;
01162 struct nurb_seg *nsg;
01163 struct bezier_seg *bsg;
01164 int i;
01165
01166 magic = bu_glong( ptr );
01167 ptr += SIZEOF_NETWORK_LONG;
01168 switch( magic )
01169 {
01170 case CURVE_LSEG_MAGIC:
01171 lsg = (struct line_seg *)bu_malloc( sizeof( struct line_seg ), "lsg" );
01172 lsg->magic = magic;
01173 lsg->start = bu_glong( ptr );
01174 ptr += SIZEOF_NETWORK_LONG;
01175 lsg->end = bu_glong( ptr );
01176 ptr += SIZEOF_NETWORK_LONG;
01177 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)lsg;
01178 break;
01179 case CURVE_CARC_MAGIC:
01180 csg = (struct carc_seg *)bu_malloc( sizeof( struct carc_seg ), "csg" );
01181 csg->magic = magic;
01182 csg->start = bu_glong( ptr );
01183 ptr += SIZEOF_NETWORK_LONG;
01184 csg->end = bu_glong( ptr );
01185 ptr += SIZEOF_NETWORK_LONG;
01186 csg->orientation = bu_glong( ptr );
01187 ptr += SIZEOF_NETWORK_LONG;
01188 csg->center_is_left = bu_glong( ptr );
01189 ptr += SIZEOF_NETWORK_LONG;
01190 ntohd( (unsigned char *)&csg->radius, ptr, 1 );
01191 ptr += SIZEOF_NETWORK_DOUBLE;
01192 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)csg;
01193 break;
01194 case CURVE_NURB_MAGIC:
01195 nsg = (struct nurb_seg *)bu_malloc( sizeof( struct nurb_seg ), "nsg" );
01196 nsg->magic = magic;
01197 nsg->order = bu_glong( ptr );
01198 ptr += SIZEOF_NETWORK_LONG;
01199 nsg->pt_type = bu_glong( ptr );
01200 ptr += SIZEOF_NETWORK_LONG;
01201 nsg->k.k_size = bu_glong( ptr );
01202 ptr += SIZEOF_NETWORK_LONG;
01203 nsg->k.knots = (fastf_t *)bu_malloc( nsg->k.k_size * sizeof( fastf_t ), "nsg->k.knots" );
01204 ntohd( (unsigned char *)nsg->k.knots, ptr, nsg->k.k_size );
01205 ptr += SIZEOF_NETWORK_DOUBLE * nsg->k.k_size;
01206 nsg->c_size = bu_glong( ptr );
01207 ptr += SIZEOF_NETWORK_LONG;
01208 nsg->ctl_points = (int *)bu_malloc( nsg->c_size * sizeof( int ), "nsg->ctl_points" );
01209 for( i=0 ; i<nsg->c_size ; i++ )
01210 {
01211 nsg->ctl_points[i] = bu_glong( ptr );
01212 ptr += SIZEOF_NETWORK_LONG;
01213 }
01214 if( RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) )
01215 {
01216 nsg->weights = (fastf_t *)bu_malloc( nsg->c_size * sizeof( fastf_t ), "nsg->weights" );
01217 ntohd( (unsigned char *)nsg->weights, ptr, nsg->c_size );
01218 ptr += SIZEOF_NETWORK_DOUBLE * nsg->c_size;
01219 }
01220 else
01221 nsg->weights = (fastf_t *)NULL;
01222 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)nsg;
01223 break;
01224 case CURVE_BEZIER_MAGIC:
01225 bsg = (struct bezier_seg *)bu_malloc( sizeof( struct bezier_seg ), "bsg" );
01226 bsg->magic = magic;
01227 bsg->degree = bu_glong( ptr );
01228 ptr += SIZEOF_NETWORK_LONG;
01229 bsg->ctl_points = (int *)bu_calloc( bsg->degree+1, sizeof( int ), "bsg->ctl_points" );
01230 for( i=0 ; i<=bsg->degree ; i++ ) {
01231 bsg->ctl_points[i] = bu_glong( ptr );
01232 ptr += SIZEOF_NETWORK_LONG;
01233 }
01234 sketch_ip->skt_curve.segments[seg_no] = (genptr_t)bsg;
01235 break;
01236 default:
01237 bu_bomb( "rt_sketch_import: ERROR: unrecognized segment type!!!\n" );
01238 break;
01239 }
01240 }
01241
01242 crv = &sketch_ip->skt_curve;
01243
01244 if (crv->seg_count) {
01245 crv->reverse = (int *)bu_calloc( crv->seg_count, sizeof(int), "crv->reverse" );
01246 }
01247
01248 for( i=0 ; i<crv->seg_count ; i++ )
01249 {
01250 crv->reverse[i] = bu_glong( ptr );
01251 ptr += SIZEOF_NETWORK_LONG;
01252 }
01253
01254 if( bu_debug&BU_DEBUG_MEM_CHECK )
01255 {
01256 bu_log( "Barrier check at end of sketch_import5():\n" );
01257 bu_mem_barriercheck();
01258 }
01259
01260 return(0);
01261 }
01262
01263
01264
01265
01266
01267
01268
01269 int
01270 rt_sketch_export5(struct bu_external *ep, const struct rt_db_internal *ip, double local2mm, const struct db_i *dbip)
01271 {
01272 struct rt_sketch_internal *sketch_ip;
01273 unsigned char *cp;
01274 int seg_no;
01275 int i;
01276 vect_t tmp_vec;
01277
01278 if( bu_debug&BU_DEBUG_MEM_CHECK )
01279 {
01280 bu_log( "Barrier check at start of sketch_export5():\n" );
01281 bu_mem_barriercheck();
01282 }
01283
01284 RT_CK_DB_INTERNAL(ip);
01285 if( ip->idb_type != ID_SKETCH ) return(-1);
01286 sketch_ip = (struct rt_sketch_internal *)ip->idb_ptr;
01287 RT_SKETCH_CK_MAGIC(sketch_ip);
01288
01289 BU_CK_EXTERNAL(ep);
01290
01291
01292 ep->ext_nbytes = 3 * (3 * SIZEOF_NETWORK_DOUBLE)
01293 + 2 * SIZEOF_NETWORK_LONG
01294 + 2 * sketch_ip->vert_count * SIZEOF_NETWORK_DOUBLE
01295 + sketch_ip->skt_curve.seg_count * SIZEOF_NETWORK_LONG;
01296
01297 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
01298 {
01299 long *lng;
01300 struct nurb_seg *nseg;
01301 struct bezier_seg *bseg;
01302
01303 lng = (long *)sketch_ip->skt_curve.segments[seg_no];
01304 switch( *lng )
01305 {
01306 case CURVE_LSEG_MAGIC:
01307 ep->ext_nbytes += 3 * SIZEOF_NETWORK_LONG;
01308 break;
01309 case CURVE_CARC_MAGIC:
01310 ep->ext_nbytes += 5 * SIZEOF_NETWORK_LONG + SIZEOF_NETWORK_DOUBLE;
01311 break;
01312 case CURVE_NURB_MAGIC:
01313 nseg = (struct nurb_seg *)lng;
01314 ep->ext_nbytes += 3 * SIZEOF_NETWORK_LONG;
01315 ep->ext_nbytes += SIZEOF_NETWORK_LONG + nseg->k.k_size * SIZEOF_NETWORK_DOUBLE;
01316 ep->ext_nbytes += nseg->c_size * SIZEOF_NETWORK_LONG;
01317 if( RT_NURB_IS_PT_RATIONAL( nseg->pt_type ) )
01318 ep->ext_nbytes += nseg->c_size * SIZEOF_NETWORK_DOUBLE;
01319 break;
01320 case CURVE_BEZIER_MAGIC:
01321 bseg = (struct bezier_seg *)lng;
01322 ep->ext_nbytes += (bseg->degree + 3) * SIZEOF_NETWORK_LONG;
01323 break;
01324 default:
01325 bu_log( "rt_sketch_export: unsupported segement type (x%x)\n", *lng );
01326 bu_bomb( "rt_sketch_export: unsupported segement type\n" );
01327 }
01328 }
01329 ep->ext_buf = (genptr_t)bu_malloc( ep->ext_nbytes, "sketch external");
01330
01331 cp = (unsigned char *)ep->ext_buf;
01332
01333
01334 VSCALE( tmp_vec, sketch_ip->V, local2mm );
01335 htond( cp, (unsigned char *)tmp_vec, 3 );
01336 cp += 3 * SIZEOF_NETWORK_DOUBLE;
01337
01338
01339 htond( cp, (unsigned char *)sketch_ip->u_vec, 3 );
01340 cp += 3 * SIZEOF_NETWORK_DOUBLE;
01341 htond( cp, (unsigned char *)sketch_ip->v_vec, 3 );
01342 cp += 3 * SIZEOF_NETWORK_DOUBLE;
01343
01344 (void)bu_plong( cp, sketch_ip->vert_count );
01345 cp += SIZEOF_NETWORK_LONG;
01346 (void)bu_plong( cp, sketch_ip->skt_curve.seg_count );
01347 cp += SIZEOF_NETWORK_LONG;
01348
01349
01350 for( i=0 ; i<sketch_ip->vert_count ; i++ )
01351 {
01352 point2d_t pt2d;
01353
01354 V2SCALE( pt2d, sketch_ip->verts[i], local2mm )
01355 htond( cp, (const unsigned char *)pt2d, 2 );
01356 cp += 2 * SIZEOF_NETWORK_DOUBLE;
01357 }
01358
01359 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
01360 {
01361 struct line_seg *lseg;
01362 struct carc_seg *cseg;
01363 struct nurb_seg *nseg;
01364 struct bezier_seg *bseg;
01365 long *lng;
01366 fastf_t tmp_fastf;
01367
01368
01369 lng = (long *)sketch_ip->skt_curve.segments[seg_no];
01370 switch (*lng )
01371 {
01372 case CURVE_LSEG_MAGIC:
01373 lseg = (struct line_seg *)lng;
01374 (void)bu_plong( cp, CURVE_LSEG_MAGIC );
01375 cp += SIZEOF_NETWORK_LONG;
01376 (void)bu_plong( cp, lseg->start );
01377 cp += SIZEOF_NETWORK_LONG;
01378 (void)bu_plong( cp, lseg->end );
01379 cp += SIZEOF_NETWORK_LONG;
01380 break;
01381 case CURVE_CARC_MAGIC:
01382 cseg = (struct carc_seg *)lng;
01383 (void)bu_plong( cp, CURVE_CARC_MAGIC );
01384 cp += SIZEOF_NETWORK_LONG;
01385 (void)bu_plong( cp, cseg->start );
01386 cp += SIZEOF_NETWORK_LONG;
01387 (void)bu_plong( cp, cseg->end );
01388 cp += SIZEOF_NETWORK_LONG;
01389 (void) bu_plong( cp, cseg->orientation );
01390 cp += SIZEOF_NETWORK_LONG;
01391 (void) bu_plong( cp, cseg->center_is_left );
01392 cp += SIZEOF_NETWORK_LONG;
01393 tmp_fastf = cseg->radius * local2mm;
01394 htond( cp, (unsigned char *)&tmp_fastf, 1 );
01395 cp += SIZEOF_NETWORK_DOUBLE;
01396 break;
01397 case CURVE_NURB_MAGIC:
01398 nseg = (struct nurb_seg *)lng;
01399 (void)bu_plong( cp, CURVE_NURB_MAGIC );
01400 cp += SIZEOF_NETWORK_LONG;
01401 (void)bu_plong( cp, nseg->order );
01402 cp += SIZEOF_NETWORK_LONG;
01403 (void)bu_plong( cp, nseg->pt_type );
01404 cp += SIZEOF_NETWORK_LONG;
01405 (void)bu_plong( cp, nseg->k.k_size );
01406 cp += SIZEOF_NETWORK_LONG;
01407 htond( cp, (const unsigned char *)nseg->k.knots, nseg->k.k_size );
01408 cp += nseg->k.k_size * SIZEOF_NETWORK_DOUBLE;
01409 (void)bu_plong( cp, nseg->c_size );
01410 cp += SIZEOF_NETWORK_LONG;
01411 for( i=0 ; i<nseg->c_size ; i++ )
01412 {
01413 (void)bu_plong( cp, nseg->ctl_points[i] );
01414 cp += SIZEOF_NETWORK_LONG;
01415 }
01416 if( RT_NURB_IS_PT_RATIONAL( nseg->pt_type ) )
01417 {
01418 htond( cp, (const unsigned char *)nseg->weights, nseg->c_size );
01419 cp += SIZEOF_NETWORK_DOUBLE * nseg->c_size;
01420 }
01421 break;
01422 case CURVE_BEZIER_MAGIC:
01423 bseg = (struct bezier_seg *)lng;
01424 (void)bu_plong( cp, CURVE_BEZIER_MAGIC );
01425 cp += SIZEOF_NETWORK_LONG;
01426 (void)bu_plong( cp, bseg->degree );
01427 cp += SIZEOF_NETWORK_LONG;
01428 for( i=0 ; i<=bseg->degree ; i++ ) {
01429 (void)bu_plong( cp, bseg->ctl_points[i] );
01430 cp += SIZEOF_NETWORK_LONG;
01431 }
01432 break;
01433 default:
01434 bu_bomb( "rt_sketch_export: ERROR: unrecognized curve type!!!!\n" );
01435 break;
01436
01437 }
01438 }
01439
01440 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
01441 {
01442 (void)bu_plong( cp, sketch_ip->skt_curve.reverse[seg_no] );
01443 cp += SIZEOF_NETWORK_LONG;
01444 }
01445
01446 if( bu_debug&BU_DEBUG_MEM_CHECK )
01447 {
01448 bu_log( "Barrier check at end of sketch_export5():\n" );
01449 bu_mem_barriercheck();
01450 }
01451
01452 return(0);
01453 }
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463 int
01464 rt_sketch_describe(struct bu_vls *str, const struct rt_db_internal *ip, int verbose, double mm2local)
01465 {
01466 register struct rt_sketch_internal *sketch_ip =
01467 (struct rt_sketch_internal *)ip->idb_ptr;
01468 int i;
01469 int seg_no;
01470 char buf[256];
01471 point_t V;
01472 vect_t u, v;
01473
01474 RT_SKETCH_CK_MAGIC(sketch_ip);
01475 bu_vls_strcat( str, "2D sketch (SKETCH)\n");
01476
01477 VSCALE( V, sketch_ip->V, mm2local );
01478 VSCALE( u, sketch_ip->u_vec, mm2local );
01479 VSCALE( v, sketch_ip->v_vec, mm2local );
01480
01481 sprintf(buf, "\tV = (%g %g %g), A = (%g %g %g), B = (%g %g %g)\n\t%d vertices\n",
01482 V3INTCLAMPARGS( V ),
01483 V3INTCLAMPARGS( u ),
01484 V3INTCLAMPARGS( v ),
01485 sketch_ip->vert_count );
01486 bu_vls_strcat( str, buf );
01487
01488 if( !verbose )
01489 return( 0 );
01490
01491 if( sketch_ip->vert_count )
01492 {
01493 bu_vls_strcat( str, "\tVertices:\n\t" );
01494 for( i=0 ; i<sketch_ip->vert_count ; i++ )
01495 {
01496 sprintf( buf, " %d-(%g %g)", i, V2INTCLAMPARGS( sketch_ip->verts[i] ) );
01497 bu_vls_strcat( str, buf );
01498 if( i && (i+1)%3 == 0 )
01499 bu_vls_strcat( str, "\n\t" );
01500 }
01501 }
01502 bu_vls_strcat( str, "\n" );
01503
01504 sprintf(buf, "\n\tCurve:\n" );
01505 bu_vls_strcat( str, buf );
01506 for( seg_no=0 ; seg_no < sketch_ip->skt_curve.seg_count ; seg_no++ )
01507 {
01508 struct line_seg *lsg;
01509 struct carc_seg *csg;
01510 struct nurb_seg *nsg;
01511 struct bezier_seg *bsg;
01512
01513 lsg = (struct line_seg *)sketch_ip->skt_curve.segments[seg_no];
01514 switch( lsg->magic )
01515 {
01516 case CURVE_LSEG_MAGIC:
01517 lsg = (struct line_seg *)sketch_ip->skt_curve.segments[seg_no];
01518 if( lsg->start >= sketch_ip->vert_count ||
01519 lsg->end >= sketch_ip->vert_count )
01520 {
01521 if( sketch_ip->skt_curve.reverse[seg_no] )
01522 sprintf( buf, "\t\tLine segment from vertex #%d to #%d\n",
01523 lsg->end, lsg->start );
01524 else
01525 sprintf( buf, "\t\tLine segment from vertex #%d to #%d\n",
01526 lsg->start, lsg->end );
01527 }
01528 else
01529 {
01530 if( sketch_ip->skt_curve.reverse[seg_no] )
01531 sprintf( buf, "\t\tLine segment (%g %g) <-> (%g %g)\n",
01532 V2INTCLAMPARGS( sketch_ip->verts[lsg->end] ),
01533 V2INTCLAMPARGS( sketch_ip->verts[lsg->start] ) );
01534 else
01535 sprintf( buf, "\t\tLine segment (%g %g) <-> (%g %g)\n",
01536 V2INTCLAMPARGS( sketch_ip->verts[lsg->start] ),
01537 V2INTCLAMPARGS( sketch_ip->verts[lsg->end] ) );
01538 }
01539 bu_vls_strcat( str, buf );
01540 break;
01541 case CURVE_CARC_MAGIC:
01542 csg = (struct carc_seg *)sketch_ip->skt_curve.segments[seg_no];
01543 if( csg->radius < 0.0 )
01544 {
01545 bu_vls_strcat( str, "\t\tFull Circle:\n" );
01546
01547 if( csg->end >= sketch_ip->vert_count ||
01548 csg->start >= sketch_ip->vert_count )
01549 {
01550 sprintf( buf, "\t\tcenter at vertex #%d\n",
01551 csg->end );
01552 bu_vls_strcat( str, buf );
01553 sprintf( buf, "\t\tpoint on circle at vertex #%d\n",
01554 csg->start );
01555 }
01556 else
01557 {
01558 sprintf( buf, "\t\t\tcenter: (%g %g)\n",
01559 V2INTCLAMPARGS( sketch_ip->verts[csg->end] ) );
01560 bu_vls_strcat( str, buf );
01561 sprintf( buf, "\t\t\tpoint on circle: (%g %g)\n",
01562 V2INTCLAMPARGS( sketch_ip->verts[csg->start] ) );
01563 }
01564 bu_vls_strcat( str, buf );
01565 }
01566 else
01567 {
01568 bu_vls_strcat( str, "\t\tCircular Arc:\n" );
01569
01570 if( csg->end >= sketch_ip->vert_count ||
01571 csg->start >= sketch_ip->vert_count )
01572 {
01573 sprintf( buf, "\t\t\tstart at vertex #%d\n",
01574 csg->start );
01575 bu_vls_strcat( str, buf );
01576 sprintf( buf, "\t\t\tend at vertex #%d\n",
01577 csg->end );
01578 bu_vls_strcat( str, buf );
01579 }
01580 else
01581 {
01582 sprintf( buf, "\t\t\tstart: (%g, %g)\n",
01583 V2INTCLAMPARGS( sketch_ip->verts[csg->start] ) );
01584 bu_vls_strcat( str, buf );
01585 sprintf( buf, "\t\t\tend: (%g, %g)\n",
01586 V2INTCLAMPARGS( sketch_ip->verts[csg->end] ) );
01587 bu_vls_strcat( str, buf );
01588 }
01589 sprintf( buf, "\t\t\tradius: %g\n", csg->radius*mm2local );
01590 bu_vls_strcat( str, buf );
01591 if( csg->orientation )
01592 bu_vls_strcat( str, "\t\t\tcurve is clock-wise\n" );
01593 else
01594 bu_vls_strcat( str, "\t\t\tcurve is counter-clock-wise\n" );
01595 if( csg->center_is_left )
01596 bu_vls_strcat( str, "\t\t\tcenter of curvature is left of the line from start point to end point\n" );
01597 else
01598 bu_vls_strcat( str, "\t\t\tcenter of curvature is right of the line from start point to end point\n" );
01599 if( sketch_ip->skt_curve.reverse[seg_no] )
01600 bu_vls_strcat( str, "\t\t\tarc is reversed\n" );
01601 }
01602 break;
01603 case CURVE_NURB_MAGIC:
01604 nsg = (struct nurb_seg *)sketch_ip->skt_curve.segments[seg_no];
01605 bu_vls_strcat( str, "\t\tNURB Curve:\n" );
01606 if( RT_NURB_IS_PT_RATIONAL( nsg->pt_type ) )
01607 {
01608 sprintf( buf, "\t\t\tCurve is rational\n" );
01609 bu_vls_strcat( str, buf );
01610 }
01611 sprintf( buf, "\t\t\torder = %d, number of control points = %d\n",
01612 nsg->order, nsg->c_size );
01613 bu_vls_strcat( str, buf );
01614 if( nsg->ctl_points[0] >= sketch_ip->vert_count ||
01615 nsg->ctl_points[nsg->c_size-1] >= sketch_ip->vert_count )
01616 {
01617 if( sketch_ip->skt_curve.reverse[seg_no] )
01618 sprintf( buf, "\t\t\tstarts at vertex #%d\n\t\t\tends at vertex #%d\n",
01619 nsg->ctl_points[nsg->c_size-1],
01620 nsg->ctl_points[0] );
01621 else
01622 sprintf( buf, "\t\t\tstarts at vertex #%d\n\t\t\tends at vertex #%d\n",
01623 nsg->ctl_points[0],
01624 nsg->ctl_points[nsg->c_size-1] );
01625 }
01626 else
01627 {
01628 if( sketch_ip->skt_curve.reverse[seg_no] )
01629 sprintf( buf, "\t\t\tstarts at (%g %g)\n\t\t\tends at (%g %g)\n",
01630 V2INTCLAMPARGS( sketch_ip->verts[nsg->ctl_points[nsg->c_size-1]] ),
01631 V2INTCLAMPARGS( sketch_ip->verts[nsg->ctl_points[0]] ) );
01632 else
01633 sprintf( buf, "\t\t\tstarts at (%g %g)\n\t\t\tends at (%g %g)\n",
01634 V2INTCLAMPARGS( sketch_ip->verts[nsg->ctl_points[0]] ),
01635 V2INTCLAMPARGS( sketch_ip->verts[nsg->ctl_points[nsg->c_size-1]] ) );
01636 }
01637 bu_vls_strcat( str, buf );
01638 sprintf( buf, "\t\t\tknot values are %g to %g\n",
01639 INTCLAMP(nsg->k.knots[0]), INTCLAMP(nsg->k.knots[nsg->k.k_size-1]) );
01640 bu_vls_strcat( str, buf );
01641 break;
01642 case CURVE_BEZIER_MAGIC:
01643 bsg = (struct bezier_seg *)sketch_ip->skt_curve.segments[seg_no];
01644 bu_vls_strcat( str, "\t\tBezier segment:\n" );
01645 sprintf( buf, "\t\t\tdegree = %d\n", bsg->degree );
01646 bu_vls_strcat( str, buf );
01647 if( bsg->ctl_points[0] >= sketch_ip->vert_count ||
01648 bsg->ctl_points[bsg->degree] >= sketch_ip->vert_count ) {
01649 if( sketch_ip->skt_curve.reverse[seg_no] ){
01650 sprintf( buf, "\t\t\tstarts at vertex #%d\n\t\t\tends at vertex #%d\n",
01651 bsg->ctl_points[bsg->degree],
01652 bsg->ctl_points[0] );
01653 } else {
01654 sprintf( buf, "\t\t\tstarts at vertex #%d\n\t\t\tends at vertex #%d\n",
01655 bsg->ctl_points[0],
01656 bsg->ctl_points[bsg->degree] );
01657 }
01658 } else {
01659 if( sketch_ip->skt_curve.reverse[seg_no] )
01660 sprintf( buf, "\t\t\tstarts at (%g %g)\n\t\t\tends at (%g %g)\n",
01661 V2INTCLAMPARGS( sketch_ip->verts[bsg->ctl_points[bsg->degree]]),
01662 V2INTCLAMPARGS( sketch_ip->verts[bsg->ctl_points[0]] ) );
01663 else
01664 sprintf( buf, "\t\t\tstarts at (%g %g)\n\t\t\tends at (%g %g)\n",
01665 V2INTCLAMPARGS( sketch_ip->verts[bsg->ctl_points[0]] ),
01666 V2INTCLAMPARGS( sketch_ip->verts[bsg->ctl_points[bsg->degree]]));
01667 }
01668 bu_vls_strcat( str, buf );
01669 break;
01670 default:
01671 bu_bomb( "rt_sketch_describe: ERROR: unrecognized segment type\n" );
01672 }
01673 }
01674
01675 return(0);
01676 }
01677
01678 void
01679 rt_curve_free(struct curve *crv)
01680 {
01681 int i;
01682
01683 if( crv->seg_count )
01684 bu_free( (char *)crv->reverse, "crv->reverse" );
01685 for( i=0 ; i<crv->seg_count ; i++ )
01686 {
01687 long *lng;
01688 struct nurb_seg *nsg;
01689 struct bezier_seg *bsg;
01690
01691 lng = (long *)crv->segments[i];
01692 switch( *lng )
01693 {
01694 case CURVE_NURB_MAGIC:
01695 nsg = (struct nurb_seg *)lng;
01696 bu_free( (char *)nsg->ctl_points, "nsg->ctl_points" );
01697 if( nsg->weights )
01698 bu_free( ( char *)nsg->weights, "nsg->weights" );
01699 bu_free( ( char *)nsg->k.knots, "nsg->k.knots" );
01700 bu_free( (char *)lng, "curve segment" );
01701 break;
01702 case CURVE_BEZIER_MAGIC:
01703 bsg = (struct bezier_seg *)lng;
01704 bu_free( (char *)bsg->ctl_points, "bsg->ctl_points" );
01705 bu_free( (char *)lng, "curve segment" );
01706 break;
01707 case CURVE_LSEG_MAGIC:
01708 case CURVE_CARC_MAGIC:
01709 bu_free( (char *)lng, "curve segment" );
01710 break;
01711 default:
01712 bu_log( "ERROR: rt_curve_free: unrecognized curve segments type!!!!\n");
01713 break;
01714 }
01715 }
01716
01717 if( crv->seg_count > 0 )
01718 bu_free( (char *)crv->segments, "crv->segments" );
01719
01720 crv->seg_count = 0;
01721 crv->reverse = (int *)NULL;
01722 crv->segments = (genptr_t)NULL;
01723 }
01724
01725
01726
01727
01728
01729
01730
01731 void
01732 rt_sketch_ifree( struct rt_db_internal *ip )
01733 {
01734 register struct rt_sketch_internal *sketch_ip;
01735 struct curve *crv;
01736
01737 RT_CK_DB_INTERNAL(ip);
01738 sketch_ip = (struct rt_sketch_internal *)ip->idb_ptr;
01739 RT_SKETCH_CK_MAGIC(sketch_ip);
01740 sketch_ip->magic = 0;
01741
01742 if( bu_debug&BU_DEBUG_MEM_CHECK )
01743 {
01744 bu_log( "Barrier check at start of sketch_ifree():\n" );
01745 bu_mem_barriercheck();
01746 }
01747
01748 if( sketch_ip->verts )
01749 bu_free( (char *)sketch_ip->verts, "sketch_ip->verts" );
01750
01751 crv = &sketch_ip->skt_curve;
01752
01753 rt_curve_free( crv );
01754
01755 bu_free( (char *)sketch_ip, "sketch ifree" );
01756 ip->idb_ptr = GENPTR_NULL;
01757
01758 if( bu_debug&BU_DEBUG_MEM_CHECK )
01759 {
01760 bu_log( "Barrier check at end of sketch_ifree():\n" );
01761 bu_mem_barriercheck();
01762 }
01763
01764 }
01765
01766 void
01767 rt_copy_curve(struct curve *crv_out, const struct curve *crv_in)
01768 {
01769 int i, j;
01770
01771 crv_out->seg_count = crv_in->seg_count;
01772 crv_out->reverse = (int *)bu_calloc( crv_out->seg_count, sizeof( int ), "crv->reverse" );
01773 crv_out->segments = (genptr_t *)bu_calloc( crv_out->seg_count, sizeof( genptr_t ), "crv->segments" );
01774 for( j=0 ; j<crv_out->seg_count ; j++ )
01775 {
01776 long *lng;
01777 struct line_seg *lsg_out, *lsg_in;
01778 struct carc_seg *csg_out, *csg_in;
01779 struct nurb_seg *nsg_out, *nsg_in;
01780 struct bezier_seg *bsg_out, *bsg_in;
01781
01782 crv_out->reverse[j] = crv_in->reverse[j];
01783 lng = (long *)crv_in->segments[j];
01784 switch( *lng )
01785 {
01786 case CURVE_LSEG_MAGIC:
01787 lsg_in = (struct line_seg *)lng;
01788 lsg_out = (struct line_seg *)bu_malloc( sizeof( struct line_seg ), "line_seg" );
01789 crv_out->segments[j] = (genptr_t)lsg_out;
01790 *lsg_out = *lsg_in;
01791 break;
01792 case CURVE_CARC_MAGIC:
01793 csg_in = (struct carc_seg *)lng;
01794 csg_out = (struct carc_seg *)bu_malloc( sizeof( struct carc_seg ), "carc_seg" );
01795 crv_out->segments[j] = (genptr_t)csg_out;
01796 *csg_out = *csg_in;
01797 break;
01798 case CURVE_NURB_MAGIC:
01799 nsg_in = (struct nurb_seg *)lng;
01800 nsg_out = (struct nurb_seg *)bu_malloc( sizeof( struct nurb_seg ), "nurb_seg" );
01801 crv_out->segments[j] = (genptr_t)nsg_out;
01802 *nsg_out = *nsg_in;
01803 nsg_out->ctl_points = (int *)bu_calloc( nsg_in->c_size, sizeof( int ), "nsg_out->ctl_points" );
01804 for( i=0 ; i<nsg_out->c_size ; i++ )
01805 nsg_out->ctl_points[i] = nsg_in->ctl_points[i];
01806 if( RT_NURB_IS_PT_RATIONAL( nsg_in->pt_type ) )
01807 {
01808 nsg_out->weights = (fastf_t *)bu_malloc( nsg_out->c_size * sizeof( fastf_t ), "nsg_out->weights" );
01809 for( i=0 ; i<nsg_out->c_size ; i++ )
01810 nsg_out->weights[i] = nsg_in->weights[i];
01811 }
01812 else
01813 nsg_out->weights = (fastf_t *)NULL;
01814 nsg_out->k.knots = bu_malloc( nsg_in->k.k_size * sizeof( fastf_t ), "nsg_out->k.knots" );
01815 for( i=0 ; i<nsg_in->k.k_size ; i++ )
01816 nsg_out->k.knots[i] = nsg_in->k.knots[i];
01817 break;
01818 case CURVE_BEZIER_MAGIC:
01819 bsg_in = (struct bezier_seg *)lng;
01820 bsg_out = (struct bezier_seg *)bu_malloc( sizeof( struct bezier_seg ), "bezier_seg" );
01821 crv_out->segments[j] = (genptr_t)bsg_out;
01822 *bsg_out = *bsg_in;
01823 bsg_out->ctl_points = (int *)bu_calloc( bsg_out->degree + 1,
01824 sizeof( int ), "bsg_out->ctl_points" );
01825 for( i=0 ; i<=bsg_out->degree ; i++ ) {
01826 bsg_out->ctl_points[i] = bsg_in->ctl_points[i];
01827 }
01828 break;
01829 default:
01830 bu_bomb( "rt_copy_sketch: ERROR: unrecognized segment type!!!!\n" );
01831 }
01832 }
01833
01834 }
01835
01836
01837 struct rt_sketch_internal *
01838 rt_copy_sketch(const struct rt_sketch_internal *sketch_ip)
01839 {
01840 struct rt_sketch_internal *out;
01841 int i;
01842 struct curve *crv_out;
01843
01844 RT_SKETCH_CK_MAGIC( sketch_ip );
01845
01846 if( bu_debug&BU_DEBUG_MEM_CHECK )
01847 {
01848 bu_log( "Barrier check at start of rt_copy_sketch():\n" );
01849 bu_mem_barriercheck();
01850 }
01851
01852 out = (struct rt_sketch_internal *) bu_malloc( sizeof( struct rt_sketch_internal ), "rt_sketch_internal" );
01853 *out = *sketch_ip;
01854
01855 out->verts = (point2d_t *)bu_calloc( out->vert_count, sizeof( point2d_t ), "out->verts" );
01856 for( i=0 ; i<out->vert_count ; i++ )
01857 V2MOVE( out->verts[i], sketch_ip->verts[i] );
01858
01859 crv_out = &out->skt_curve;
01860 rt_copy_curve( crv_out, &sketch_ip->skt_curve );
01861
01862 if( bu_debug&BU_DEBUG_MEM_CHECK )
01863 {
01864 bu_log( "Barrier check at end of rt_copy_sketch():\n" );
01865 bu_mem_barriercheck();
01866 }
01867
01868 return( out );
01869 }
01870
01871
01872 int
01873 curve_to_tcl_list(struct bu_vls *vls, struct curve *crv)
01874 {
01875 int i,j;
01876
01877 bu_vls_printf( vls, " SL {" );
01878 for( j=0 ; j<crv->seg_count ; j++ )
01879 {
01880 switch( (*(long *)crv->segments[j]) )
01881 {
01882 case CURVE_LSEG_MAGIC:
01883 {
01884 struct line_seg *lsg = (struct line_seg *)crv->segments[j];
01885 bu_vls_printf( vls, " { line S %d E %d }", lsg->start, lsg->end );
01886 }
01887 break;
01888 case CURVE_CARC_MAGIC:
01889 {
01890 struct carc_seg *csg = (struct carc_seg *)crv->segments[j];
01891 bu_vls_printf( vls, " { carc S %d E %d R %.25g L %d O %d }",
01892 csg->start, csg->end, csg->radius,
01893 csg->center_is_left, csg->orientation );
01894 }
01895 break;
01896 case CURVE_BEZIER_MAGIC:
01897 {
01898 struct bezier_seg *bsg = (struct bezier_seg *)crv->segments[j];
01899 bu_vls_printf( vls, " { bezier D %d P {", bsg->degree );
01900 for( i=0 ; i<=bsg->degree ; i++ )
01901 bu_vls_printf( vls, " %d", bsg->ctl_points[i] );
01902 bu_vls_printf( vls, " } }" );
01903 }
01904 break;
01905 case CURVE_NURB_MAGIC:
01906 {
01907 int k;
01908 struct nurb_seg *nsg = (struct nurb_seg *)crv->segments[j];
01909 bu_vls_printf( vls, " { nurb O %d T %d K {",
01910 nsg->order, nsg->pt_type );
01911 for( k=0 ; k<nsg->k.k_size ; k++ )
01912 bu_vls_printf( vls, " %.25g", nsg->k.knots[k] );
01913 bu_vls_strcat( vls, "} P {" );
01914 for( k=0 ; k<nsg->c_size ; k++ )
01915 bu_vls_printf( vls, " %d", nsg->ctl_points[k] );
01916 if( nsg->weights )
01917 {
01918 bu_vls_strcat( vls, "} W {" );
01919 for( k=0 ; k<nsg->c_size ; k++ )
01920 bu_vls_printf( vls, " %.25g", nsg->weights[k] );
01921 }
01922 bu_vls_strcat( vls, "} }" );
01923 }
01924 break;
01925 }
01926 }
01927 bu_vls_strcat( vls, " }" );
01928
01929 return( 0 );
01930 }
01931
01932
01933 int rt_sketch_tclform( const struct rt_functab *ftp, Tcl_Interp *interp)
01934 {
01935 RT_CK_FUNCTAB(ftp);
01936
01937 Tcl_AppendResult( interp,
01938 "V {%f %f %f} A {%f %f %f} B {%f %f %f} VL { {%f %f} {%f %f} ...} SL { { segment_data } { segment_data} }" );
01939
01940 return TCL_OK;
01941 }
01942
01943
01944 int
01945 rt_sketch_tclget(Tcl_Interp *interp, const struct rt_db_internal *intern, const char *attr)
01946 {
01947 register struct rt_sketch_internal *skt=(struct rt_sketch_internal *)intern->idb_ptr;
01948 Tcl_DString ds;
01949 struct bu_vls vls;
01950 int i;
01951 struct curve *crv;
01952
01953 RT_SKETCH_CK_MAGIC( skt );
01954
01955 Tcl_DStringInit( &ds );
01956 bu_vls_init( &vls );
01957
01958 if( attr == (char *)NULL )
01959 {
01960 bu_vls_strcpy( &vls, "sketch" );
01961 bu_vls_printf( &vls, " V {%.25g %.25g %.25g}", V3ARGS( skt->V ) );
01962 bu_vls_printf( &vls, " A {%.25g %.25g %.25g}", V3ARGS( skt->u_vec ) );
01963 bu_vls_printf( &vls, " B {%.25g %.25g %.25g}", V3ARGS( skt->v_vec ) );
01964 bu_vls_strcat( &vls, " VL {" );
01965 for( i=0 ; i<skt->vert_count ; i++ )
01966 bu_vls_printf( &vls, " {%.25g %.25g}", V2ARGS( skt->verts[i] ) );
01967 bu_vls_strcat( &vls, " }" );
01968
01969 crv = &skt->skt_curve;
01970 if( curve_to_tcl_list( &vls, crv ) )
01971 {
01972 bu_vls_free( &vls );
01973 return( TCL_ERROR );
01974 }
01975 }
01976 else if( !strcmp( attr, "V" ) )
01977 bu_vls_printf( &vls, "%.25g %.25g %.25g", V3ARGS( skt->V ) );
01978 else if( !strcmp( attr, "A" ) )
01979 bu_vls_printf( &vls, "%.25g %.25g %.25g", V3ARGS( skt->u_vec ) );
01980 else if( !strcmp( attr, "B" ) )
01981 bu_vls_printf( &vls, "%.25g %.25g %.25g", V3ARGS( skt->v_vec ) );
01982 else if( !strcmp( attr, "VL" ) )
01983 {
01984 for( i=0 ; i<skt->vert_count ; i++ )
01985 bu_vls_printf( &vls, " {%.25g %.25g}", V2ARGS( skt->verts[i] ) );
01986 }
01987 else if( !strcmp( attr, "SL" ) )
01988 {
01989 crv = &skt->skt_curve;
01990 if( curve_to_tcl_list( &vls, crv ) )
01991 {
01992 bu_vls_free( &vls );
01993 return( TCL_ERROR );
01994 }
01995 }
01996 else if( *attr == 'V' )
01997 {
01998 i = atoi( (attr+1) );
01999 if( i < 0 || i >= skt->vert_count )
02000 {
02001 Tcl_SetResult( interp, "ERROR: Illegal vertex number\n", TCL_STATIC );
02002 bu_vls_free( &vls );
02003 return( TCL_ERROR );
02004 }
02005
02006 bu_vls_printf( &vls, "%.25g %.25g", V2ARGS( skt->verts[i] ) );
02007 }
02008 else
02009 {
02010 Tcl_SetResult( interp, "ERROR: Unknown attribute, choices are V, A, B, VL, SL, or V#\n", TCL_STATIC );
02011 bu_vls_free( &vls );
02012 return( TCL_ERROR );
02013 }
02014
02015 Tcl_DStringAppend( &ds, bu_vls_addr( &vls ), -1 );
02016 Tcl_DStringResult( interp, &ds );
02017 Tcl_DStringFree( &ds );
02018 bu_vls_free( &vls );
02019 return( TCL_OK );
02020 }
02021
02022
02023 int
02024 get_tcl_curve(Tcl_Interp *interp, struct curve *crv, Tcl_Obj *seg_list)
02025 {
02026 int seg_count;
02027 int ret, j;
02028
02029
02030 seg_count = 0;
02031 if( (ret=Tcl_ListObjLength( interp, seg_list, &seg_count ) ))
02032 {
02033 return( ret );
02034 }
02035
02036 if( seg_count )
02037 {
02038 crv->seg_count = seg_count;
02039 crv->reverse = (int *)bu_calloc( seg_count, sizeof( int ), "crv->reverse" );
02040 crv->segments = (genptr_t *)bu_calloc( seg_count, sizeof( genptr_t ), "crv->segments" );
02041 }
02042
02043
02044 for( j=0 ; j<seg_count ; j++ )
02045 {
02046 Tcl_Obj *seg, *seg_type, *seg_elem, *seg_val;
02047 char *type, *elem;
02048 int k, seg_len;
02049
02050
02051
02052 if( (ret=Tcl_ListObjIndex( interp, seg_list, j, &seg ) ))
02053 {
02054 return( ret );
02055 }
02056
02057 if( (ret=Tcl_ListObjLength( interp, seg, &seg_len )) )
02058 return( ret );
02059
02060
02061 if( (ret=Tcl_ListObjIndex( interp, seg, 0, &seg_type ) ))
02062 return( ret );
02063 type = Tcl_GetString( seg_type );
02064
02065 if( !strcmp( type, "line" ) )
02066 {
02067 struct line_seg *lsg;
02068
02069 lsg = (struct line_seg *)bu_calloc( 1, sizeof( struct line_seg ), "lsg" );
02070 for( k=1 ; k<seg_len ; k += 2 )
02071 {
02072 if( (ret=Tcl_ListObjIndex( interp, seg, k, &seg_elem ) ))
02073 return( ret );
02074
02075 if( (ret=Tcl_ListObjIndex( interp, seg, k+1, &seg_val ) ))
02076 return( ret );
02077
02078 elem = Tcl_GetString( seg_elem );
02079 switch( *elem )
02080 {
02081 case 'S':
02082 Tcl_GetIntFromObj( interp, seg_val, &lsg->start );
02083 break;
02084 case 'E':
02085 Tcl_GetIntFromObj( interp, seg_val, &lsg->end );
02086 break;
02087 }
02088 }
02089 lsg->magic = CURVE_LSEG_MAGIC;
02090 crv->segments[j] = (genptr_t)lsg;
02091 }
02092 else if( !strcmp( type, "bezier" ) )
02093 {
02094 struct bezier_seg *bsg;
02095 int num_points;
02096
02097 bsg = (struct bezier_seg *)bu_calloc( 1, sizeof( struct bezier_seg ), "bsg" );
02098 for( k=1 ; k<seg_len ; k+= 2 ) {
02099
02100 if( (ret=Tcl_ListObjIndex( interp, seg, k, &seg_elem ) ))
02101 return( ret );
02102
02103 if( (ret=Tcl_ListObjIndex( interp, seg, k+1, &seg_val ) ))
02104 return( ret );
02105
02106 elem = Tcl_GetString( seg_elem );
02107 switch( *elem )
02108 {
02109 case 'D':
02110 Tcl_GetIntFromObj( interp, seg_val,
02111 &bsg->degree );
02112 break;
02113 case 'P':
02114 num_points = 0;
02115 (void)tcl_obj_to_int_array( interp,
02116 seg_val, &bsg->ctl_points,
02117 &num_points );
02118
02119 if( num_points != bsg->degree + 1 ) {
02120 Tcl_SetResult( interp, "ERROR: degree and number of control points disagree for a Bezier segment\n", TCL_STATIC );
02121 return( TCL_ERROR );
02122 }
02123 }
02124 }
02125 bsg->magic = CURVE_BEZIER_MAGIC;
02126 crv->segments[j] = (genptr_t)bsg;
02127 }
02128 else if( !strcmp( type, "carc" ) )
02129 {
02130 struct carc_seg *csg;
02131 double tmp;
02132
02133 csg = (struct carc_seg *)bu_calloc( 1, sizeof( struct carc_seg ), "csg" );
02134 for( k=1 ; k<seg_len ; k += 2 )
02135 {
02136 if( (ret=Tcl_ListObjIndex( interp, seg, k, &seg_elem ) ))
02137 return( ret );
02138
02139 if( (ret=Tcl_ListObjIndex( interp, seg, k+1, &seg_val ) ))
02140 return( ret );
02141
02142 elem = Tcl_GetString( seg_elem );
02143 switch( *elem )
02144 {
02145 case 'S':
02146 Tcl_GetIntFromObj( interp, seg_val, &csg->start );
02147 break;
02148 case 'E':
02149 Tcl_GetIntFromObj( interp, seg_val, &csg->end );
02150 break;
02151 case 'R':
02152 Tcl_GetDoubleFromObj( interp, seg_val, &tmp );
02153 csg->radius = tmp;
02154 break;
02155 case 'L' :
02156 Tcl_GetBooleanFromObj( interp, seg_val, &csg->center_is_left );
02157 break;
02158 case 'O':
02159 Tcl_GetBooleanFromObj( interp, seg_val, &csg->orientation );
02160 break;
02161 }
02162 }
02163 csg->magic = CURVE_CARC_MAGIC;
02164 crv->segments[j] = (genptr_t)csg;
02165 }
02166 else if( !strcmp( type, "nurb" ) )
02167 {
02168 struct nurb_seg *nsg;
02169
02170 nsg = (struct nurb_seg *)bu_calloc( 1, sizeof( struct nurb_seg ), "nsg" );
02171 for( k=1 ; k<seg_len ; k += 2 )
02172 {
02173 if( (ret=Tcl_ListObjIndex( interp, seg, k, &seg_elem ) ))
02174 return( ret );
02175
02176 if( (ret=Tcl_ListObjIndex( interp, seg, k+1, &seg_val ) ))
02177 return( ret );
02178
02179 elem = Tcl_GetString( seg_elem );
02180 switch( *elem )
02181 {
02182 case 'O':
02183 Tcl_GetIntFromObj( interp, seg_val, &nsg->order );
02184 break;
02185 case 'T':
02186 Tcl_GetIntFromObj( interp, seg_val, &nsg->pt_type );
02187 break;
02188 case 'K':
02189 tcl_obj_to_fastf_array( interp, seg_val, &nsg->k.knots, &nsg->k.k_size );
02190 break;
02191 case 'P' :
02192 tcl_obj_to_int_array( interp, seg_val, &nsg->ctl_points, &nsg->c_size );
02193 break;
02194 case 'W':
02195 tcl_obj_to_fastf_array( interp, seg_val, &nsg->weights, &nsg->c_size );
02196 break;
02197 }
02198 }
02199 nsg->magic = CURVE_NURB_MAGIC;
02200 crv->segments[j] = (genptr_t)nsg;
02201 }
02202 else
02203 {
02204 Tcl_ResetResult( interp );
02205 Tcl_AppendResult( interp, "ERROR: Unrecognized segment type: ",
02206 Tcl_GetString( seg ), (char *)NULL);
02207 return( TCL_ERROR );
02208 }
02209 }
02210
02211 return( TCL_OK );
02212 }
02213
02214
02215 int
02216 rt_sketch_tcladjust(Tcl_Interp *interp, struct rt_db_internal *intern, int argc, char **argv)
02217 {
02218 struct rt_sketch_internal *skt;
02219 int ret, array_len;
02220 fastf_t *new;
02221
02222 RT_CK_DB_INTERNAL( intern );
02223 skt = (struct rt_sketch_internal *)intern->idb_ptr;
02224 RT_SKETCH_CK_MAGIC( skt );
02225
02226 while( argc >= 2 )
02227 {
02228 if( !strcmp( argv[0], "V" ) )
02229 {
02230 new = skt->V;
02231 array_len = 3;
02232 if( tcl_list_to_fastf_array( interp, argv[1], &new, &array_len) !=
02233 array_len ) {
02234 Tcl_SetResult( interp,
02235 "ERROR: Incorrect number of coordinates for vertex\n",
02236 TCL_STATIC );
02237 return( TCL_ERROR );
02238 }
02239 }
02240 else if( !strcmp( argv[0], "A" ) )
02241 {
02242 new = skt->u_vec;
02243 array_len = 3;
02244 if( tcl_list_to_fastf_array( interp, argv[1], &new, &array_len) !=
02245 array_len ) {
02246 Tcl_SetResult( interp,
02247 "ERROR: Incorrect number of coordinates for vertex\n",
02248 TCL_STATIC );
02249 return( TCL_ERROR );
02250 }
02251 }
02252 else if( !strcmp( argv[0], "B" ) )
02253 {
02254 new = skt->v_vec;
02255 array_len = 3;
02256 if( tcl_list_to_fastf_array( interp, argv[1], &new, &array_len) !=
02257 array_len ) {
02258 Tcl_SetResult( interp,
02259 "ERROR: Incorrect number of coordinates for vertex\n",
02260 TCL_STATIC );
02261 return( TCL_ERROR );
02262 }
02263 }
02264 else if( !strcmp( argv[0], "VL" ) )
02265 {
02266 fastf_t *new_verts=(fastf_t *)NULL;
02267 int len;
02268 char *ptr;
02269
02270
02271
02272
02273 ptr = argv[1];
02274 while( *ptr != '\0' )
02275 {
02276 if( *ptr == '{' || *ptr == '}' )
02277 *ptr = ' ';
02278 ptr++;
02279 }
02280
02281 len = 0;
02282 (void)tcl_list_to_fastf_array( interp, argv[1], &new_verts, &len );
02283 if( len%2 ) {
02284 Tcl_SetResult( interp,
02285 "ERROR: Incorrect number of coordinates for vertices\n",
02286 TCL_STATIC );
02287 return( TCL_ERROR );
02288 }
02289
02290 if( skt->verts )
02291 bu_free( (char *)skt->verts, "verts" );
02292 skt->verts = (point2d_t *)new_verts;
02293 skt->vert_count = len / 2;
02294 }
02295 else if( !strcmp( argv[0], "SL" ) )
02296 {
02297 Tcl_Obj *tmp;
02298 struct curve *crv;
02299
02300
02301 tmp = Tcl_NewStringObj( argv[1], -1 );
02302
02303 crv = &skt->skt_curve;
02304 crv->seg_count = 0;
02305 crv->reverse = (int *)NULL;
02306 crv->segments = (genptr_t)NULL;
02307
02308 if( (ret=get_tcl_curve( interp, crv, tmp )) != TCL_OK )
02309 return( ret );
02310 }
02311 else if( *argv[0] == 'V' && isdigit( *(argv[0]+1) ) )
02312 {
02313
02314 int vert_no;
02315 fastf_t *new_vert;
02316
02317 vert_no = atoi( argv[0] + 1 );
02318 new_vert = skt->verts[vert_no];
02319 if( vert_no < 0 || vert_no > skt->vert_count )
02320 {
02321 Tcl_SetResult( interp, "ERROR: Illegal vertex number\n",
02322 TCL_STATIC );
02323 return( TCL_ERROR );
02324 }
02325 array_len = 2;
02326 if(tcl_list_to_fastf_array( interp, argv[1], &new_vert, &array_len)
02327 != array_len )
02328 {
02329 Tcl_SetResult( interp,
02330 "ERROR: Incorrect number of coordinates for vertex\n",
02331 TCL_STATIC );
02332 return( TCL_ERROR );
02333 }
02334 }
02335
02336 argc -= 2;
02337 argv += 2;
02338 }
02339
02340 return( TCL_OK );
02341 }
02342
02343
02344 void
02345 rt_curve_reverse_segment( long *lng )
02346 {
02347 struct line_seg *lsg;
02348 struct carc_seg *csg;
02349 struct bezier_seg *bsg;
02350 int tmp, i;
02351
02352 switch( *lng ) {
02353 case CURVE_LSEG_MAGIC:
02354 lsg = (struct line_seg *)lng;
02355 tmp = lsg->start;
02356 lsg->start = lsg->end;
02357 lsg->end = tmp;
02358 break;
02359 case CURVE_CARC_MAGIC:
02360 csg = (struct carc_seg *)lng;
02361 if( csg->radius < 0.0 ) {
02362
02363 csg->orientation = !csg->orientation;
02364 } else {
02365 tmp = csg->start;
02366 csg->start = csg->end;
02367 csg->end = tmp;
02368 csg->center_is_left = !csg->center_is_left;
02369 csg->orientation = !csg->orientation;
02370 }
02371 break;
02372 case CURVE_BEZIER_MAGIC:
02373 bsg = (struct bezier_seg *)lng;
02374 for( i=0 ; i<bsg->degree/2 ; i++ ) {
02375 tmp = bsg->ctl_points[i];
02376 bsg->ctl_points[i] = bsg->ctl_points[bsg->degree-i];
02377 bsg->ctl_points[bsg->degree-i] = tmp;
02378 }
02379 break;
02380 }
02381 }
02382
02383
02384 void
02385 rt_curve_order_segments( struct curve *crv )
02386 {
02387 int i, j, k;
02388 int seg_count;
02389 int start1, end1, start2, end2, start3, end3;
02390
02391 seg_count = crv->seg_count;
02392 if( seg_count < 2 ) {
02393 return;
02394 }
02395
02396 for( j=1 ; j<seg_count ; j++ ) {
02397 i = j - 1;
02398
02399 get_indices( crv->segments[i], &start1, &end1 );
02400 get_indices( crv->segments[j], &start2, &end2 );
02401
02402 if( end1 != start2 ) {
02403 int fixed=0;
02404
02405 for( k=j+1 ; k<seg_count ; k++ ) {
02406 get_indices( crv->segments[k], &start3, &end3 );
02407 if( start3 == end1 ) {
02408 int tmp_reverse;
02409 genptr_t tmp_seg;
02410
02411
02412 tmp_seg = crv->segments[j];
02413 crv->segments[j] = crv->segments[k];
02414 crv->segments[k] = tmp_seg;
02415
02416 tmp_reverse = crv->reverse[j];
02417 crv->reverse[j] = crv->reverse[k];
02418 crv->reverse[k] = tmp_reverse;
02419 fixed = 1;
02420 break;
02421 }
02422 }
02423 if( !fixed ) {
02424
02425 for( k=j ; k<seg_count ; k++ ) {
02426 get_indices( crv->segments[k], &start3, &end3 );
02427 if( end3 == end1 ) {
02428 int tmp_reverse;
02429 genptr_t tmp_seg;
02430
02431 rt_curve_reverse_segment( crv->segments[k] );
02432
02433 if( k != j ) {
02434
02435 tmp_seg = crv->segments[j];
02436 crv->segments[j] = crv->segments[k];
02437 crv->segments[k] = tmp_seg;
02438
02439 tmp_reverse = crv->reverse[j];
02440 crv->reverse[j] = crv->reverse[k];
02441 crv->reverse[k] = tmp_reverse;
02442 }
02443 fixed = 1;
02444 break;
02445 }
02446 }
02447 }
02448 }
02449 }
02450 }
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461