cgma
CompositeCurve.cpp
Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // Filename      : CompositeCurve.cpp
00003 //
00004 // Purpose       : Geometry defined as the joining of a chain of curves.
00005 //
00006 // Special Notes : 
00007 //
00008 // Creator       : Jason Kraftcheck
00009 //
00010 // Creation Date : 12/19/01
00011 //-------------------------------------------------------------------------
00012 
00013 #include <math.h>
00014 
00015 #include "CompositeCurve.hpp"
00016 #include "CompositeCoEdge.hpp"
00017 #include "CompositeLoop.hpp"
00018 #include "CompositePoint.hpp"
00019 #include "VirtualQueryEngine.hpp"
00020 #include "CompositeEngine.hpp"
00021 
00022 //#include "GfxDebug.hpp"
00023 #include "GMem.hpp"
00024 
00025 //-------------------------------------------------------------------------
00026 // Purpose       : Constructor
00027 //
00028 // Special Notes : 
00029 //
00030 // Creator       : Jason Kraftcheck
00031 //
00032 // Creation Date : 12/19/01
00033 //-------------------------------------------------------------------------
00034 CompositeCurve::CompositeCurve( Curve* curve )
00035   : HadBridgeRemoved(0),
00036     hiddenSet(0),
00037     firstCoEdge(0),
00038     startPoint(0), 
00039     endPoint(0), 
00040     startNext(0), 
00041     endNext(0),
00042     stitchNext(0)
00043 {
00044   compGeom = new CompositeGeom(1);
00045   compGeom->append( curve, CUBIT_FORWARD );
00046   if( curve->owner() )
00047     curve->owner()->swap_bridge( curve, this, false );
00048   curve->owner(this);
00049 }
00050 
00051 CompositeCurve::CompositeCurve( CompositeGeom* geometry )
00052   : HadBridgeRemoved(0),
00053     compGeom( geometry ),
00054     hiddenSet( 0 ),
00055     firstCoEdge( 0 ),
00056     startPoint( 0 ),
00057     endPoint( 0 ),
00058     startNext( 0 ),
00059     endNext( 0 ),
00060     stitchNext(0)
00061 {
00062   for( int i = 0; i < compGeom->num_entities(); i++ )
00063   {
00064     GeometryEntity* entity = compGeom->entity(i);
00065     assert( !entity->owner() );
00066     entity->owner(this);
00067   }
00068 }
00069 
00070 //-------------------------------------------------------------------------
00071 // Purpose       : Point-curve constructor
00072 //
00073 // Special Notes : 
00074 //
00075 // Creator       : Jason Kraftcheck
00076 //
00077 // Creation Date : 02/27/04
00078 //-------------------------------------------------------------------------
00079 CompositeCurve::CompositeCurve( CompositePoint* point )
00080   : HadBridgeRemoved(0),
00081     hiddenSet(0),
00082     firstCoEdge(0),
00083     startPoint(0), 
00084     endPoint(0), 
00085     startNext(0), 
00086     endNext(0),
00087     stitchNext(0)
00088 {
00089   compGeom = new CompositeGeom(1);
00090   //compGeom->append( point, CUBIT_FORWARD );
00091   start_point(point);
00092   end_point(point);
00093 }
00094 
00095 
00096 CompositeCurve::~CompositeCurve()
00097 {
00098   while( firstCoEdge )
00099     remove( firstCoEdge );
00100   
00101   for( int i = 0; i < num_curves(); i++ )
00102     if( get_curve(i)->owner() == this )
00103       get_curve(i)->owner(0);
00104       
00105   start_point(0);
00106   end_point(0);
00107   
00108   unstitch_all();
00109   
00110   delete hiddenSet;
00111   delete compGeom;
00112   hiddenSet = (HiddenEntitySet*)0xbdbdbdbd;
00113   compGeom = (CompositeGeom*)0xbdbdbdbd;
00114   assert(!startNext);
00115   assert(!endNext);
00116 }
00117 
00118 
00119 CompositeCurve* CompositeCurve::next( const CompositePoint* around )
00120 {
00121   return around == startPoint ? startNext :
00122          around == endPoint ? endNext : 0;
00123 }
00124 
00125 CubitStatus CompositeCurve::start_point( CompositePoint* pt )
00126 {
00127   return set_point( true, pt );
00128 }
00129 
00130 CubitStatus CompositeCurve::end_point( CompositePoint* pt )
00131 {
00132   return set_point( false, pt );
00133 }
00134 
00135 CubitStatus CompositeCurve::set_point( bool start, CompositePoint* pt )
00136 {
00137   CompositePoint*& my_point = start ? startPoint : endPoint;
00138   CompositeCurve*& next_crv = start ? startNext : endNext;
00139 
00140   if( pt == my_point )
00141     return CUBIT_SUCCESS;
00142   
00143   if( my_point && startPoint != endPoint )
00144   {
00145     CompositeCurve* prev = my_point->firstCurve;
00146     assert( prev != NULL );
00147 
00148     if( prev == this )
00149     {
00150       my_point->firstCurve = next_crv;
00151     }
00152     else
00153     {
00154       CompositeCurve* curve = prev->next(my_point);
00155       while( curve != this )
00156       {
00157         prev = curve;
00158           curve = prev->next(my_point);
00159       }
00160       
00161       if( prev->startPoint == my_point )
00162       {
00163         assert(prev->startNext == this);
00164         prev->startNext = next_crv;
00165       }
00166       
00167       if( prev->endPoint == my_point )
00168       {
00169         assert(prev->endNext == this);
00170         prev->endNext = next_crv;
00171       }
00172     }
00173   }
00174 
00175   my_point = pt;
00176   if (!pt)
00177   {
00178     next_crv = 0;
00179   }
00180   else if (startPoint == endPoint)
00181   {
00182     next_crv = start ? endNext : startNext;
00183   }
00184   else
00185   {
00186     next_crv = pt->firstCurve;
00187     pt->firstCurve = this;
00188   }
00189 
00190   return CUBIT_SUCCESS;
00191 }
00192     
00193 
00194 CompositePoint* CompositeCurve::other_point( CompositePoint* pt )
00195 { 
00196   CompositePoint* sp = start_point();
00197   CompositePoint* ep = end_point();
00198   return (pt == sp) ? ep : (pt == ep) ? sp : 0;
00199 }
00200 
00201 CompositeCurve* CompositeCurve::split( Curve* curve )
00202 {
00203   int index = index_of( curve );
00204   if( (index < 0) || (index == (num_curves()-1)) )
00205     return 0;
00206   
00207   CompositeGeom* new_geom = compGeom->split( index );
00208   if( !new_geom )
00209     return 0;
00210     
00211   for( int i = 0; i < new_geom->num_entities(); i++ )
00212     new_geom->entity(i)->owner( 0 );
00213   
00214   return new CompositeCurve( new_geom );
00215 }
00216 
00217 
00218 CubitStatus CompositeCurve::combine( CompositeCurve* curve, bool prepend )
00219 {
00220   int start, stop;
00221   if ( prepend ) {
00222     start = 0;
00223     stop = curve->compGeom->num_entities();
00224   } else {
00225     start = compGeom->num_entities();
00226     stop = start + curve->compGeom->num_entities();
00227   }
00228   
00229   compGeom->merge( *(curve->compGeom), prepend );
00230   if( curve->hiddenSet )
00231     hidden_entities().merge( curve->hiddenSet );
00232     
00233   for( int i = start; i < stop; i++ )
00234   {
00235     TopologyBridge* bridge = compGeom->entity(i);
00236     assert( bridge->owner() == curve );
00237     bridge->owner(this);
00238   }
00239   
00240   return CUBIT_SUCCESS;
00241 }
00242 
00243 bool CompositeCurve::has_parent_composite_surface() const
00244 {
00245   CompositeCoEdge* coedge;
00246   for( coedge = first_coedge(); coedge; coedge = next_coedge(coedge) )
00247     if( coedge->get_loop() )
00248       return true;
00249   return false;
00250 }
00251   
00252 void CompositeCurve::reverse()
00253 {
00254   compGeom->reverse();
00255 }
00256 
00257 CompositePoint* CompositeCurve::common_point( CompositeCurve* curve )
00258 {
00259   CompositePoint* result = 0;
00260   CompositePoint* this_sp = start_point();
00261   CompositePoint* this_ep = end_point();
00262   CompositePoint* othr_sp = curve->start_point();
00263   CompositePoint* othr_ep = curve->end_point();
00264   
00265   if( this_sp == othr_sp || this_sp == othr_ep )
00266     result = this_sp;
00267   else if( this_ep == othr_sp || this_ep == othr_ep )
00268     result = this_ep;
00269   
00270   return result;
00271 }
00272 /*
00273 CompositeCoEdge* CompositeCurve::find_coedge( CompositeSurface* surface )
00274 {
00275   CoEdge* coedge = 0;
00276   while( coedge = next_coedge( coedge ) )
00277     if( coedge->get_loop() && coedge->get_loop()->get_surface() == surface )
00278       break;
00279   return coedge;
00280 }
00281 */
00282 CubitStatus CompositeCurve::add( CompositeCoEdge* coedge )
00283 {
00284   if( coedge->myCurve )  
00285   {
00286     assert(0);
00287     return CUBIT_FAILURE;
00288   }
00289   
00290   coedge->myCurve = this;
00291   coedge->nextOnCurve = firstCoEdge;
00292   firstCoEdge = coedge;
00293   
00294   return CUBIT_SUCCESS;
00295 }
00296 
00297 CubitStatus CompositeCurve::remove( CompositeCoEdge* coedge )
00298 {
00299   if( coedge->myCurve != this )
00300     return CUBIT_FAILURE;
00301   
00302   if( coedge == firstCoEdge )
00303   {
00304     firstCoEdge = coedge->nextOnCurve;
00305   }
00306   else
00307   {
00308     CompositeCoEdge *prev = firstCoEdge,
00309                     *next = firstCoEdge->nextOnCurve;
00310     while( next != coedge )
00311     {
00312       assert(next != NULL);
00313       prev = next;
00314       next = next->nextOnCurve;
00315     }
00316   
00317     prev->nextOnCurve = next->nextOnCurve;
00318   }
00319   
00320   coedge->nextOnCurve = 0;
00321   coedge->myCurve = 0;
00322   return CUBIT_SUCCESS;                
00323 }
00324 
00325 
00326 CubitBox CompositeCurve::bounding_box() const
00327 { return compGeom->bounding_box(); }
00328 
00329 double CompositeCurve::measure() 
00330 { return compGeom->measure(); }
00331 
00332 GeometryType CompositeCurve::geometry_type()
00333 {
00334   switch (num_curves()) {
00335     case 0  : return POINT_CURVE_TYPE;
00336     case 1  : return get_curve(0)->geometry_type();
00337     default : return UNDEFINED_CURVE_TYPE;
00338   }
00339 }
00340 
00341 GeometryQueryEngine* CompositeCurve::get_geometry_query_engine() const
00342 { return VirtualQueryEngine::instance(); }
00343 
00344 
00345 double CompositeCurve::start_param()
00346 { return 0; }
00347 
00348 double CompositeCurve::end_param()
00349 { return measure(); }
00350 
00351 CubitBoolean CompositeCurve::get_param_range( double& lower, double& upper )
00352 {
00353   lower = 0;
00354   upper = measure();
00355   return CUBIT_TRUE;
00356 }
00357 
00358 CubitBoolean CompositeCurve::is_periodic( double& period )
00359 {
00360   if (geometry_type() == POINT_CURVE_TYPE)
00361     return CUBIT_FALSE;
00362   
00363   if( startPoint == endPoint && num_curves() > 0 )
00364   {
00365     period = measure();
00366     return CUBIT_TRUE;
00367   }
00368   else
00369   {
00370     period = 0;
00371     return CUBIT_FALSE;
00372   }
00373 }
00374 
00375 CubitStatus CompositeCurve::position_from_u( double u, CubitVector& position )
00376 {
00377   int index;
00378   double ui;
00379   
00380   if (num_curves() == 0) // point curve
00381     return CUBIT_FAILURE;
00382   
00383   if( ! curve_param( u, ui, index ) || index < 0 )
00384     return CUBIT_FAILURE;
00385   
00386   Curve* curve_ptr = get_curve( index );
00387   return curve_ptr ? curve_ptr->position_from_u( ui, position ) : CUBIT_FAILURE;
00388 }  
00389 
00390 double CompositeCurve::u_from_position( const CubitVector& position )
00391 {
00392   if (num_curves() == 0) // point curve
00393     return 0.0;
00394   
00395   int index = closest_curve(position );
00396   double param = get_curve( index )->u_from_position( position );
00397   return composite_param( index, param );
00398 }
00399 
00400 double CompositeCurve::u_from_arc_length( double param, double length )
00401 { return param + length; }
00402 double CompositeCurve::length_from_u( double u1, double u2 )
00403 { return u2 - u1; }
00404 
00405 CubitStatus CompositeCurve::closest_point( const CubitVector& location,
00406                                            CubitVector& closest,
00407                                            CubitVector* tangent_ptr,
00408                                            CubitVector* curvature_ptr,
00409                                            double* param )
00410 {
00411   if (num_curves() == 0) // point curve
00412   {
00413     if (!startPoint)
00414       return CUBIT_FAILURE;
00415     
00416     closest = startPoint->coordinates();
00417     if (tangent_ptr)
00418       tangent_ptr->set(0.0,0.0,0.0);
00419     if (curvature_ptr)
00420       curvature_ptr->set(0.0,0.0,0.0);
00421     if (param)
00422       *param = 0.0;
00423   }
00424   
00425   if( compGeom->num_entities() == 1 )
00426   {
00427     CubitStatus result = get_curve(0)
00428       ->closest_point( location, closest, tangent_ptr, curvature_ptr, param );
00429 
00430     if( tangent_ptr && compGeom->sense(0) == CUBIT_REVERSED )
00431       *tangent_ptr *= -1.0;
00432     
00433     if( param )
00434       *param = composite_param( 0, *param );
00435       
00436     return result;
00437   }
00438   
00439   int index = closest_curve( location, &closest );
00440   Curve* curve = get_curve( index );
00441   if( tangent_ptr || curvature_ptr || param )
00442   {
00443     curve->closest_point( location, closest, tangent_ptr, 
00444                           curvature_ptr, param );
00445     if( param )
00446       *param = composite_param( index, *param );
00447     if( tangent_ptr && compGeom->sense(index) == CUBIT_REVERSED )
00448       *tangent_ptr *= -1.0;
00449   }
00450   
00451   return CUBIT_SUCCESS;
00452 }
00453 
00454 
00455 CubitStatus CompositeCurve::closest_point_trimmed( 
00456                                     const CubitVector& position,
00457                                     CubitVector& closest )
00458 {
00459   if (num_curves() == 0) 
00460     return closest_point( position, closest );
00461     
00462   if( compGeom->num_entities() == 1 )
00463     return get_curve(0)->closest_point_trimmed( position, closest );
00464   
00465   closest_curve( position, &closest );
00466   return CUBIT_SUCCESS;
00467 }
00468 
00469 CubitBoolean CompositeCurve::is_position_on( const CubitVector& position )
00470 {
00471     // point curve
00472   if (num_curves() == 0)
00473   {
00474     CompositePoint* point = start_point();
00475     double lensqr = (position - point->coordinates()).length_squared();
00476     return lensqr <= (GEOMETRY_RESABS*GEOMETRY_RESABS);
00477   }
00478   
00479   if( compGeom->num_entities() == 1 )
00480     return get_curve(0)->is_position_on( position );
00481   
00482   int index = closest_curve( position );
00483   return get_curve(index)->is_position_on( position );
00484 }
00485 
00486 CubitPointContainment CompositeCurve::point_containment( const CubitVector& point )
00487 {
00488   int index;
00489   
00490   if (num_curves() == 0) 
00491     return is_position_on(point) ? CUBIT_PNT_ON : CUBIT_PNT_OFF;
00492   
00493   for( index = 0; index < compGeom->num_entities(); index++ )
00494   {
00495     if( get_curve(index)->point_containment( point ) == CUBIT_PNT_ON )
00496       return CUBIT_PNT_ON;
00497   }
00498   
00499   return CUBIT_PNT_OFF;  //not on any Curve
00500 }
00501 
00502 CubitStatus CompositeCurve::get_point_direction( CubitVector& origin,
00503                                                  CubitVector& direction )
00504 {
00505   if (num_curves() == 0) // point curve
00506     return CUBIT_FAILURE;
00507   
00508   if( compGeom->num_entities() == 1 )
00509     return get_curve(0)->get_point_direction( origin, direction );
00510   
00511   int count = compGeom->num_entities();
00512   CubitVector* vect_list = new CubitVector[count];
00513   double RESABS_SQUARED = CUBIT_RESABS * CUBIT_RESABS;
00514   direction.set(0,0,0);
00515   for( int i = 0; i < count; i++ )
00516   {
00517     if( ! get_curve(i)->get_point_direction(origin,vect_list[i]) ||
00518         (vect_list[i].length_squared() < RESABS_SQUARED) )
00519     {
00520       delete [] vect_list;
00521       return CUBIT_FAILURE;
00522     }
00523     if( get_sense(i) == CUBIT_REVERSED )
00524       vect_list[i] *= -1;
00525     direction += vect_list[i];
00526   }
00527   //If we reach this point, then all of the underlying curves are linear.
00528   //Next check if they are colinear.
00529   if( direction.length_squared() < RESABS_SQUARED )
00530   {
00531     delete [] vect_list;
00532     return CUBIT_FAILURE;
00533   }
00534   CubitVector mean = ~direction;
00535   for( int j = 0; j < count; j++ )
00536   {
00537     if( fabs( 1 - (mean % ~vect_list[j]) ) > CUBIT_RESABS )
00538     {
00539       delete [] vect_list;
00540       return CUBIT_FAILURE;
00541     }
00542   }
00543   
00544   delete [] vect_list;
00545   get_curve(0)->get_point_direction(origin,direction);
00546   direction = mean;
00547   return CUBIT_SUCCESS;
00548 }
00549 
00550 CubitStatus CompositeCurve::get_interior_extrema( 
00551                                     DLIList<CubitVector*>& interior_points,
00552                                     CubitSense& return_sense )
00553 {
00554   return_sense = CUBIT_FORWARD;
00555   if (num_curves() == 0) // point curve
00556     return CUBIT_SUCCESS;
00557 
00558     // Go through each curve in the composite
00559   DLIList<CubitVector*> curve_point_list;
00560   for (int i = compGeom->num_entities() - 1; i >= 0; i--)
00561   {
00562       // Get the next curve's extrema
00563     Curve* cur_curve = get_curve(i);
00564     cur_curve->get_interior_extrema(curve_point_list,return_sense);
00565       // See which order to put them into the return list
00566     if (return_sense == get_sense(i))
00567     {
00568       interior_points += curve_point_list;
00569     }
00570     else
00571     {
00572       curve_point_list.last();
00573       for (int j = curve_point_list.size(); j--; )
00574         interior_points.append(curve_point_list.get_and_back());
00575     }
00576       // Unless this is the last curve, put in the point
00577       // between this and the next curve
00578     if (i != 0)
00579     {
00580       CubitVector* endpoint = new CubitVector(0,0,0);
00581       if (get_sense(i) == CUBIT_FORWARD)
00582         cur_curve->position_from_u(cur_curve->end_param(), *endpoint);
00583       else
00584         cur_curve->position_from_u(cur_curve->end_param(), *endpoint);
00585       interior_points.append(endpoint);
00586     }
00587       // clean out the list for the next curve
00588     curve_point_list.clean_out();
00589   }
00590 
00591   return CUBIT_SUCCESS;
00592 }
00593 
00594 CubitStatus CompositeCurve::get_center_radius( CubitVector& c, double& r )
00595 {
00596   if (num_curves() == 0) // point curve
00597     return CUBIT_FAILURE;
00598   
00599   if (!get_curve(0)->get_center_radius(c,r) )
00600     return CUBIT_FAILURE;
00601     
00602   for (int i = compGeom->num_entities() - 1; i > 0; i-- )
00603   {
00604     CubitVector c2;
00605     double r2;
00606     if (!get_curve(i)->get_center_radius(c2,r2) ||
00607         fabs(r - r2) > GEOMETRY_RESABS ||
00608         (c2 - c).length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS)
00609     {
00610       return CUBIT_FAILURE;
00611     }
00612   }
00613   return CUBIT_SUCCESS;
00614 }
00615   
00616 CubitBoolean CompositeCurve::G1_discontinuous( double param,
00617   CubitVector* minus_tangent, CubitVector* plus_tangent )
00618 {
00619   if (num_curves() == 0) // point curve
00620     return CUBIT_FALSE;
00621   
00622   const double half_resabs = CUBIT_RESABS / 2.0;
00623   double curve_param;
00624   int curve_index;
00625   CubitStatus s = this->curve_param( param, curve_param, curve_index );
00626   if( ! s )
00627   {
00628     PRINT_ERROR("Parameter %f out of range [%f,%f] in "
00629      "CompositeCurve::G1_discontinous(..)\n",param,start_param(),end_param());
00630     return CUBIT_FALSE;
00631   }
00632   
00633   CubitVector tan1, tan2, location, cp;
00634   CubitBoolean result = CUBIT_FALSE;
00635   if( (curve_index > 0) && 
00636       (fabs(compGeom->measure(curve_index-1) - param) < half_resabs) )
00637   {
00638     get_curve( curve_index )->position_from_u( curve_param, location );
00639     get_curve( curve_index-1 )->closest_point( location, cp, &tan1 );
00640     if( get_sense( curve_index-1 ) == CUBIT_REVERSED ) tan1 *= -1.0;
00641     get_curve( curve_index   )->closest_point( location, cp, &tan2 );
00642     if( get_sense( curve_index   ) == CUBIT_REVERSED ) tan2 *= -1.0;
00643     double cross = (tan1 * tan2).length_squared();
00644     double sum   = (tan1 + tan2).length_squared();
00645     double diff  = (tan1 - tan2).length_squared();
00646     if( (cross > CUBIT_RESABS) || (sum < diff) )
00647     {
00648       if( minus_tangent ) *minus_tangent = tan1;
00649       if( plus_tangent ) *plus_tangent = tan2;
00650       result = CUBIT_TRUE;
00651     }
00652     else
00653       result = CUBIT_FALSE;
00654     
00655   }
00656   else if( (curve_index < (compGeom->num_entities()-1)) &&
00657            (fabs(compGeom->measure(curve_index) - param) < half_resabs) )
00658   {
00659     get_curve( curve_index )->position_from_u( curve_param, location );
00660     get_curve( curve_index   )->closest_point( location, cp, &tan1 );
00661     if( get_sense( curve_index   ) == CUBIT_REVERSED ) tan1 *= -1.0;
00662     get_curve( curve_index+1 )->closest_point( location, cp, &tan2 );
00663     if( get_sense( curve_index+1 ) == CUBIT_REVERSED ) tan2 *= -1.0;
00664     double cross = (tan1 * tan2).length_squared();
00665     double sum   = (tan1 + tan2).length_squared();
00666     double diff  = (tan1 - tan2).length_squared();
00667     if( (cross > CUBIT_RESABS) || (sum < diff) )
00668     {
00669       if( minus_tangent ) *minus_tangent = tan1;
00670       if( plus_tangent ) *plus_tangent = tan2;
00671       result = CUBIT_TRUE;
00672     }
00673     else
00674       result = CUBIT_FALSE;
00675   }
00676   else if( get_sense(curve_index) == CUBIT_FORWARD )
00677   {
00678     result = get_curve( curve_index )
00679       ->G1_discontinuous( curve_param, minus_tangent, plus_tangent );
00680   }
00681   else
00682   {
00683     result = get_curve( curve_index )
00684       ->G1_discontinuous( curve_param, plus_tangent, minus_tangent );
00685     if( result )
00686     {
00687       if( plus_tangent )  *plus_tangent  *= -1.0;
00688       if( minus_tangent) *minus_tangent *= -1.0;
00689     }
00690   }
00691   return result;  
00692 }
00693 
00694 
00695 int CompositeCurve::closest_curve( const CubitVector& location,
00696                                    CubitVector *point )
00697 {  
00698   double shortest_distance_sqr, current_distance_sqr;
00699   CubitVector closest_point, current_point;
00700   int closest_curve, current_curve;
00701   
00702   closest_curve = compGeom->closest_box( location );
00703   
00704   get_curve( closest_curve )->closest_point_trimmed( location, closest_point );
00705   shortest_distance_sqr = (location - closest_point).length_squared();
00706   
00707   while( ( current_curve = compGeom->next_box_within_dist( shortest_distance_sqr ) ) >= 0 )
00708   {
00709     get_curve( current_curve )->closest_point_trimmed( location, current_point );
00710     current_distance_sqr = (location - current_point).length_squared();
00711     if( current_distance_sqr < shortest_distance_sqr )
00712     {
00713       closest_curve = current_curve;
00714       shortest_distance_sqr = current_distance_sqr;
00715       closest_point = current_point;
00716     }
00717   }
00718     
00719   if( point ) *point = closest_point;
00720   return closest_curve;
00721 }
00722 
00723 
00724 
00725 //-------------------------------------------------------------------------
00726 // Purpose       : Parameter Conversion
00727 //
00728 // Special Notes : 
00729 //
00730 // Creator       : Jason Kraftcheck 
00731 //
00732 // Creation Date : 06/08/98
00733 //-------------------------------------------------------------------------
00734 double CompositeCurve::composite_param( int index, double u ) const
00735 {
00736   if( (index < 0) || (index >= compGeom->num_entities()) ) return -1.0;
00737   Curve* curve_ptr = get_curve( index );
00738   double sum = lengthUntilI( index );
00739 
00740   double u_min, u_max;
00741   curve_ptr->get_param_range( u_min, u_max );
00742 
00743   CubitSense sense = this->get_sense(index);
00744   double root_param = (sense == CUBIT_FORWARD) ? u_min : u_max;
00745   double lfu = (root_param < u) ?
00746     curve_ptr->length_from_u( root_param, u ) :
00747     curve_ptr->length_from_u( u, root_param );
00748   return sum + fabs( lfu );
00749 }
00750   
00751   
00752 CubitStatus CompositeCurve::curve_param( double uc, double& ui, int& index ) const
00753 {
00754   double sum = 0.0, period;
00755   if( const_cast<CompositeCurve*>(this)->is_periodic(period) )
00756     fixup_periodic_param( uc );
00757 
00758   int max = compGeom->num_entities();
00759   int min = 0;
00760   index = max / 2;
00761   sum = lengthUntilI( max - 1);
00762   if( uc >= sum ) index = max - 1;
00763   else while( min != max )
00764   {
00765     sum = lengthUntilI(index);
00766     if( sum > uc )
00767       max = index;
00768     else if( lengthUntilI(index+1) > uc ) 
00769       break;
00770     else 
00771       min = index;
00772     
00773     index = (min + max) / 2;
00774   }
00775       
00776   if( index >= compGeom->num_entities() ) return CUBIT_FAILURE;
00777 
00778   double start_param, end_param;
00779   get_curve(index)->get_param_range( start_param, end_param );
00780 
00781   double arc_len = uc - sum;
00782   if( get_sense(index) == CUBIT_REVERSED ) 
00783     arc_len = get_curve(index)->measure() - arc_len;
00784 
00785   ui = get_curve(index)->u_from_arc_length( start_param, arc_len );
00786   return CUBIT_SUCCESS;
00787 }
00788 
00789 
00790 
00791 
00792 //-------------------------------------------------------------------------
00793 // Purpose       : Calculate the sum of the lengths of curves 0 to i-1.
00794 //
00795 // Special Notes : 
00796 //
00797 // Creator       : Jason Kraftcheck 
00798 //
00799 // Creation Date : 06/09/98
00800 //-------------------------------------------------------------------------
00801 double CompositeCurve::lengthUntilI( int i ) const
00802 {
00803   assert( i >= 0 && i < compGeom->num_entities() );
00804   return ( i == 0 ) ? 0.0 : compGeom->measure(i - 1);
00805 }
00806 
00807 //-------------------------------------------------------------------------
00808 // Purpose       : TopologyBridge queries
00809 //
00810 // Special Notes : 
00811 //
00812 // Creator       : Jason Kraftcheck
00813 //
00814 // Creation Date : 03/04/02
00815 //-------------------------------------------------------------------------
00816 void CompositeCurve::get_parents_virt( DLIList<TopologyBridge*>& list )
00817 { 
00818   for( CompositeCoEdge* coedge = firstCoEdge; 
00819        coedge != 0;
00820        coedge = coedge->nextOnCurve )
00821     if (!dynamic_cast<HiddenEntitySet*>(coedge->owner()))
00822       list.append( coedge );
00823   
00824   if (stitchNext)
00825     stitchNext->get_parents_virt(list);
00826 }
00827 void CompositeCurve::get_children_virt( DLIList<TopologyBridge*>& list )
00828 {
00829   CompositePoint* sp = start_point();
00830   CompositePoint* ep = end_point();
00831   
00832   if( sp ) 
00833     list.append( sp );
00834   if( ep && ep != sp )
00835     list.append( ep );
00836 }
00837 
00838 //-------------------------------------------------------------------------
00839 // Purpose       : TBOwner methods
00840 //
00841 // Special Notes : 
00842 //
00843 // Creator       : Jason Kraftcheck
00844 //
00845 // Creation Date : 03/04/02
00846 //-------------------------------------------------------------------------
00847 CubitStatus CompositeCurve::remove_bridge( TopologyBridge* bridge )
00848 {
00849   int i = compGeom->index_of(bridge);
00850   if ( i >= 0 )
00851   {
00852     bridge->owner(0);
00853     if ( !compGeom->remove(i,true) )
00854       return CUBIT_FAILURE;
00855 
00856     if (compGeom->num_entities() == 0)
00857       CompositeEngine::instance().notify_deactivated(this);
00858     HadBridgeRemoved = 1;
00859     return CUBIT_SUCCESS;
00860   }
00861   else
00862   {
00863     for (CompositeCurve* ptr = this; ptr->stitchNext; ptr = ptr->stitchNext)
00864     {
00865       if (ptr->stitchNext == bridge)
00866       {
00867         ptr->stitchNext = ((CompositeCurve*)bridge)->stitchNext;
00868 HadBridgeRemoved = 1;
00869         return CUBIT_SUCCESS;
00870       }
00871     }
00872   }
00873   
00874   return CUBIT_FAILURE;
00875 }
00876 
00877 Curve* CompositeCurve::remove_curve( int index )
00878 {
00879   Curve* curve = get_curve(index);
00880   if (!curve || !compGeom->remove(index,false) )
00881     return 0;
00882   curve->owner(0);
00883   return curve;
00884 }
00885 
00886   
00887 
00888 CubitStatus CompositeCurve::swap_bridge( TopologyBridge* o,
00889                                          TopologyBridge* n,
00890                                          bool reversed )
00891 {
00892   int i = compGeom->index_of(o);
00893   GeometryEntity* ge = dynamic_cast<GeometryEntity*>(n);
00894   if( i >= 0 && ge != 0 )
00895   {
00896     o->owner(0);
00897     n->owner(this);
00898     if ( ! compGeom->swap( i, ge ) )
00899       return CUBIT_FAILURE;
00900     
00901     if (reversed)
00902       compGeom->reverse_sense(i);
00903     return CUBIT_SUCCESS;
00904   }
00905   else
00906     return CUBIT_FAILURE;
00907 }
00908 CubitBoolean CompositeCurve::contains_bridge( TopologyBridge* bridge ) const
00909 {
00910   if (!compGeom)
00911     return CUBIT_FALSE;
00912   
00913   return (CubitBoolean)(compGeom->index_of(bridge) >= 0);
00914 }
00915 
00916 
00917 //-------------------------------------------------------------------------
00918 // Purpose       : Attach a CubitSimpleAttribute
00919 //
00920 // Special Notes : 
00921 //
00922 // Creator       : Jason Kraftcheck
00923 //
00924 // Creation Date : 03/10/98
00925 //-------------------------------------------------------------------------
00926 void CompositeCurve::append_simple_attribute_virt(
00927                 const CubitSimpleAttrib& simple_attrib_ptr )
00928 {
00929   if(compGeom)
00930     compGeom->add_attribute( simple_attrib_ptr );
00931 }
00932 
00933 //-------------------------------------------------------------------------
00934 // Purpose       : Remove an attached CubitSimpleAttrib
00935 //
00936 // Special Notes : 
00937 //
00938 // Creator       : Jason Kraftcheck
00939 //
00940 // Creation Date : 03/10/98
00941 //-------------------------------------------------------------------------
00942 void CompositeCurve::remove_simple_attribute_virt(
00943                 const CubitSimpleAttrib& simple_attrib_ptr )
00944 {
00945   if(compGeom)
00946     compGeom->rem_attribute( simple_attrib_ptr );
00947 }
00948 
00949 
00950 //-------------------------------------------------------------------------
00951 // Purpose       : Remove an all attached CubitSimpleAttrib
00952 //
00953 // Special Notes : 
00954 //
00955 // Creator       : Greg Nielson
00956 //
00957 // Creation Date : 07/10/98
00958 //-------------------------------------------------------------------------
00959 void CompositeCurve::remove_all_simple_attribute_virt()
00960 {
00961   if(compGeom)
00962     compGeom->rem_all_attributes( );
00963 }
00964 
00965 
00966 //-------------------------------------------------------------------------
00967 // Purpose       : Return the attached CubitSimpleAttribs.
00968 //
00969 // Special Notes : 
00970 //
00971 // Creator       : Jason Kraftcheck
00972 //
00973 // Creation Date : 03/10/98
00974 //-------------------------------------------------------------------------
00975 CubitStatus CompositeCurve::get_simple_attribute(
00976                DLIList<CubitSimpleAttrib>& attrib_list )
00977 {
00978   if(!compGeom)
00979     return CUBIT_FAILURE;
00980   compGeom->get_attributes( attrib_list );
00981   return CUBIT_SUCCESS;
00982 }
00983 
00984 
00985 
00986 //-------------------------------------------------------------------------
00987 // Purpose       : Get attribs by name
00988 //
00989 // Special Notes : 
00990 //
00991 // Creator       : Jason Kraftcheck
00992 //
00993 // Creation Date : 03/03/03
00994 //-------------------------------------------------------------------------
00995 CubitStatus CompositeCurve::get_simple_attribute(
00996           const CubitString& name, DLIList<CubitSimpleAttrib>& attrib_list )
00997 {
00998   if(!compGeom)
00999     return CUBIT_FAILURE;
01000   compGeom->get_attributes( name.c_str(), attrib_list );
01001   return CUBIT_SUCCESS;
01002 }
01003 
01004 void CompositeCurve::fixup_periodic_param( double& param ) const
01005 {
01006   if(!compGeom)
01007     return;
01008   double period = compGeom->measure();
01009   if( param < 0.0 )
01010     param = period - param;
01011   if( param >= period )
01012     param = fmod( param, period );
01013 }
01014 
01015 //-------------------------------------------------------------------------
01016 // Purpose       : Write attributes to underlying geometry entity
01017 //
01018 // Special Notes : Special case for point-curves
01019 //
01020 // Creator       : Jason Kraftcheck
01021 //
01022 // Creation Date : 02/28/04
01023 //-------------------------------------------------------------------------
01024 void CompositeCurve::write_attributes()
01025 {
01026   if (num_curves()) // not a point-curve
01027   {
01028     compGeom->write_attributes();
01029   }
01030   else
01031   {
01032     CompositePoint* point = start_point();
01033     assert(point == end_point());
01034     compGeom->write_attributes(point);
01035   }
01036 }
01037 
01038 //-------------------------------------------------------------------------
01039 // Purpose       : Read attributes from underlying geometry
01040 //
01041 // Special Notes : 
01042 //
01043 // Creator       : Jason Kraftcheck
01044 //
01045 // Creation Date : 02/28/04
01046 //-------------------------------------------------------------------------
01047 void CompositeCurve::read_attributes()
01048 {
01049   if (num_curves()) // not a point-curve
01050   {
01051     compGeom->read_attributes();
01052   }
01053   else
01054   {
01055     CompositePoint* point = start_point();
01056     assert(point == end_point());
01057     compGeom->read_attributes(point);
01058   }
01059 }
01060 
01061 
01062 void CompositeCurve::get_hidden_points( DLIList<TBPoint*>& points )
01063 {
01064   if( hiddenSet )
01065   {
01066     hiddenSet->hidden_points( points );
01067   }
01068 }
01069 
01070 
01071 
01072 void CompositeCurve::print_debug_info( const char* prefix, 
01073                                        bool brief ) const
01074 {
01075   if( prefix == 0 ) prefix = "";
01076   
01077   if ( brief )
01078   {
01079 #ifdef TOPOLOGY_BRIDGE_IDS
01080     PRINT_INFO("%sCompositeCurve %d : points (%d,%d) ", prefix, get_id(),
01081       startPoint ? startPoint->get_id() : -1, endPoint ? endPoint->get_id() : -1 );
01082     if ( num_curves() == 1 )
01083       PRINT_INFO(": %s %d\n", fix_type_name(typeid(*get_curve(0)).name()), get_curve(0)->get_id());
01084     else
01085       PRINT_INFO(": %d curves.\n", num_curves() );
01086 #else
01087     PRINT_INFO("%sCompositeCurve %p : points (%p,%p) ", prefix, (void*)this,
01088       (void*)startPoint, (void*)endPoint );
01089     if ( num_curves() == 1 )
01090       PRINT_INFO(": %s %p\n", fix_type_name(typeid(*get_curve(0)).name()), (void*)get_curve(0));
01091     else
01092       PRINT_INFO(": %d curves.\n", num_curves() );
01093 #endif
01094     return;
01095   }
01096     
01097   char* new_prefix = new char[strlen(prefix)+3];
01098   strcpy( new_prefix, prefix );
01099   strcat( new_prefix, "  ");
01100   
01101 #ifdef TOPOLOGY_BRIDGE_IDS
01102   PRINT_INFO("%sCompositeCurve %d\n", prefix, get_id() );
01103 #else
01104   PRINT_INFO("%sCompositeCurve %p\n", prefix, (void*)this );
01105 #endif
01106   compGeom->print_debug_info( new_prefix );
01107   if( hiddenSet ) hiddenSet->print_debug_info( new_prefix );
01108   else PRINT_INFO("%s  No Hidden Entities.\n", prefix );
01109   
01110   CompositeCoEdge* coedge = first_coedge();
01111   DLIList<TopologyBridge*> loops(1), surface_list(1);
01112   
01113   while( coedge )
01114   {
01115     TopologyBridge* surf_ptr = 0;
01116     loops.clean_out();
01117     surface_list.clean_out();
01118     coedge->get_parents_virt(loops);
01119     if ( loops.size() == 1 )
01120     {
01121       loops.get()->get_parents_virt(surface_list);
01122       if( surface_list.size() == 1 )
01123         surf_ptr = surface_list.get();
01124     }
01125 
01126 #ifdef TOPOLOGY_BRIDGE_IDS
01127     PRINT_INFO("%s  %s on Surface %d\n", prefix, 
01128       coedge->sense() == CUBIT_FORWARD ? "FORWARD" :
01129       coedge->sense() == CUBIT_REVERSED ? "REVERSE" : "UNKNOWN",
01130       surf_ptr->get_id() );
01131 #else
01132     PRINT_INFO("%s  %s on Surface %p\n", prefix, 
01133       coedge->sense() == CUBIT_FORWARD ? "FORWARD" :
01134       coedge->sense() == CUBIT_REVERSED ? "REVERSE" : "UNKNOWN",
01135       (void*)surf_ptr );
01136 #endif
01137 
01138     if (!coedge->get_loop())
01139       coedge->print_debug_info( new_prefix, true );
01140     coedge = next_coedge(coedge);
01141   }
01142   
01143   if ( !start_point() )
01144     PRINT_INFO("%s  NULL START POINT\n", prefix );
01145   else
01146     start_point()->print_debug_info( new_prefix, true );
01147   
01148   if ( !end_point() )
01149     PRINT_INFO("%s  NULL END POINT\n", prefix );
01150   else if ( end_point() == start_point() )
01151     PRINT_INFO("%s  end point SAME as start point\n", prefix ); 
01152   else
01153     end_point()->print_debug_info( new_prefix, true );
01154   
01155   delete [] new_prefix;
01156 }
01157 
01158 
01159 //-------------------------------------------------------------------------
01160 // Purpose       : Update composite for change in sense of underlying curve
01161 //
01162 // Special Notes : 
01163 //
01164 // Creator       : Jason Kraftcheck
01165 //
01166 // Creation Date : 
01167 //-------------------------------------------------------------------------
01168 void CompositeCurve::notify_reversed( TopologyBridge* bridge )
01169 {
01170   int index = compGeom->index_of(bridge);
01171   if( index >= 0 )
01172     compGeom->reverse_sense(index);
01173 }
01174 
01175 //-------------------------------------------------------------------------
01176 // Purpose       : Merge
01177 //
01178 // Special Notes : 
01179 //
01180 // Creator       : Jason Kraftcheck
01181 //
01182 // Creation Date : 12/02/02
01183 //-------------------------------------------------------------------------
01184 CubitStatus CompositeCurve::stitch( CompositeCurve* dead )
01185 {
01186     // check to make sure end points are already stitched.
01187   bool reversed;
01188   
01189   if( dead->start_point() == this->start_point() )
01190     reversed = false;
01191   else if( dead->end_point() == this->start_point() )
01192     reversed = true;
01193   else
01194     return CUBIT_FAILURE;
01195   
01196   if( ( reversed && (dead->start_point() != this->end_point())) ||
01197       (!reversed && (dead->end_point()   != this->end_point())) )
01198     return CUBIT_FAILURE;
01199 
01200     // shouldn't be merging hidden curves
01201   if( dynamic_cast<CompositeCurve*>(this->owner()) ||
01202       dynamic_cast<CompositeCurve*>(dead->owner()) )
01203   {
01204     assert(0);
01205     return CUBIT_FAILURE;
01206   }
01207   
01208     // DAG / next level up should already be merged
01209   if( dead->owner() != this->owner() )
01210   {
01211     assert(0);
01212     return CUBIT_FAILURE;
01213   }
01214   
01215     // update owner 
01216   if( dead->owner() )
01217     dead->owner()->notify_merged( dead, this );
01218   assert( !dead->owner() );
01219   dead->owner( this );
01220   
01221     // merge lists
01222   CompositeCurve* end = dead;
01223   while (end->stitchNext) 
01224   {
01225     end->stitchNext->owner( this );
01226     end = end->stitchNext;
01227   }
01228   end->stitchNext = stitchNext;
01229   stitchNext = end;
01230   
01231   return CUBIT_SUCCESS;
01232 }
01233       
01234 //-------------------------------------------------------------------------
01235 // Purpose       : Get the visible curve of a set of stitched curves
01236 //
01237 // Special Notes : 
01238 //
01239 // Creator       : Jason Kraftcheck
01240 //
01241 // Creation Date : 12/02/02
01242 //-------------------------------------------------------------------------
01243 CompositeCurve* CompositeCurve::primary_stitched_curve()
01244 {
01245   CompositeCurve* result = dynamic_cast<CompositeCurve*>(owner());
01246   return result ? result : this;
01247 }
01248 
01249 //-------------------------------------------------------------------------
01250 // Purpose       : Is this curve stitched with any others
01251 //
01252 // Special Notes : 
01253 //
01254 // Creator       : Jason Kraftcheck
01255 //
01256 // Creation Date : 12/02/02
01257 //-------------------------------------------------------------------------
01258 bool CompositeCurve::is_stitched()
01259 {
01260   return stitchNext || dynamic_cast<CompositeCurve*>(owner());
01261 }
01262 
01263 //-------------------------------------------------------------------------
01264 // Purpose       : Get list of stitched curves
01265 //
01266 // Special Notes : 
01267 //
01268 // Creator       : Jason Kraftcheck
01269 //
01270 // Creation Date : 12/16/02
01271 //-------------------------------------------------------------------------
01272 void CompositeCurve::get_stitched( DLIList<CompositeCurve*>& list )
01273 {
01274   for (CompositeCurve* curve = primary_stitched_curve();
01275        curve; curve = curve->stitchNext)
01276     list.append( curve );
01277 }
01278 
01279 //-------------------------------------------------------------------------
01280 // Purpose       : Remove all stitched curves
01281 //
01282 // Special Notes : 
01283 //
01284 // Creator       : Jason Kraftcheck
01285 //
01286 // Creation Date : 12/02/02
01287 //-------------------------------------------------------------------------
01288 void CompositeCurve::unstitch_all()
01289 {
01290     // should only call on visible curve
01291   assert (this == primary_stitched_curve());
01292   
01293   while (stitchNext)
01294   {
01295     stitchNext->owner(0);
01296     if (owner())
01297       owner()->notify_copied( stitchNext, this );
01298     stitchNext = stitchNext->stitchNext;
01299   }
01300 }
01301 
01302   
01303 //-------------------------------------------------------------------------
01304 // Purpose       : Update for split in underlying curve
01305 //
01306 // Special Notes : 
01307 //
01308 // Creator       : Jason Kraftcheck
01309 //
01310 // Creation Date : 12/19/02
01311 //-------------------------------------------------------------------------
01312 void CompositeCurve::notify_split( TopologyBridge* new_bridge,
01313                                    TopologyBridge* old_bridge )
01314 {
01315   Curve* old_curve = dynamic_cast<Curve*>(old_bridge);
01316   Curve* new_curve = dynamic_cast<Curve*>(new_bridge);
01317   assert( old_curve && new_curve && index_of(old_curve) >= 0 );
01318   
01319     // get start and end points
01320   DLIList<TopologyBridge*> bridges;
01321   old_curve->get_children(bridges,true,old_curve->layer());
01322   bridges.reset();
01323   TBPoint* old_start = dynamic_cast<TBPoint*>(bridges.get());
01324   TBPoint* old_end   = dynamic_cast<TBPoint*>(bridges.next());
01325   bridges.clean_out();
01326   new_curve->get_children(bridges,true,new_curve->layer());
01327   TBPoint* new_start = dynamic_cast<TBPoint*>(bridges.get());
01328   TBPoint* new_end   = dynamic_cast<TBPoint*>(bridges.next());
01329   bridges.clean_out();
01330 
01331   
01332     // find new point
01333   bool sp = (new_start == old_start || new_start == old_end);
01334 #ifndef NDEBUG
01335   bool ep = (new_end   == old_start || new_end   == old_end);
01336   assert( ep != sp ); // one must be true and one must be false
01337 #endif
01338   TBPoint* new_pt = sp ? new_start : new_end;
01339   
01340     // find relative sense of curves
01341   int old_index = index_of(old_curve);
01342   bool is_start = (old_start == new_pt);
01343   bool is_forward = (get_sense(old_index) == CUBIT_FORWARD);
01344   bool prepend = (is_start == is_forward);
01345   is_start = (new_start == new_pt);
01346   assert( is_start || new_pt == new_end );
01347   bool reversed = (is_start == prepend);
01348   
01349   CompositePoint* new_cpt = new CompositePoint(new_pt);
01350   
01351   hidden_entities().hide(new_cpt);
01352   
01353   CubitSense new_sense = reversed ? CUBIT_REVERSED : CUBIT_FORWARD;
01354   int insert_index = old_index;
01355   if( !prepend ) insert_index++;
01356   if( ! compGeom->insert( insert_index, new_curve, new_sense ) )
01357   {
01358     assert(0);
01359     delete new_cpt;
01360     return;
01361   }
01362   new_curve->owner(this);
01363   
01364   DLIList<CoEdgeSM*> new_coedges, old_coedges;
01365   bridges.clean_out();
01366   new_curve->get_parents_virt( bridges );
01367   CAST_LIST( bridges, new_coedges, CoEdgeSM );
01368   assert(bridges.size() == new_coedges.size());
01369   bridges.clean_out();
01370   old_curve->get_parents_virt( bridges );
01371   CAST_LIST( bridges, old_coedges, CoEdgeSM );
01372   assert(bridges.size() == old_coedges.size());
01373   
01374   for( CompositeCoEdge* coedge = first_coedge();
01375        coedge;
01376        coedge = next_coedge(coedge) )
01377   {
01378       // for each coedge of the old curve
01379     int i;
01380     CoEdgeSM* old_coedge = 0;
01381     for( i = 0; i < coedge->num_coedges(); i++ )
01382     {
01383       old_coedge = coedge->get_coedge(i);
01384       if( old_coedges.is_in_list(old_coedge) )
01385         break;
01386     }
01387     assert(i < coedge->num_coedges() && old_coedge);
01388     
01389     bridges.clean_out();
01390     old_coedge->get_parents_virt(bridges);
01391     assert(bridges.size() == 1);
01392     LoopSM* loopsm = dynamic_cast<LoopSM*>(bridges.get());
01393     assert(0 != loopsm);
01394       
01395     bridges.clean_out();
01396     loopsm->get_children(bridges, true, old_curve->layer());
01397     bridges.move_to(old_coedge);
01398     assert(bridges.get() == old_coedge);
01399       
01400       // Determine if new_coedge (the one we are looking for)
01401       // should occur before or after old_coedge in the loop.
01402       // If new_curve is after old_curve (old_end == new_pt), 
01403       // then the we want the coedge after old_coedge iff the
01404       // sense of old_coedge is forward, otherwise the one before.
01405       // Invert that if new_curve is before old_curve (old_start
01406       // == new_pt).
01407     bool coe_reversed = (old_coedge->sense() == CUBIT_REVERSED);
01408     bool curve_prepend = (old_start == new_pt);
01409     bool previous = coe_reversed != curve_prepend;
01410     CoEdgeSM* new_coedge = 
01411       dynamic_cast<CoEdgeSM*>(previous ? bridges.prev() : bridges.next());
01412     assert(new_coedges.is_in_list(new_coedge));
01413     
01414     CubitStatus s = coedge->insert_coedge(insert_index, new_coedge);
01415     assert(s);
01416     if (CUBIT_SUCCESS != s) {
01417       PRINT_ERROR("Failed to insert a new coedge.\n");
01418       return;
01419     }
01420   }
01421 }
01422 
01423 CubitStatus CompositeCurve::get_spline_params
01424 (
01425   bool &rational,    // return true/false
01426   int &degree,       // the degree of this spline
01427   DLIList<CubitVector> &cntrl_pts,  // xyz position of controlpoints
01428   DLIList<double> &cntrl_pt_weights, // if rational, a weight for each cntrl point.
01429   DLIList<double> &knots,   // There should be order+cntrl_pts.size()-2 knots
01430   bool &spline_is_reversed
01431 ) const
01432 {
01433   PRINT_ERROR("Currently, Cubit is unable to determine spline parameters for CompositeCurves.\n");
01434   return CUBIT_FAILURE;
01435 }
01436 
01437 CubitStatus CompositeCurve::get_ellipse_params
01438 (
01439   CubitVector &center_vec,
01440   CubitVector &normal,
01441   CubitVector &major_axis,
01442   double &radius_ratio
01443 ) const
01444 {
01445   PRINT_ERROR("Currently, Cubit is unable to determine ellipse parameters for CompositeCurves.\n");
01446   return CUBIT_FAILURE;
01447 }
01448 
01449 /*
01450 void CompositeCurve::draw( int color )
01451 {
01452   int num_pts;
01453   GMem gmem;
01454   
01455   if (!VirtualQueryEngine::instance()->get_graphics(this, num_pts, &gmem))
01456     return;
01457   
01458     GfxDebug::draw_polyline( gmem.point_list(),
01459                              gmem.pointListCount,
01460                              color );
01461     GfxDebug::flush();
01462 }
01463 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines