root/cgm/trunk/geom/virtual/CompositeCurve.cpp

Revision 1040, 37.8 KB (checked in by tautges, 2 years ago)

Version 10.2 of cgm.

  • Property svn:executable set to *
Line 
1//-------------------------------------------------------------------------
2// Filename      : CompositeCurve.cpp
3//
4// Purpose       : Geometry defined as the joining of a chain of curves.
5//
6// Special Notes :
7//
8// Creator       : Jason Kraftcheck
9//
10// Creation Date : 12/19/01
11//-------------------------------------------------------------------------
12
13#include <math.h>
14
15#include "CompositeCurve.hpp"
16#include "CompositeCoEdge.hpp"
17#include "CompositeLoop.hpp"
18#include "CompositePoint.hpp"
19#include "VirtualQueryEngine.hpp"
20#include "CompositeEngine.hpp"
21
22//#include "GfxDebug.hpp"
23#include "GMem.hpp"
24
25//-------------------------------------------------------------------------
26// Purpose       : Constructor
27//
28// Special Notes :
29//
30// Creator       : Jason Kraftcheck
31//
32// Creation Date : 12/19/01
33//-------------------------------------------------------------------------
34CompositeCurve::CompositeCurve( Curve* curve )
35  : hiddenSet(0), 
36    firstCoEdge(0),
37    startPoint(0), 
38    endPoint(0), 
39    startNext(0), 
40    endNext(0),
41    stitchNext(0),
42    HadBridgeRemoved(0)
43{
44  compGeom = new CompositeGeom(1);
45  compGeom->append( curve, CUBIT_FORWARD );
46  if( curve->owner() )
47    curve->owner()->swap_bridge( curve, this, false );
48  curve->owner(this);
49}
50
51CompositeCurve::CompositeCurve( CompositeGeom* geometry )
52  : compGeom( geometry ),
53    hiddenSet( 0 ),
54    firstCoEdge( 0 ),
55    startPoint( 0 ),
56    endPoint( 0 ),
57    startNext( 0 ),
58    endNext( 0 ),
59    stitchNext(0),
60    HadBridgeRemoved(0)
61{
62  for( int i = 0; i < compGeom->num_entities(); i++ )
63  {
64    GeometryEntity* entity = compGeom->entity(i);
65    assert( !entity->owner() );
66    entity->owner(this);
67  }
68}
69
70//-------------------------------------------------------------------------
71// Purpose       : Point-curve constructor
72//
73// Special Notes :
74//
75// Creator       : Jason Kraftcheck
76//
77// Creation Date : 02/27/04
78//-------------------------------------------------------------------------
79CompositeCurve::CompositeCurve( CompositePoint* point )
80  : hiddenSet(0), 
81    firstCoEdge(0),
82    startPoint(0), 
83    endPoint(0), 
84    startNext(0), 
85    endNext(0),
86    stitchNext(0),
87    HadBridgeRemoved(0)
88{
89  compGeom = new CompositeGeom(1);
90  //compGeom->append( point, CUBIT_FORWARD );
91  start_point(point);
92  end_point(point);
93}
94
95
96CompositeCurve::~CompositeCurve()
97{
98  while( firstCoEdge )
99    remove( firstCoEdge );
100 
101  for( int i = 0; i < num_curves(); i++ )
102    if( get_curve(i)->owner() == this )
103      get_curve(i)->owner(0);
104     
105  start_point(0);
106  end_point(0);
107 
108  unstitch_all();
109 
110  delete hiddenSet;
111  delete compGeom;
112  hiddenSet = (HiddenEntitySet*)0xbdbdbdbd;
113  compGeom = (CompositeGeom*)0xbdbdbdbd;
114  assert(!startNext);
115  assert(!endNext);
116}
117
118
119CompositeCurve* CompositeCurve::next( const CompositePoint* around )
120{
121  return around == startPoint ? startNext :
122         around == endPoint ? endNext : 0;
123}
124
125CubitStatus CompositeCurve::start_point( CompositePoint* pt )
126{
127  return set_point( true, pt );
128}
129
130CubitStatus CompositeCurve::end_point( CompositePoint* pt )
131{
132  return set_point( false, pt );
133}
134
135CubitStatus CompositeCurve::set_point( bool start, CompositePoint* pt )
136{
137  CompositePoint*& my_point = start ? startPoint : endPoint;
138  CompositeCurve*& next_crv = start ? startNext : endNext;
139
140  if( pt == my_point )
141    return CUBIT_SUCCESS;
142 
143  if( my_point && startPoint != endPoint )
144  {
145    CompositeCurve* prev = my_point->firstCurve;
146    assert( prev != NULL );
147
148    if( prev == this )
149    {
150      my_point->firstCurve = next_crv;
151    }
152    else
153    {
154      CompositeCurve* curve = prev->next(my_point);
155      while( curve != this )
156      {
157        prev = curve;
158              curve = prev->next(my_point);
159      }
160     
161      if( prev->startPoint == my_point )
162      {
163        assert(prev->startNext == this);
164        prev->startNext = next_crv;
165      }
166     
167      if( prev->endPoint == my_point )
168      {
169        assert(prev->endNext == this);
170        prev->endNext = next_crv;
171      }
172    }
173  }
174
175  my_point = pt;
176  if (!pt)
177  {
178    next_crv = 0;
179  }
180  else if (startPoint == endPoint)
181  {
182    next_crv = start ? endNext : startNext;
183  }
184  else
185  {
186    next_crv = pt->firstCurve;
187    pt->firstCurve = this;
188  }
189
190  return CUBIT_SUCCESS;
191}
192   
193
194CompositePoint* CompositeCurve::other_point( CompositePoint* pt )
195{ 
196  CompositePoint* sp = start_point();
197  CompositePoint* ep = end_point();
198  return (pt == sp) ? ep : (pt == ep) ? sp : 0;
199}
200
201CompositeCurve* CompositeCurve::split( Curve* curve )
202{
203  int index = index_of( curve );
204  if( (index < 0) || (index == (num_curves()-1)) )
205    return 0;
206 
207  CompositeGeom* new_geom = compGeom->split( index );
208  if( !new_geom )
209    return 0;
210   
211  for( int i = 0; i < new_geom->num_entities(); i++ )
212    new_geom->entity(i)->owner( 0 );
213 
214  return new CompositeCurve( new_geom );
215}
216
217
218CubitStatus CompositeCurve::combine( CompositeCurve* curve, bool prepend )
219{
220  int start, stop;
221  if ( prepend ) {
222    start = 0;
223    stop = curve->compGeom->num_entities();
224  } else {
225    start = compGeom->num_entities();
226    stop = start + curve->compGeom->num_entities();
227  }
228 
229  compGeom->merge( *(curve->compGeom), prepend );
230  if( curve->hiddenSet )
231    hidden_entities().merge( curve->hiddenSet );
232   
233  for( int i = start; i < stop; i++ )
234  {
235    TopologyBridge* bridge = compGeom->entity(i);
236    assert( bridge->owner() == curve );
237    bridge->owner(this);
238  }
239 
240  return CUBIT_SUCCESS;
241}
242
243bool CompositeCurve::has_parent_composite_surface() const
244{
245  CompositeCoEdge* coedge;
246  for( coedge = first_coedge(); coedge; coedge = next_coedge(coedge) )
247    if( coedge->get_loop() )
248      return true;
249  return false;
250}
251 
252void CompositeCurve::reverse()
253{
254  compGeom->reverse();
255}
256
257CompositePoint* CompositeCurve::common_point( CompositeCurve* curve )
258{
259  CompositePoint* result = 0;
260  CompositePoint* this_sp = start_point();
261  CompositePoint* this_ep = end_point();
262  CompositePoint* othr_sp = curve->start_point();
263  CompositePoint* othr_ep = curve->end_point();
264 
265  if( this_sp == othr_sp || this_sp == othr_ep )
266    result = this_sp;
267  else if( this_ep == othr_sp || this_ep == othr_ep )
268    result = this_ep;
269 
270  return result;
271}
272/*
273CompositeCoEdge* CompositeCurve::find_coedge( CompositeSurface* surface )
274{
275  CoEdge* coedge = 0;
276  while( coedge = next_coedge( coedge ) )
277    if( coedge->get_loop() && coedge->get_loop()->get_surface() == surface )
278      break;
279  return coedge;
280}
281*/
282CubitStatus CompositeCurve::add( CompositeCoEdge* coedge )
283{
284  if( coedge->myCurve ) 
285  {
286    assert(0);
287    return CUBIT_FAILURE;
288  }
289 
290  coedge->myCurve = this;
291  coedge->nextOnCurve = firstCoEdge;
292  firstCoEdge = coedge;
293 
294  return CUBIT_SUCCESS;
295}
296
297CubitStatus CompositeCurve::remove( CompositeCoEdge* coedge )
298{
299  if( coedge->myCurve != this )
300    return CUBIT_FAILURE;
301 
302  if( coedge == firstCoEdge )
303  {
304    firstCoEdge = coedge->nextOnCurve;
305  }
306  else
307  {
308    CompositeCoEdge *prev = firstCoEdge,
309                    *next = firstCoEdge->nextOnCurve;
310    while( next != coedge )
311    {
312      assert(next != NULL);
313      prev = next;
314      next = next->nextOnCurve;
315    }
316 
317    prev->nextOnCurve = next->nextOnCurve;
318  }
319 
320  coedge->nextOnCurve = 0;
321  coedge->myCurve = 0;
322  return CUBIT_SUCCESS;               
323}
324
325
326CubitBox CompositeCurve::bounding_box() const
327{ return compGeom->bounding_box(); }
328
329double CompositeCurve::measure() 
330{ return compGeom->measure(); }
331
332GeometryType CompositeCurve::geometry_type()
333{
334  switch (num_curves()) {
335    case 0  : return POINT_CURVE_TYPE;
336    case 1  : return get_curve(0)->geometry_type();
337    default : return UNDEFINED_CURVE_TYPE;
338  }
339}
340
341GeometryQueryEngine* CompositeCurve::get_geometry_query_engine() const
342{ return VirtualQueryEngine::instance(); }
343
344
345double CompositeCurve::start_param()
346{ return 0; }
347
348double CompositeCurve::end_param()
349{ return measure(); }
350
351CubitBoolean CompositeCurve::get_param_range( double& lower, double& upper )
352{
353  lower = 0;
354  upper = measure();
355  return CUBIT_TRUE;
356}
357
358CubitBoolean CompositeCurve::is_periodic( double& period )
359{
360  if (geometry_type() == POINT_CURVE_TYPE)
361    return CUBIT_FALSE;
362 
363  if( startPoint == endPoint && num_curves() > 0 )
364  {
365    period = measure();
366    return CUBIT_TRUE;
367  }
368  else
369  {
370    period = 0;
371    return CUBIT_FALSE;
372  }
373}
374
375CubitStatus CompositeCurve::position_from_u( double u, CubitVector& position )
376{
377  int index;
378  double ui;
379 
380  if (num_curves() == 0) // point curve
381    return CUBIT_FAILURE;
382 
383  if( ! curve_param( u, ui, index ) || index < 0 )
384    return CUBIT_FAILURE;
385 
386  Curve* curve_ptr = get_curve( index );
387  return curve_ptr ? curve_ptr->position_from_u( ui, position ) : CUBIT_FAILURE;
388} 
389
390double CompositeCurve::u_from_position( const CubitVector& position )
391{
392  if (num_curves() == 0) // point curve
393    return 0.0;
394 
395  int index = closest_curve(position );
396  double param = get_curve( index )->u_from_position( position );
397  return composite_param( index, param );
398}
399
400double CompositeCurve::u_from_arc_length( double param, double length )
401{ return param + length; }
402double CompositeCurve::length_from_u( double u1, double u2 )
403{ return fabs( u1 - u2 ); }
404
405CubitStatus CompositeCurve::closest_point( const CubitVector& location,
406                                           CubitVector& closest,
407                                           CubitVector* tangent_ptr,
408                                           CubitVector* curvature_ptr,
409                                           double* param )
410{
411  if (num_curves() == 0) // point curve
412  {
413    if (!startPoint)
414      return CUBIT_FAILURE;
415   
416    closest = startPoint->coordinates();
417    if (tangent_ptr)
418      tangent_ptr->set(0.0,0.0,0.0);
419    if (curvature_ptr)
420      curvature_ptr->set(0.0,0.0,0.0);
421    if (param)
422      *param = 0.0;
423  }
424 
425  if( compGeom->num_entities() == 1 )
426  {
427    CubitStatus result = get_curve(0)
428      ->closest_point( location, closest, tangent_ptr, curvature_ptr, param );
429
430    if( tangent_ptr && compGeom->sense(0) == CUBIT_REVERSED )
431      *tangent_ptr *= -1.0;
432   
433    if( param )
434      *param = composite_param( 0, *param );
435     
436    return result;
437  }
438 
439  int index = closest_curve( location, &closest );
440  Curve* curve = get_curve( index );
441  if( tangent_ptr || curvature_ptr || param )
442  {
443    curve->closest_point( location, closest, tangent_ptr, 
444                          curvature_ptr, param );
445    if( param )
446      *param = composite_param( index, *param );
447    if( tangent_ptr && compGeom->sense(index) == CUBIT_REVERSED )
448      *tangent_ptr *= -1.0;
449  }
450 
451  return CUBIT_SUCCESS;
452}
453
454
455CubitStatus CompositeCurve::closest_point_trimmed( 
456                                    const CubitVector& position,
457                                    CubitVector& closest )
458{
459  if (num_curves() == 0) 
460    return closest_point( position, closest );
461   
462  if( compGeom->num_entities() == 1 )
463    return get_curve(0)->closest_point_trimmed( position, closest );
464 
465  closest_curve( position, &closest );
466  return CUBIT_SUCCESS;
467}
468
469CubitBoolean CompositeCurve::is_position_on( const CubitVector& position )
470{
471    // point curve
472  if (num_curves() == 0)
473  {
474    CompositePoint* point = start_point();
475    double lensqr = (position - point->coordinates()).length_squared();
476    return lensqr <= (GEOMETRY_RESABS*GEOMETRY_RESABS);
477  }
478 
479  if( compGeom->num_entities() == 1 )
480    return get_curve(0)->is_position_on( position );
481 
482  int index = closest_curve( position );
483  return get_curve(index)->is_position_on( position );
484}
485
486CubitPointContainment CompositeCurve::point_containment( const CubitVector& point )
487{
488  int index;
489 
490  if (num_curves() == 0) 
491    return is_position_on(point) ? CUBIT_PNT_ON : CUBIT_PNT_OFF;
492 
493  for( index = 0; index < compGeom->num_entities(); index++ )
494  {
495    if( get_curve(index)->point_containment( point ) == CUBIT_PNT_ON )
496      return CUBIT_PNT_ON;
497  }
498 
499  return CUBIT_PNT_OFF;  //not on any Curve
500}
501
502CubitStatus CompositeCurve::get_point_direction( CubitVector& origin,
503                                                 CubitVector& direction )
504{
505  if (num_curves() == 0) // point curve
506    return CUBIT_FAILURE;
507 
508  if( compGeom->num_entities() == 1 )
509    return get_curve(0)->get_point_direction( origin, direction );
510 
511  int count = compGeom->num_entities();
512  CubitVector* vect_list = new CubitVector[count];
513  double RESABS_SQUARED = CUBIT_RESABS * CUBIT_RESABS;
514  direction.set(0,0,0);
515  for( int i = 0; i < count; i++ )
516  {
517    if( ! get_curve(i)->get_point_direction(origin,vect_list[i]) ||
518        (vect_list[i].length_squared() < RESABS_SQUARED) )
519    {
520      delete [] vect_list;
521      return CUBIT_FAILURE;
522    }
523    if( get_sense(i) == CUBIT_REVERSED )
524      vect_list[i] *= -1;
525    direction += vect_list[i];
526  }
527  //If we reach this point, then all of the underlying curves are linear.
528  //Next check if they are colinear.
529  if( direction.length_squared() < RESABS_SQUARED )
530  {
531    delete [] vect_list;
532    return CUBIT_FAILURE;
533  }
534  CubitVector mean = ~direction;
535  for( int j = 0; j < count; j++ )
536  {
537    if( fabs( 1 - (mean % ~vect_list[j]) ) > CUBIT_RESABS )
538    {
539      delete [] vect_list;
540      return CUBIT_FAILURE;
541    }
542  }
543 
544  delete [] vect_list;
545  get_curve(0)->get_point_direction(origin,direction);
546  direction = mean;
547  return CUBIT_SUCCESS;
548}
549
550CubitStatus CompositeCurve::get_interior_extrema( 
551                                    DLIList<CubitVector*>& interior_points,
552                                    CubitSense& return_sense )
553{
554  return_sense = CUBIT_FORWARD;
555  if (num_curves() == 0) // point curve
556    return CUBIT_SUCCESS;
557
558    // Go through each curve in the composite
559  DLIList<CubitVector*> curve_point_list;
560  for (int i = compGeom->num_entities() - 1; i >= 0; i--)
561  {
562      // Get the next curve's extrema
563    Curve* cur_curve = get_curve(i);
564    cur_curve->get_interior_extrema(curve_point_list,return_sense);
565      // See which order to put them into the return list
566    if (return_sense == get_sense(i))
567    {
568      interior_points += curve_point_list;
569    }
570    else
571    {
572      curve_point_list.last();
573      for (int j = curve_point_list.size(); j--; )
574        interior_points.append(curve_point_list.get_and_back());
575    }
576      // Unless this is the last curve, put in the point
577      // between this and the next curve
578    if (i != 0)
579    {
580      CubitVector* endpoint = new CubitVector(0,0,0);
581      if (get_sense(i) == CUBIT_FORWARD)
582        cur_curve->position_from_u(cur_curve->end_param(), *endpoint);
583      else
584        cur_curve->position_from_u(cur_curve->end_param(), *endpoint);
585      interior_points.append(endpoint);
586    }
587      // clean out the list for the next curve
588    curve_point_list.clean_out();
589  }
590
591  return CUBIT_SUCCESS;
592}
593
594CubitStatus CompositeCurve::get_center_radius( CubitVector& c, double& r )
595{
596  if (num_curves() == 0) // point curve
597    return CUBIT_FAILURE;
598 
599  if (!get_curve(0)->get_center_radius(c,r) )
600    return CUBIT_FAILURE;
601   
602  for (int i = compGeom->num_entities() - 1; i > 0; i-- )
603  {
604    CubitVector c2;
605    double r2;
606    if (!get_curve(i)->get_center_radius(c2,r2) ||
607        fabs(r - r2) > GEOMETRY_RESABS ||
608        (c2 - c).length_squared() > GEOMETRY_RESABS*GEOMETRY_RESABS)
609    {
610      return CUBIT_FAILURE;
611    }
612  }
613  return CUBIT_SUCCESS;
614}
615 
616CubitBoolean CompositeCurve::G1_discontinuous( double param,
617  CubitVector* minus_tangent, CubitVector* plus_tangent )
618{
619  if (num_curves() == 0) // point curve
620    return CUBIT_FALSE;
621 
622  const double half_resabs = CUBIT_RESABS / 2.0;
623  double curve_param;
624  int curve_index;
625  CubitStatus s = this->curve_param( param, curve_param, curve_index );
626  if( ! s )
627  {
628    PRINT_ERROR("Parameter %f out of range [%f,%f] in "
629     "CompositeCurve::G1_discontinous(..)\n",param,start_param(),end_param());
630    return CUBIT_FALSE;
631  }
632 
633  CubitVector tan1, tan2, location, cp;
634  CubitBoolean result = CUBIT_FALSE;
635  if( (curve_index > 0) && 
636      (fabs(compGeom->measure(curve_index-1) - param) < half_resabs) )
637  {
638    get_curve( curve_index )->position_from_u( curve_param, location );
639    get_curve( curve_index-1 )->closest_point( location, cp, &tan1 );
640    if( get_sense( curve_index-1 ) == CUBIT_REVERSED ) tan1 *= -1.0;
641    get_curve( curve_index   )->closest_point( location, cp, &tan2 );
642    if( get_sense( curve_index   ) == CUBIT_REVERSED ) tan2 *= -1.0;
643    double cross = (tan1 * tan2).length_squared();
644    double sum   = (tan1 + tan2).length_squared();
645    double diff  = (tan1 - tan2).length_squared();
646    if( (cross > CUBIT_RESABS) || (sum < diff) )
647    {
648      if( minus_tangent ) *minus_tangent = tan1;
649      if( plus_tangent ) *plus_tangent = tan2;
650      result = CUBIT_TRUE;
651    }
652    else
653      result = CUBIT_FALSE;
654   
655  }
656  else if( (curve_index < (compGeom->num_entities()-1)) &&
657           (fabs(compGeom->measure(curve_index) - param) < half_resabs) )
658  {
659    get_curve( curve_index )->position_from_u( curve_param, location );
660    get_curve( curve_index   )->closest_point( location, cp, &tan1 );
661    if( get_sense( curve_index   ) == CUBIT_REVERSED ) tan1 *= -1.0;
662    get_curve( curve_index+1 )->closest_point( location, cp, &tan2 );
663    if( get_sense( curve_index+1 ) == CUBIT_REVERSED ) tan2 *= -1.0;
664    double cross = (tan1 * tan2).length_squared();
665    double sum   = (tan1 + tan2).length_squared();
666    double diff  = (tan1 - tan2).length_squared();
667    if( (cross > CUBIT_RESABS) || (sum < diff) )
668    {
669      if( minus_tangent ) *minus_tangent = tan1;
670      if( plus_tangent ) *plus_tangent = tan2;
671      result = CUBIT_TRUE;
672    }
673    else
674      result = CUBIT_FALSE;
675  }
676  else if( get_sense(curve_index) == CUBIT_FORWARD )
677  {
678    result = get_curve( curve_index )
679      ->G1_discontinuous( curve_param, minus_tangent, plus_tangent );
680  }
681  else
682  {
683    result = get_curve( curve_index )
684      ->G1_discontinuous( curve_param, plus_tangent, minus_tangent );
685    if( result )
686    {
687      if( plus_tangent )  *plus_tangent  *= -1.0;
688      if( minus_tangent) *minus_tangent *= -1.0;
689    }
690  }
691  return result; 
692}
693
694
695int CompositeCurve::closest_curve( const CubitVector& location,
696                                   CubitVector *point )
697{ 
698  double shortest_distance_sqr, current_distance_sqr;
699  CubitVector closest_point, current_point;
700  int closest_curve, current_curve;
701 
702  closest_curve = compGeom->closest_box( location );
703 
704  get_curve( closest_curve )->closest_point_trimmed( location, closest_point );
705  shortest_distance_sqr = (location - closest_point).length_squared();
706 
707  while( ( current_curve = compGeom->next_box_within_dist( shortest_distance_sqr ) ) >= 0 )
708  {
709    get_curve( current_curve )->closest_point_trimmed( location, current_point );
710    current_distance_sqr = (location - current_point).length_squared();
711    if( current_distance_sqr < shortest_distance_sqr )
712    {
713      closest_curve = current_curve;
714      shortest_distance_sqr = current_distance_sqr;
715      closest_point = current_point;
716    }
717  }
718   
719  if( point ) *point = closest_point;
720  return closest_curve;
721}
722
723
724
725//-------------------------------------------------------------------------
726// Purpose       : Parameter Conversion
727//
728// Special Notes :
729//
730// Creator       : Jason Kraftcheck
731//
732// Creation Date : 06/08/98
733//-------------------------------------------------------------------------
734double CompositeCurve::composite_param( int index, double u ) const
735{
736  if( (index < 0) || (index >= compGeom->num_entities()) ) return -1.0;
737  Curve* curve_ptr = get_curve( index );
738  double sum = lengthUntilI( index );
739
740  double u_min, u_max;
741  curve_ptr->get_param_range( u_min, u_max );
742
743  CubitSense sense = this->get_sense(index);
744  double root_param = (sense == CUBIT_FORWARD) ? u_min : u_max;
745  double lfu = (root_param < u) ?
746    curve_ptr->length_from_u( root_param, u ) :
747    curve_ptr->length_from_u( u, root_param );
748  return sum + fabs( lfu );
749}
750 
751 
752CubitStatus CompositeCurve::curve_param( double uc, double& ui, int& index ) const
753{
754  double sum = 0.0, period;
755  if( const_cast<CompositeCurve*>(this)->is_periodic(period) )
756    fixup_periodic_param( uc );
757
758  int max = compGeom->num_entities();
759  int min = 0;
760  index = max / 2;
761  sum = lengthUntilI( max - 1);
762  if( uc >= sum ) index = max - 1;
763  else while( min != max )
764  {
765    sum = lengthUntilI(index);
766    if( sum > uc )
767      max = index;
768    else if( lengthUntilI(index+1) > uc ) 
769      break;
770    else 
771      min = index;
772   
773    index = (min + max) / 2;
774  }
775     
776  if( index >= compGeom->num_entities() ) return CUBIT_FAILURE;
777
778  double ui_min, ui_max;
779  get_curve(index)->get_param_range( ui_min, ui_max );
780
781  double arc_len = uc - sum;
782  if( get_sense(index) == CUBIT_REVERSED ) 
783    arc_len = get_curve(index)->measure() - arc_len;
784  ui = get_curve(index)->u_from_arc_length( ui_min, arc_len );
785  return CUBIT_SUCCESS;
786}
787
788
789
790
791//-------------------------------------------------------------------------
792// Purpose       : Calculate the sum of the lengths of curves 0 to i-1.
793//
794// Special Notes :
795//
796// Creator       : Jason Kraftcheck
797//
798// Creation Date : 06/09/98
799//-------------------------------------------------------------------------
800double CompositeCurve::lengthUntilI( int i ) const
801{
802  assert( i >= 0 && i < compGeom->num_entities() );
803  return ( i == 0 ) ? 0.0 : compGeom->measure(i - 1);
804}
805
806//-------------------------------------------------------------------------
807// Purpose       : TopologyBridge queries
808//
809// Special Notes :
810//
811// Creator       : Jason Kraftcheck
812//
813// Creation Date : 03/04/02
814//-------------------------------------------------------------------------
815void CompositeCurve::get_parents_virt( DLIList<TopologyBridge*>& list )
816{ 
817  for( CompositeCoEdge* coedge = firstCoEdge; 
818       coedge != 0;
819       coedge = coedge->nextOnCurve )
820    if (!dynamic_cast<HiddenEntitySet*>(coedge->owner()))
821      list.append( coedge );
822 
823  if (stitchNext)
824    stitchNext->get_parents_virt(list);
825}
826void CompositeCurve::get_children_virt( DLIList<TopologyBridge*>& list )
827{
828  CompositePoint* sp = start_point();
829  CompositePoint* ep = end_point();
830 
831  if( sp ) 
832    list.append( sp );
833  if( ep && ep != sp )
834    list.append( ep );
835}
836
837//-------------------------------------------------------------------------
838// Purpose       : TBOwner methods
839//
840// Special Notes :
841//
842// Creator       : Jason Kraftcheck
843//
844// Creation Date : 03/04/02
845//-------------------------------------------------------------------------
846CubitStatus CompositeCurve::remove_bridge( TopologyBridge* bridge )
847{
848  int i = compGeom->index_of(bridge);
849  if ( i >= 0 )
850  {
851    bridge->owner(0);
852    if ( !compGeom->remove(i,true) )
853      return CUBIT_FAILURE;
854
855    if (compGeom->num_entities() == 0)
856      CompositeEngine::instance().notify_deactivated(this);
857    HadBridgeRemoved = 1;
858    return CUBIT_SUCCESS;
859  }
860  else
861  {
862    for (CompositeCurve* ptr = this; ptr->stitchNext; ptr = ptr->stitchNext)
863    {
864      if (ptr->stitchNext == bridge)
865      {
866        ptr->stitchNext = ((CompositeCurve*)bridge)->stitchNext;
867HadBridgeRemoved = 1;
868        return CUBIT_SUCCESS;
869      }
870    }
871  }
872 
873  return CUBIT_FAILURE;
874}
875
876Curve* CompositeCurve::remove_curve( int index )
877{
878  Curve* curve = get_curve(index);
879  if (!curve || !compGeom->remove(index,false) )
880    return 0;
881  curve->owner(0);
882  return curve;
883}
884
885 
886
887CubitStatus CompositeCurve::swap_bridge( TopologyBridge* o,
888                                         TopologyBridge* n,
889                                         bool reversed )
890{
891  int i = compGeom->index_of(o);
892  GeometryEntity* ge = dynamic_cast<GeometryEntity*>(n);
893  if( i >= 0 && ge != 0 )
894  {
895    o->owner(0);
896    n->owner(this);
897    if ( ! compGeom->swap( i, ge ) )
898      return CUBIT_FAILURE;
899   
900    if (reversed)
901      compGeom->reverse_sense(i);
902    return CUBIT_SUCCESS;
903  }
904  else
905    return CUBIT_FAILURE;
906}
907CubitBoolean CompositeCurve::contains_bridge( TopologyBridge* bridge ) const
908{
909  if (!compGeom)
910    return CUBIT_FALSE;
911 
912  return (CubitBoolean)(compGeom->index_of(bridge) >= 0);
913}
914
915
916//-------------------------------------------------------------------------
917// Purpose       : Attach a CubitSimpleAttribute
918//
919// Special Notes :
920//
921// Creator       : Jason Kraftcheck
922//
923// Creation Date : 03/10/98
924//-------------------------------------------------------------------------
925void CompositeCurve::append_simple_attribute_virt(
926                                                    CubitSimpleAttrib* simple_attrib_ptr )
927{
928  compGeom->add_attribute( simple_attrib_ptr );
929}
930
931//-------------------------------------------------------------------------
932// Purpose       : Remove an attached CubitSimpleAttrib
933//
934// Special Notes :
935//
936// Creator       : Jason Kraftcheck
937//
938// Creation Date : 03/10/98
939//-------------------------------------------------------------------------
940void CompositeCurve::remove_simple_attribute_virt(
941                                                    CubitSimpleAttrib* simple_attrib_ptr )
942{
943  compGeom->rem_attribute( simple_attrib_ptr );
944}
945
946
947//-------------------------------------------------------------------------
948// Purpose       : Remove an all attached CubitSimpleAttrib
949//
950// Special Notes :
951//
952// Creator       : Greg Nielson
953//
954// Creation Date : 07/10/98
955//-------------------------------------------------------------------------
956void CompositeCurve::remove_all_simple_attribute_virt()
957{
958  compGeom->rem_all_attributes( );
959}
960
961
962//-------------------------------------------------------------------------
963// Purpose       : Return the attached CubitSimpleAttribs.
964//
965// Special Notes :
966//
967// Creator       : Jason Kraftcheck
968//
969// Creation Date : 03/10/98
970//-------------------------------------------------------------------------
971CubitStatus CompositeCurve::get_simple_attribute(
972                                                   DLIList<CubitSimpleAttrib*>& attrib_list )
973{
974  compGeom->get_attributes( attrib_list );
975  return CUBIT_SUCCESS;
976}
977
978
979
980//-------------------------------------------------------------------------
981// Purpose       : Get attribs by name
982//
983// Special Notes :
984//
985// Creator       : Jason Kraftcheck
986//
987// Creation Date : 03/03/03
988//-------------------------------------------------------------------------
989CubitStatus CompositeCurve::get_simple_attribute(
990                                        const CubitString& name, DLIList<CubitSimpleAttrib*>& attrib_list )
991{
992  compGeom->get_attributes( name.c_str(), attrib_list );
993  return CUBIT_SUCCESS;
994}
995
996void CompositeCurve::fixup_periodic_param( double& param ) const
997{
998  double period = compGeom->measure();
999  if( param < 0.0 )
1000    param = period - param;
1001  if( param >= period )
1002    param = fmod( param, period );
1003}
1004
1005//-------------------------------------------------------------------------
1006// Purpose       : Write attributes to underlying geometry entity
1007//
1008// Special Notes : Special case for point-curves
1009//
1010// Creator       : Jason Kraftcheck
1011//
1012// Creation Date : 02/28/04
1013//-------------------------------------------------------------------------
1014void CompositeCurve::write_attributes()
1015{
1016  if (num_curves()) // not a point-curve
1017  {
1018    compGeom->write_attributes();
1019  }
1020  else
1021  {
1022    CompositePoint* point = start_point();
1023    assert(point == end_point());
1024    compGeom->write_attributes(point);
1025  }
1026}
1027
1028//-------------------------------------------------------------------------
1029// Purpose       : Read attributes from underlying geometry
1030//
1031// Special Notes :
1032//
1033// Creator       : Jason Kraftcheck
1034//
1035// Creation Date : 02/28/04
1036//-------------------------------------------------------------------------
1037void CompositeCurve::read_attributes()
1038{
1039  if (num_curves()) // not a point-curve
1040  {
1041    compGeom->read_attributes();
1042  }
1043  else
1044  {
1045    CompositePoint* point = start_point();
1046    assert(point == end_point());
1047    compGeom->read_attributes(point);
1048  }
1049}
1050
1051
1052void CompositeCurve::get_hidden_points( DLIList<Point*>& points )
1053{
1054  if( hiddenSet )
1055  {
1056    hiddenSet->hidden_points( points );
1057  }
1058}
1059
1060
1061
1062void CompositeCurve::print_debug_info( const char* prefix, 
1063                                       bool brief ) const
1064{
1065  if( prefix == 0 ) prefix = "";
1066 
1067  if ( brief )
1068  {
1069#ifdef TOPOLOGY_BRIDGE_IDS
1070    PRINT_INFO("%sCompositeCurve %d : points (%d,%d) ", prefix, get_id(),
1071      startPoint ? startPoint->get_id() : -1, endPoint ? endPoint->get_id() : -1 );
1072    if ( num_curves() == 1 )
1073      PRINT_INFO(": %s %d\n", fix_type_name(typeid(*get_curve(0)).name()), get_curve(0)->get_id());
1074    else
1075      PRINT_INFO(": %d curves.\n", num_curves() );
1076#else
1077    PRINT_INFO("%sCompositeCurve %p : points (%p,%p) ", prefix, this,
1078      startPoint, endPoint );
1079    if ( num_curves() == 1 )
1080      PRINT_INFO(": %s %p\n", fix_type_name(typeid(*get_curve(0)).name()), get_curve(0));
1081    else
1082      PRINT_INFO(": %d curves.\n", num_curves() );
1083#endif
1084    return;
1085  }
1086   
1087  char* new_prefix = new char[strlen(prefix)+3];
1088  strcpy( new_prefix, prefix );
1089  strcat( new_prefix, "  ");
1090 
1091#ifdef TOPOLOGY_BRIDGE_IDS
1092  PRINT_INFO("%sCompositeCurve %d\n", prefix, get_id() );
1093#else
1094  PRINT_INFO("%sCompositeCurve %p\n", prefix, this );
1095#endif
1096  compGeom->print_debug_info( new_prefix );
1097  if( hiddenSet ) hiddenSet->print_debug_info( new_prefix );
1098  else PRINT_INFO("%s  No Hidden Entities.\n", prefix );
1099 
1100  CompositeCoEdge* coedge = first_coedge();
1101  DLIList<TopologyBridge*> loops(1), surface_list(1);
1102 
1103  while( coedge )
1104  {
1105    TopologyBridge* surf_ptr = 0;
1106    loops.clean_out();
1107    surface_list.clean_out();
1108    coedge->get_parents_virt(loops);
1109    if ( loops.size() == 1 )
1110    {
1111      loops.get()->get_parents_virt(surface_list);
1112      if( surface_list.size() == 1 )
1113        surf_ptr = surface_list.get();
1114    }
1115
1116#ifdef TOPOLOGY_BRIDGE_IDS
1117    PRINT_INFO("%s  %s on Surface %d\n", prefix, 
1118      coedge->sense() == CUBIT_FORWARD ? "FORWARD" :
1119      coedge->sense() == CUBIT_REVERSED ? "REVERSE" : "UNKNOWN",
1120      surf_ptr->get_id() );
1121#else
1122    PRINT_INFO("%s  %s on Surface %p\n", prefix, 
1123      coedge->sense() == CUBIT_FORWARD ? "FORWARD" :
1124      coedge->sense() == CUBIT_REVERSED ? "REVERSE" : "UNKNOWN",
1125      surf_ptr );
1126#endif
1127
1128    if (!coedge->get_loop())
1129      coedge->print_debug_info( new_prefix, true );
1130    coedge = next_coedge(coedge);
1131  }
1132 
1133  if ( !start_point() )
1134    PRINT_INFO("%s  NULL START POINT\n", prefix );
1135  else
1136    start_point()->print_debug_info( new_prefix, true );
1137 
1138  if ( !end_point() )
1139    PRINT_INFO("%s  NULL END POINT\n", prefix );
1140  else if ( end_point() == start_point() )
1141    PRINT_INFO("%s  end point SAME as start point\n", prefix ); 
1142  else
1143    end_point()->print_debug_info( new_prefix, true );
1144 
1145  delete [] new_prefix;
1146}
1147
1148
1149//-------------------------------------------------------------------------
1150// Purpose       : Update composite for change in sense of underlying curve
1151//
1152// Special Notes :
1153//
1154// Creator       : Jason Kraftcheck
1155//
1156// Creation Date :
1157//-------------------------------------------------------------------------
1158void CompositeCurve::notify_reversed( TopologyBridge* bridge )
1159{
1160  int index = compGeom->index_of(bridge);
1161  if( index >= 0 )
1162    compGeom->reverse_sense(index);
1163}
1164
1165//-------------------------------------------------------------------------
1166// Purpose       : Merge
1167//
1168// Special Notes :
1169//
1170// Creator       : Jason Kraftcheck
1171//
1172// Creation Date : 12/02/02
1173//-------------------------------------------------------------------------
1174CubitStatus CompositeCurve::stitch( CompositeCurve* dead )
1175{
1176    // check to make sure end points are already stitched.
1177  bool reversed;
1178 
1179  if( dead->start_point() == this->start_point() )
1180    reversed = false;
1181  else if( dead->end_point() == this->start_point() )
1182    reversed = true;
1183  else
1184    return CUBIT_FAILURE;
1185 
1186  if( ( reversed && (dead->start_point() != this->end_point())) ||
1187      (!reversed && (dead->end_point()   != this->end_point())) )
1188    return CUBIT_FAILURE;
1189
1190    // shouldn't be merging hidden curves
1191  if( dynamic_cast<CompositeCurve*>(this->owner()) ||
1192      dynamic_cast<CompositeCurve*>(dead->owner()) )
1193  {
1194    assert(0);
1195    return CUBIT_FAILURE;
1196  }
1197 
1198    // DAG / next level up should already be merged
1199  if( dead->owner() != this->owner() )
1200  {
1201    assert(0);
1202    return CUBIT_FAILURE;
1203  }
1204 
1205    // update owner
1206  if( dead->owner() )
1207    dead->owner()->notify_merged( dead, this );
1208  assert( !dead->owner() );
1209  dead->owner( this );
1210 
1211    // merge lists
1212  CompositeCurve* end = dead;
1213  while (end->stitchNext) 
1214  {
1215    end->stitchNext->owner( this );
1216    end = end->stitchNext;
1217  }
1218  end->stitchNext = stitchNext;
1219  stitchNext = end;
1220 
1221  return CUBIT_SUCCESS;
1222}
1223     
1224//-------------------------------------------------------------------------
1225// Purpose       : Get the visible curve of a set of stitched curves
1226//
1227// Special Notes :
1228//
1229// Creator       : Jason Kraftcheck
1230//
1231// Creation Date : 12/02/02
1232//-------------------------------------------------------------------------
1233CompositeCurve* CompositeCurve::primary_stitched_curve()
1234{
1235  CompositeCurve* result = dynamic_cast<CompositeCurve*>(owner());
1236  return result ? result : this;
1237}
1238
1239//-------------------------------------------------------------------------
1240// Purpose       : Is this curve stitched with any others
1241//
1242// Special Notes :
1243//
1244// Creator       : Jason Kraftcheck
1245//
1246// Creation Date : 12/02/02
1247//-------------------------------------------------------------------------
1248bool CompositeCurve::is_stitched()
1249{
1250  return stitchNext || dynamic_cast<CompositeCurve*>(owner());
1251}
1252
1253//-------------------------------------------------------------------------
1254// Purpose       : Get list of stitched curves
1255//
1256// Special Notes :
1257//
1258// Creator       : Jason Kraftcheck
1259//
1260// Creation Date : 12/16/02
1261//-------------------------------------------------------------------------
1262void CompositeCurve::get_stitched( DLIList<CompositeCurve*>& list )
1263{
1264  for (CompositeCurve* curve = primary_stitched_curve();
1265       curve; curve = curve->stitchNext)
1266    list.append( curve );
1267}
1268
1269//-------------------------------------------------------------------------
1270// Purpose       : Remove all stitched curves
1271//
1272// Special Notes :
1273//
1274// Creator       : Jason Kraftcheck
1275//
1276// Creation Date : 12/02/02
1277//-------------------------------------------------------------------------
1278void CompositeCurve::unstitch_all()
1279{
1280    // should only call on visible curve
1281  assert (this == primary_stitched_curve());
1282 
1283  while (stitchNext)
1284  {
1285    stitchNext->owner(0);
1286    if (owner())
1287      owner()->notify_copied( stitchNext, this );
1288    stitchNext = stitchNext->stitchNext;
1289  }
1290}
1291
1292 
1293//-------------------------------------------------------------------------
1294// Purpose       : Update for split in underlying curve
1295//
1296// Special Notes :
1297//
1298// Creator       : Jason Kraftcheck
1299//
1300// Creation Date : 12/19/02
1301//-------------------------------------------------------------------------
1302void CompositeCurve::notify_split( TopologyBridge* new_bridge,
1303                                   TopologyBridge* old_bridge )
1304{
1305  Curve* old_curve = dynamic_cast<Curve*>(old_bridge);
1306  Curve* new_curve = dynamic_cast<Curve*>(new_bridge);
1307  assert( old_curve && new_curve && index_of(old_curve) >= 0 );
1308 
1309    // get start and end points
1310  DLIList<TopologyBridge*> bridges;
1311  old_curve->get_children(bridges,true,old_curve->layer());
1312  bridges.reset();
1313  Point* old_start = dynamic_cast<Point*>(bridges.get());
1314  Point* old_end   = dynamic_cast<Point*>(bridges.next());
1315  bridges.clean_out();
1316  new_curve->get_children(bridges,true,new_curve->layer());
1317  Point* new_start = dynamic_cast<Point*>(bridges.get());
1318  Point* new_end   = dynamic_cast<Point*>(bridges.next());
1319  bridges.clean_out();
1320
1321 
1322    // find new point
1323  bool sp = (new_start == old_start || new_start == old_end);
1324  bool ep = (new_end   == old_start || new_end   == old_end);
1325  assert( ep != sp ); // one must be true and one must be false
1326  Point* new_pt = sp ? new_start : new_end;
1327 
1328    // find relative sense of curves
1329  int old_index = index_of(old_curve);
1330  bool is_start = (old_start == new_pt);
1331  bool is_forward = (get_sense(old_index) == CUBIT_FORWARD);
1332  bool prepend = (is_start == is_forward);
1333  is_start = (new_start == new_pt);
1334  assert( is_start || new_pt == new_end );
1335  bool reversed = (is_start == prepend);
1336 
1337  CompositePoint* new_cpt = new CompositePoint(new_pt);
1338 
1339  hidden_entities().hide(new_cpt);
1340 
1341  CubitSense new_sense = reversed ? CUBIT_REVERSED : CUBIT_FORWARD;
1342  int insert_index = old_index;
1343  if( !prepend ) insert_index++;
1344  if( ! compGeom->insert( insert_index, new_curve, new_sense ) )
1345  {
1346    assert(0);
1347    delete new_cpt;
1348    return;
1349  }
1350  new_curve->owner(this);
1351 
1352  DLIList<CoEdgeSM*> new_coedges, old_coedges;
1353  bridges.clean_out();
1354  new_curve->get_parents_virt( bridges );
1355  CAST_LIST( bridges, new_coedges, CoEdgeSM );
1356  assert(bridges.size() == new_coedges.size());
1357  bridges.clean_out();
1358  old_curve->get_parents_virt( bridges );
1359  CAST_LIST( bridges, old_coedges, CoEdgeSM );
1360  assert(bridges.size() == old_coedges.size());
1361 
1362  for( CompositeCoEdge* coedge = first_coedge();
1363       coedge;
1364       coedge = next_coedge(coedge) )
1365  {
1366      // for each coedge of the old curve
1367    int i;
1368    CoEdgeSM* old_coedge = 0;
1369    for( i = 0; i < coedge->num_coedges(); i++ )
1370    {
1371      old_coedge = coedge->get_coedge(i);
1372      if( old_coedges.is_in_list(old_coedge) )
1373        break;
1374    }
1375    assert(i < coedge->num_coedges() && old_coedge);
1376   
1377    bridges.clean_out();
1378    old_coedge->get_parents_virt(bridges);
1379    assert(bridges.size() == 1);
1380    LoopSM* loopsm = dynamic_cast<LoopSM*>(bridges.get());
1381    assert(0 != loopsm);
1382     
1383    bridges.clean_out();
1384    loopsm->get_children(bridges, true, old_curve->layer());
1385    bridges.move_to(old_coedge);
1386    assert(bridges.get() == old_coedge);
1387     
1388      // Determine if new_coedge (the one we are looking for)
1389      // should occur before or after old_coedge in the loop.
1390      // If new_curve is after old_curve (old_end == new_pt),
1391      // then the we want the coedge after old_coedge iff the
1392      // sense of old_coedge is forward, otherwise the one before.
1393      // Invert that if new_curve is before old_curve (old_start
1394      // == new_pt).
1395    bool coe_reversed = (old_coedge->sense() == CUBIT_REVERSED);
1396    bool curve_prepend = (old_start == new_pt);
1397    bool previous = coe_reversed != curve_prepend;
1398    CoEdgeSM* new_coedge = 
1399      dynamic_cast<CoEdgeSM*>(previous ? bridges.prev() : bridges.next());
1400    assert(new_coedges.is_in_list(new_coedge));
1401   
1402    CubitStatus s = coedge->insert_coedge(insert_index, new_coedge);
1403    assert(s);
1404  }
1405}
1406
1407/*
1408void CompositeCurve::draw( int color )
1409{
1410  int num_pts;
1411  GMem gmem;
1412 
1413  if (!VirtualQueryEngine::instance()->get_graphics(this, num_pts, &gmem))
1414    return;
1415 
1416    GfxDebug::draw_polyline( gmem.point_list(),
1417                             gmem.pointListCount,
1418                             color );
1419    GfxDebug::flush();
1420}
1421*/
Note: See TracBrowser for help on using the browser.