cgma
SSSide Class Reference

#include <TDSplitSurface.hpp>

List of all members.

Public Member Functions

 SSSide (RefFace *ref_face_ptr, DLIList< CoEdge * > &co_edges, const CubitVector *collapsed_loc_ptr=NULL)
 ~SSSide ()
CubitStatus position_from_u (double u_value, CubitVector &output_position)
CubitStatus u_from_position (const CubitVector &input_position, double &u)
CubitStatus u_from_position (const CubitVector &input_position, CoEdge *co_edge_ptr, SSParam *param, double &u)
CubitBoolean is_vertex_on (RefVertex *ref_vertex_ptr)
double length ()
CubitStatus build_param_list_from_facets (double tolerance=0.1)
CubitStatus build_param_list (double fraction, double distance, int num_segs, DLIList< RefVertex * > &through_vertex_list)
CubitStatus syncronize_lists (SSSide *other_side, double param_tol=.1)
DLIList< CoEdge * > * co_edges ()
int coord_list_size ()
void coord_list_reset ()
void coord_list_last ()
CubitVectorcoord_list_get ()
CubitVectorcoord_list_get_and_step ()
CubitVectorcoord_list_get_and_back ()
int param_list_size ()
void param_list_reset ()
void param_list_last ()
double param_list_get ()
double param_list_get_and_step ()
double param_list_get_and_back ()
CubitBoolean is_collapsed ()

Private Attributes

RefFacerefFacePtr
DLIList< CoEdge * > coEdgeChain
double paramHigh
DLIList< SSParam * > coEdgeParamList
DLIList< CubitVector * > coordList
DLIList< double > paramList
CubitBoolean isCollapsed

Detailed Description

Definition at line 54 of file TDSplitSurface.hpp.


Constructor & Destructor Documentation

SSSide::SSSide ( RefFace ref_face_ptr,
DLIList< CoEdge * > &  co_edges,
const CubitVector collapsed_loc_ptr = NULL 
)

Definition at line 290 of file TDSplitSurface.cpp.

{
  refFacePtr = ref_face_ptr;
  isCollapsed = CUBIT_FALSE;

  coEdgeChain = co_edges;
  double param_low = 0.0;
  paramHigh = 0.0;
  int i;
  CoEdge *co_edge_ptr;
  for( i=coEdgeChain.size(); i--; )
  {
    co_edge_ptr = coEdgeChain.get_and_step();
    paramHigh += co_edge_ptr->get_ref_edge_ptr()->measure();
    coEdgeParamList.append( new SSParam( param_low, paramHigh) );
    param_low = paramHigh;
  }

  if( !coEdgeChain.size() )
  {
    // Need to add a single point to hold the location of this side
    // ie., the side is collapsed (point of a triangle)
    isCollapsed = CUBIT_TRUE;

    assert( collapsed_loc_ptr != NULL );

    paramHigh = 0.0;
    coordList.append( new CubitVector( *collapsed_loc_ptr ) );
    paramList.append( 0.0 );
  }
}

Definition at line 323 of file TDSplitSurface.cpp.

{
  // Free memory
  while( coEdgeParamList.size() ) 
    delete coEdgeParamList.pop();
  while( coordList.size() ) 
    delete coordList.pop();
}

Member Function Documentation

CubitStatus SSSide::build_param_list ( double  fraction,
double  distance,
int  num_segs,
DLIList< RefVertex * > &  through_vertex_list 
)

Definition at line 594 of file TDSplitSurface.cpp.

{
  int i;
  double frac, param;
  // Add paramList.size to account for potential collapsed edge that already
  // has an item in the list
  for( i=1+paramList.size(); i<num_segs; i++ )
  {
    // Example locations (we need to fill middle only): 0 1 2 3 4
    if( num_segs > 2 )
      frac = (double)i/num_segs;
    else if( through_vertex_list.size() )
    {
      int j;
      int found = 0;
      through_vertex_list.reset();
      for( j=through_vertex_list.size(); j--; )
      {
        RefVertex *ref_vertex_ptr = through_vertex_list.get_and_step();
        if( is_vertex_on( ref_vertex_ptr ) )
        {
          coordList.append( new CubitVector( ref_vertex_ptr->coordinates() ) );
          if( u_from_position( ref_vertex_ptr->coordinates(), param ) == CUBIT_FAILURE )
            return CUBIT_FAILURE;
          paramList.append( param );
          found = 1;

          // Keep track of vertices that were used - we can give a warning when
          // done if some weren't used.
          TDSplitSurface *tdss = (TDSplitSurface *)ref_vertex_ptr->
            get_TD(&TDSplitSurface::is_split_surface);
          if( !tdss )
            ref_vertex_ptr->add_TD( new TDSplitSurface( 0 ) );
          break;
        }
      }
      if( found )
        continue;
      else
        frac = fraction;
    }
    else
      frac = fraction;

    if( distance != -1.0 )
    {
      if( distance > paramHigh )
      {
        PRINT_ERROR( "Surface %d is not wide enough to support split distance of %f\n",
          refFacePtr->id(), distance );
        return CUBIT_FAILURE;
      }
      param = distance;
    }
    else
      param = frac*paramHigh;

    paramList.append( param );

    CubitVector vec;
    if( position_from_u( param, vec ) == CUBIT_FAILURE )
      return CUBIT_FAILURE;
    
    coordList.append( new CubitVector( vec ) );
  }

  return CUBIT_SUCCESS;
}

Definition at line 500 of file TDSplitSurface.cpp.

{
  if( isCollapsed )
    return CUBIT_SUCCESS;

  int i, j, num_pnts;
  CoEdge *co_edge_ptr;
  SSParam *param_ptr;
  double param;
  CubitVector vec, *vec_ptr;

  coEdgeChain.reset();
  coEdgeParamList.reset();
  co_edge_ptr = coEdgeChain.get();
  param_ptr = coEdgeParamList.get();

  // Get the first coordinate
  if( co_edge_ptr->get_sense() == CUBIT_FORWARD )
    vec = co_edge_ptr->get_ref_edge_ptr()->start_coordinates();
  else
    vec = co_edge_ptr->get_ref_edge_ptr()->end_coordinates();

  // Add to list
  if( u_from_position( vec, co_edge_ptr, param_ptr, param ) == CUBIT_FAILURE )
    return CUBIT_FAILURE;
  paramList.append( param );

  for( i=coEdgeChain.size(); i--; )
  {
    DLIList<CubitVector*> temp_vec_list;
    co_edge_ptr = coEdgeChain.get_and_step();
    param_ptr = coEdgeParamList.get_and_step();
    GMem *g_mem = new GMem;
    
    co_edge_ptr->get_ref_edge_ptr()->get_graphics( *g_mem, tolerance );
    num_pnts = g_mem->pointListCount;
    
    GPoint* point_list = g_mem->point_list();
    
    for( j=0; j<num_pnts; j++ )
    {
      vec_ptr = new CubitVector(
        point_list[j].x, point_list[j].y, point_list[j].z );
      temp_vec_list.append( vec_ptr );
    }

    delete g_mem;

    if( co_edge_ptr->get_sense() == CUBIT_REVERSED )
      temp_vec_list.reverse();

    // Calculate corresponding parameter values
    temp_vec_list.reset();
    // Skip the first point since already in the list
    vec_ptr = temp_vec_list.get_and_step();
    for( j=1; j<num_pnts; j++ )
    {
      vec_ptr = temp_vec_list.get_and_step();
      if( u_from_position( *vec_ptr, co_edge_ptr, param_ptr, param )
        == CUBIT_FAILURE )
        return CUBIT_FAILURE;
      paramList.append( param );
    }

    while( temp_vec_list.size() )
      delete temp_vec_list.pop();
  }

  // Extremes of paramList should be 0.0 and paramHigh - force them to
  // these values exactly.  This avoids some slight roundoff errors that
  // can cause an extra split point close to the start or end of a surface
  // that won't even be cleaned up in syncronize_lists.  This causes 
  // unexpected results at the start or end of the split.
  paramList.reset();
  double first_param = paramList.get_and_back();
  double last_param = paramList.get();
  paramList.reset();
  if( first_param > last_param )
  {
    paramList.change_to( paramHigh );
    paramList.back();
    paramList.change_to( 0.0 );
  }
  else
  {
    paramList.change_to( 0.0 );
    paramList.back();
    paramList.change_to( paramHigh );
  }

  return CUBIT_SUCCESS;
}
DLIList< CoEdge * > * SSSide::co_edges ( ) [inline]

Definition at line 148 of file TDSplitSurface.hpp.

{ return &coEdgeChain; }

Definition at line 157 of file TDSplitSurface.hpp.

{ return coordList.get(); }

Definition at line 161 of file TDSplitSurface.hpp.

{ return coordList.get_and_back(); }

Definition at line 159 of file TDSplitSurface.hpp.

{ return coordList.get_and_step(); }
void SSSide::coord_list_last ( ) [inline]

Definition at line 155 of file TDSplitSurface.hpp.

{ coordList.last(); }
void SSSide::coord_list_reset ( ) [inline]

Definition at line 153 of file TDSplitSurface.hpp.

int SSSide::coord_list_size ( ) [inline]

Definition at line 151 of file TDSplitSurface.hpp.

{ return coordList.size(); }

Definition at line 177 of file TDSplitSurface.hpp.

{ return isCollapsed;}

Definition at line 468 of file TDSplitSurface.cpp.

{
  if( isCollapsed )
  {
    // Compare coordinates
    CubitVector *side_coord = coordList.get();
    
    if( side_coord->about_equal( ref_vertex_ptr->coordinates() ) )
      return CUBIT_TRUE;
    else
      return CUBIT_FALSE;
  }

  // Check if it is on each coedge
  CubitVector ref_coords = ref_vertex_ptr->coordinates();
  CubitPointContainment pnt_containment;
  int i;
  CoEdge *co_edge_ptr;
  coEdgeChain.reset();
  for( i=coEdgeChain.size(); i--; )
  {
    co_edge_ptr = coEdgeChain.get_and_step();
    pnt_containment = co_edge_ptr->get_ref_edge_ptr()->
      point_containment( ref_coords );
    if( pnt_containment == CUBIT_PNT_ON )
      return CUBIT_TRUE;
  }

  return CUBIT_FALSE;
}
double SSSide::length ( ) [inline]

Definition at line 145 of file TDSplitSurface.hpp.

{ return paramHigh; }
double SSSide::param_list_get ( ) [inline]

Definition at line 170 of file TDSplitSurface.hpp.

{ return paramList.get(); }
double SSSide::param_list_get_and_back ( ) [inline]

Definition at line 174 of file TDSplitSurface.hpp.

{ return paramList.get_and_back(); }
double SSSide::param_list_get_and_step ( ) [inline]

Definition at line 172 of file TDSplitSurface.hpp.

{ return paramList.get_and_step(); }
void SSSide::param_list_last ( ) [inline]

Definition at line 168 of file TDSplitSurface.hpp.

{ paramList.last(); }
void SSSide::param_list_reset ( ) [inline]

Definition at line 166 of file TDSplitSurface.hpp.

int SSSide::param_list_size ( ) [inline]

Definition at line 164 of file TDSplitSurface.hpp.

{ return paramList.size(); }
CubitStatus SSSide::position_from_u ( double  u_value,
CubitVector output_position 
)

Definition at line 333 of file TDSplitSurface.cpp.

{
  if( isCollapsed )
  {
    output_position = *coordList.get();
    return CUBIT_SUCCESS;
  }

  // Determine which CoEdge the given u is on
  int i;
  coEdgeChain.reset();
  coEdgeParamList.reset();
  CoEdge *co_edge_ptr = NULL;
  SSParam *param_ptr = NULL;
  double coedge_param_max;
  for( i=coEdgeChain.size(); i--; )
  {
    co_edge_ptr = coEdgeChain.get_and_step();
    param_ptr = coEdgeParamList.get_and_step();
    coedge_param_max = param_ptr->umax();
    if( u_value <= coedge_param_max )
      break;
  }

  // We have found the correct coedge.  Get it's RefEdge. 
  // Subtract it's start parameter.  
  // We now have the distance along the curve to traverse.
  RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
  double i_dist; // individual distance
  i_dist = u_value - param_ptr->umin();

  double ui_min, ui_max;
  ref_edge_ptr->get_param_range( ui_min, ui_max );

  if( co_edge_ptr->get_sense() == CUBIT_REVERSED ) 
    i_dist = ref_edge_ptr->measure() - i_dist;

  double ui = ref_edge_ptr->u_from_arc_length( ui_min, i_dist );

  return ref_edge_ptr->position_from_u( ui, output_position );
}
CubitStatus SSSide::syncronize_lists ( SSSide other_side,
double  param_tol = .1 
)

Definition at line 665 of file TDSplitSurface.cpp.

{
  // This will syncronize paramList in "this" and other_side, also
  // update coordList correspondingly in both.

  // Note: sideB and sideD (which we are operating on here) will contain the
  // corner coords (sideA and sideC just contain the interior coords)

  // This should never happen but check anyway
  if( paramHigh == 0.0 && other_side->paramHigh == 0.0 )
    return CUBIT_FAILURE;

  paramList.reset();
  other_side->paramList.reset();

  DLIList<double> other_param_list = other_side->paramList;
  int i;
  double param;

  // Reverse other_param_list (which is on side D) so that it is going in the
  // same direction as this paramList (side B)
  other_param_list.reset();
  for( i=other_param_list.size(); i--; )
  {
    param = other_param_list.get();
    other_param_list.change_to( other_side->paramHigh - param );
    other_param_list.step();
  }
  
  other_param_list.reverse(); // May make sort faster

  // Parameter lists must be "scaled" to match
  double this_factor = 1.0;
  double other_factor = 1.0;
  double scale_factor = 1.0;
  
  // Only scale if neither side is a zero length side and sides are not equal
  // in length
  if( !isCollapsed && !other_side->is_collapsed() &&
      other_side->paramHigh != paramHigh )
  {
    // Use longer side as "baseline" - it may have more "features"
    // so we will be sure to capture those
    if( paramHigh > other_side->paramHigh )
    {
      other_param_list.reset();

      other_factor = paramHigh/other_side->paramHigh;
      scale_factor = other_factor;
      for( i=other_param_list.size(); i--; )
      {
        param = other_param_list.get();
        other_param_list.change_to( param*other_factor );
        other_param_list.step();
      }
    }
    else
    {
      paramList.reset();

      this_factor = other_side->paramHigh/paramHigh;
      scale_factor = this_factor;
      for( i=paramList.size(); i--; )
      {
        param = paramList.get();
        paramList.change_to( param*this_factor );
        paramList.step();
      }
    }
  }

  DLIList<double> combined_param_list = paramList;
  combined_param_list.merge_unique( other_param_list );

  // This should never happen, but check anyway
  if( combined_param_list.size() < 2 )
    return CUBIT_FAILURE;

  // Sort the list from low to high
  combined_param_list.sort();

  // Remove near values
  param_tol = param_tol*scale_factor; // Scale tolerance to length
  double prev_param;
  combined_param_list.reset();
  prev_param = combined_param_list.get_and_step();
  for( i=combined_param_list.size()-2; i--; )
  {
    param = combined_param_list.get();
    if( fabs(param - prev_param) < param_tol )
    {
      combined_param_list.change_to( -1.0 );
    }
    else
    {
      prev_param = param;
    }
    combined_param_list.step();
  }
  combined_param_list.remove_all_with_value(-1.0);

  // We need to check if there are near coincident points at the end of the list
  combined_param_list.last();
  prev_param = combined_param_list.get_and_back();
  param = combined_param_list.get();
  // Use 10.0 * GEOMETRY_RESABS because Granite cannot handle points
  // any closer together when making a spline
  if( fabs( prev_param-param ) < 10.0*GEOMETRY_RESABS*scale_factor )
  {
    // Remove the second to last value
    combined_param_list.last();
    combined_param_list.back();
    combined_param_list.remove();

    if( combined_param_list.size() < 2 )
      return CUBIT_FAILURE;
  }

  // Also check if there are near coincident points anywhere along the 
  // other (shorter) side (very doubtful, but check anyway)
  if( scale_factor > 1.0 )
  {
    param_tol = 10.0*GEOMETRY_RESABS*scale_factor;
    double prev_param;
    combined_param_list.reset();
    prev_param = combined_param_list.get_and_step();
    for( i=combined_param_list.size()-2; i--; )
    {
      param = combined_param_list.get();
      if( fabs(param - prev_param) < param_tol )
      {
        combined_param_list.change_to( -1.0 );
      }
      else
      {
        prev_param = param;
      }
      combined_param_list.step();
    }
    combined_param_list.remove_all_with_value(-1.0);
  }
  
  // Update this paramList
  if( isCollapsed )
  {
    // This is a collapsed triangle side, so just stuff it with the proper
    // number of params and coordinates
    paramList.clean_out();
    for( i=combined_param_list.size(); i--; )
      paramList.append( 0.0 );

    // It will already have one coordinate - copy it to the others
    CubitVector *vec;
    vec = coordList.get();
    for( i=combined_param_list.size()-1; i--; )
      coordList.append( new CubitVector( *vec ) );
  }
  else
  {
    paramList.clean_out();
    paramList = combined_param_list;

    // Generate this coordList.
    CubitVector vec;
    paramList.reset();
    for( i=paramList.size(); i--; )
    {
      param = paramList.get();
      param = param/this_factor; // Normalize it
      paramList.change_to( param ); // Set proper value in paramList
      position_from_u( param, vec );
      coordList.append( new CubitVector( vec ) );
      paramList.step();
    }
  }

  // Do the same for the other side
  if( other_side->is_collapsed() )
  {
    // This is a collapsed triangle side, so just stuff it with the proper
    // number of params and coordinates
    other_side->paramList.clean_out();
    for( i=combined_param_list.size(); i--; )
      other_side->paramList.append( 0.0 );

    // It will already have one coordinate - copy it to the others
    CubitVector *vec;
    vec = other_side->coordList.get();
    for( i=combined_param_list.size()-1; i--; )
      other_side->coordList.append( new CubitVector( *vec ) );
  }
  else
  {
    combined_param_list.reset();
    for( i=combined_param_list.size(); i--; )
    {
      param = combined_param_list.get();
      combined_param_list.change_to( other_side->paramHigh-param/other_factor );
      combined_param_list.step();
    }
    combined_param_list.reverse();

    CubitVector vec;
    other_side->paramList.clean_out();
    other_side->paramList = combined_param_list;
    combined_param_list.reset();
    for( i=combined_param_list.size(); i--; )
    {
      param = combined_param_list.get_and_step();
      other_side->position_from_u( param, vec );
      other_side->coordList.append( new CubitVector( vec ) );
    }
  }

  return CUBIT_SUCCESS;
}
CubitStatus SSSide::u_from_position ( const CubitVector input_position,
double &  u 
)

Definition at line 376 of file TDSplitSurface.cpp.

{
  if( isCollapsed )
  {
    u = 0.0;
    return CUBIT_SUCCESS;
  }

  // First check each curve to determine which one the input position is on
  int i;
  coEdgeChain.reset();
  coEdgeParamList.reset();
  CoEdge *co_edge_ptr = NULL;
  SSParam *param_ptr = NULL;
  int found = 0;
  CubitPointContainment pnt_containment;
  for( i=coEdgeChain.size(); i--; )
  {
    co_edge_ptr = coEdgeChain.get_and_step();
    param_ptr = coEdgeParamList.get_and_step();
    pnt_containment = co_edge_ptr->get_ref_edge_ptr()->point_containment( input_position );
    if( pnt_containment == CUBIT_PNT_ON )
    {
      found = 1;
      break;
    }
  }

  if( !found )
  {
    PRINT_ERROR( "Position %f, %f, %f not found on any curve.\n",
      input_position.x(), input_position.y(), input_position.z() );
    return CUBIT_FAILURE;
  }

  // Now we know which CoEdge it is on.  Get the curve. Get the parameter of 
  // the individual curve.
  RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
  double ui = ref_edge_ptr->u_from_position( input_position );
  
  // Get the parameter of the composite curve

  // Add the distance along the curve to its start param (umin)
  double sum = param_ptr->umin();

  double ui_min, ui_max;
  ref_edge_ptr->get_param_range( ui_min, ui_max );

  CubitSense sense = co_edge_ptr->get_sense();
  double root_param = (sense == CUBIT_FORWARD) ? ui_min : ui_max;
  double lfu = ( root_param < ui ) ?
    ref_edge_ptr->length_from_u( root_param, ui ) :
    ref_edge_ptr->length_from_u( ui, root_param );

  u = sum + fabs( lfu );

  return CUBIT_SUCCESS;
}
CubitStatus SSSide::u_from_position ( const CubitVector input_position,
CoEdge co_edge_ptr,
SSParam param,
double &  u 
)

Definition at line 437 of file TDSplitSurface.cpp.

{
  if( isCollapsed )
  {
    u = 0.0;
    return CUBIT_SUCCESS;
  }

  RefEdge *ref_edge_ptr = co_edge_ptr->get_ref_edge_ptr();
  double ui = ref_edge_ptr->u_from_position( input_position );

  // Get the parameter of the composite curve
  double sum = param->umin();

  double ui_min, ui_max;
  ref_edge_ptr->get_param_range( ui_min, ui_max );

  CubitSense sense = co_edge_ptr->get_sense();
  double root_param = (sense == CUBIT_FORWARD) ? ui_min : ui_max;
  double lfu = ( root_param < ui ) ?
    ref_edge_ptr->length_from_u( root_param, ui ) :
    ref_edge_ptr->length_from_u( ui, root_param );

  u = sum + fabs( lfu );

  return CUBIT_SUCCESS;
}

Member Data Documentation

Definition at line 133 of file TDSplitSurface.hpp.

Definition at line 135 of file TDSplitSurface.hpp.

Definition at line 137 of file TDSplitSurface.hpp.

Definition at line 142 of file TDSplitSurface.hpp.

double SSSide::paramHigh [private]

Definition at line 134 of file TDSplitSurface.hpp.

DLIList<double> SSSide::paramList [private]

Definition at line 138 of file TDSplitSurface.hpp.

Definition at line 132 of file TDSplitSurface.hpp.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines