Beispiel #1
0
//-------------------------------------------------------------------------
// Purpose       : 
//
// Special Notes : 
//
// Creator       : Jason Kraftcheck
//
// Creation Date : 05/26/04
//-------------------------------------------------------------------------
void PartitionBody::get_all_children( DLIList<PartitionEntity*>& list )
{
  DLIList<PartitionEntity*> tmp;
  for (SubEntitySet* ptr = childList; ptr; ptr = ptr->bodyNext )
  {
    tmp.clean_out();
    ptr->get_sub_entities( tmp );
    list += tmp;
    
    tmp.clean_out();
    ptr->get_lower_order( tmp );
    list += tmp;
  }
}
Beispiel #2
0
//-------------------------------------------------------------------------
// Purpose       : Get named attributes
//
// Special Notes : 
//
// Creator       : Jason Kraftcheck
//
// Creation Date : 03/03/03
//-------------------------------------------------------------------------
void CompositeGeom::get_attributes( const char* name,
                                    DLIList<CubitSimpleAttrib>& list )
{
  if (entityList.size() == 1)
  {
      // handle 8.1 attribs on single-entity 'composites'
    list.clean_out();
    entityList[0].entity->get_simple_attribute(COMPOSITE_DATA_ATTRIB_NAME,list);
    while (list.size())
    {
      CubitSimpleAttrib attrib = list.pop();
      if (attrib.int_data_list()[0] == 1)
      {
        entityList[0].entity->remove_simple_attribute_virt(attrib);
        std::vector<CubitString> s(attrib.string_data_list().begin()+1, attrib.string_data_list().end());
        std::vector<int> i(attrib.int_data_list().begin()+1, attrib.int_data_list().end());
        CubitSimpleAttrib new_attrib(&s, &attrib.double_data_list(), &i);
        entityList[0].entity->append_simple_attribute_virt(new_attrib);
      }
    }
    
    entityList[0].entity->get_simple_attribute(name, list);
  }
    
  for (CompositeAttrib* ptr = listHead; ptr; ptr = ptr->next)
    if (ptr->name() == name)
      list.append(ptr->csa());
}
Beispiel #3
0
void CAMergePartner::merge_prepare(DLIList<RefEntity*> &merge_list)
{
  DLIList<CubitAttrib*> my_ca_list;
  CAMergePartner *my_camp_ptr;
  RefEntity* re_ptr;

    // get all the merge partner attributes that are on my owner
  attribOwnerEntity->find_cubit_attrib_type(CA_MERGE_PARTNER, my_ca_list);
  merge_list.clean_out();
  DLIList<ToolDataUser*> td_list, temp_td_list;
  int i;
  for (i = my_ca_list.size(); i > 0; i--)
  {
    my_camp_ptr = CAST_TO(my_ca_list.get(),CAMergePartner);
    my_ca_list.step();
    td_list.clean_out();
      // get all the objects with this unique id (which is also the merge id)
    TDUniqueId::find_td_unique_id(my_camp_ptr->merge_id(), temp_td_list);
    td_list += temp_td_list;
  }
  
    // now put those entities into the merge_list
  for (i = td_list.size(); i > 0; i--) 
  {
    re_ptr = CAST_TO(td_list.get(), RefEntity);
    if (re_ptr) 
    {
      CubitAttrib *tmp_attrib = re_ptr->get_cubit_attrib( CA_MERGE_PARTNER, CUBIT_FALSE );
      if( tmp_attrib )
        merge_list.append(re_ptr);
    }
    td_list.step();
  }
  
    // Now get bridge sense for each entity in list.
    // Add this entity to list, too.
  merge_list.append( attribOwnerEntity );
  for( i = merge_list.size(); i--; )
  {
    RefEntity* ent = merge_list.get_and_step();
    TopologyEntity* te = dynamic_cast<TopologyEntity*>(ent);
    if( te->bridge_manager()->number_of_bridges() != 1 )
      continue;
    
    my_ca_list.clean_out();
    ent->find_cubit_attrib_type(CA_MERGE_PARTNER, my_ca_list);
    assert( my_ca_list.size() < 2);
    if( !my_ca_list.size() )
      continue;
    
    my_camp_ptr = dynamic_cast<CAMergePartner*>(my_ca_list.get());
    if( my_camp_ptr->bridge_sense() == CUBIT_UNKNOWN )
      continue;
  }  
  merge_list.pop(); // take attribOwnerEntity back off list
    
  return;
}
Beispiel #4
0
void DagDrawingTool::get_relatives( ModelEntity* source_ptr,
	DLIList<ModelEntity*>& result_set, int direction )
{
	result_set.clean_out();
	if( direction == DDT_UP_DAG ) 
		source_ptr->get_parents( &result_set );
	else if( direction == DDT_DOWN_DAG )
	  source_ptr->get_children( &result_set  );
	else assert( (direction == DDT_UP_DAG) || (direction == DDT_DOWN_DAG) );
}
Beispiel #5
0
void DagDrawingTool::get_relatives( DLIList<ModelEntity*>& source_set,
	DLIList<ModelEntity*>& result_set, int direction )
{
	DLIList<ModelEntity*> temp_set;
	result_set.clean_out();
	for( int i = 0; i < source_set.size();  i++ )
	{
		get_relatives( source_set.get_and_step(), temp_set, direction );
		result_set.merge_unique( temp_set );
	}
}
Beispiel #6
0
int TDUniqueId::find_td_unique_id(const int temp_id,
                                  DLIList<ToolDataUser*> &td_list,
                                  const RefEntity *related_entity)
{
  td_list.clean_out();

  int unique_id = temp_id;

  //if we are not doing an undo and importing and merging within a file...
  if( !GSaveOpen::performingUndo && 
       GeometryQueryTool::importingSolidModel &&
      !GeometryQueryTool::mergeGloballyOnImport)
  {
    //see if the old id maps to a new id...if so, use the new id
    UIDMap old_uid_to_new_uid_map = CAUniqueId::get_old_to_new_uid_map();
    
    UIDMap::iterator iter;
    iter = old_uid_to_new_uid_map.find( unique_id );
    
    if( iter != old_uid_to_new_uid_map.end() )
      unique_id = (*iter).second;
  }
  
  std::pair<TDUIDList::iterator, TDUIDList::iterator> 
    bounds_pair = unique_id_list().equal_range(unique_id);

  TDUIDList::iterator
    it = bounds_pair.first, upper = bounds_pair.second;
 
  if(it == unique_id_list().end())
    return 0;

  if ((*it).first == unique_id ) {
      // the lower bound key is equal to unique_id, so this id is in the list

      // look for duplicate id's, return one that's directly related
      // get all td's with that id
    for (; it != upper; it++) 
    {
      bool related = true;
      ToolDataUser *temp_tdu = (*it).second->owner_entity();
      if (NULL != related_entity) {
        TopologyEntity *topo_ent = CAST_TO(temp_tdu, TopologyEntity);
        RefEntity* temp_entity = const_cast<RefEntity*>(related_entity);
        if (!topo_ent ||
            !topo_ent->is_directly_related(CAST_TO(temp_entity, TopologyEntity))) 
          related = false;
      }
      if (related) td_list.append(temp_tdu);
    }
  }

  return td_list.size();
}
Beispiel #7
0
//=============================================================================
//Function:  get_vertices (PUBLIC)
//Description: get the list of ChollaPoints on this surface
//Author: sjowen
//Date: 09/11/09
//=============================================================================
void ChollaSurface::get_vertices( DLIList<ChollaPoint *> &chpt_list )
{
  chpt_list.clean_out();
  ChollaCurve *chcurv_ptr;
  for (int ii=0; ii<curveList.size(); ii++)
  {
    chcurv_ptr = curveList.get_and_step();
    DLIList<ChollaPoint *> chc_pts = chcurv_ptr->get_points(); 
    chpt_list += chc_pts;
  }
  chpt_list.uniquify_unordered();
}
Beispiel #8
0
void PointGridSearch::get_neighborhood_points_sorted(
  DLIList<CubitPoint*> &point_list,
  const CubitVector& center, double cut_off)
{
  point_list.clean_out();
  DLIList<CubitPoint*> temp_point_list;
  int i;

  for (int k = boundingCellMinimumZ; k <= boundingCellMaximumZ; k++)
  {
    int kn = numberGridCellsY * k;
    for (int j = boundingCellMinimumY; j <= boundingCellMaximumY; j++)
    {
      int jn = numberGridCellsX * (kn + j);
      for ( i = boundingCellMinimumX; i <= boundingCellMaximumX; i++)
      {
	int in = jn + i;
        if (neighborhoodList[in])
        {
          temp_point_list += *(neighborhoodList[in]);
        }
      }
    }
  }

  // evaluate point distance to center ... remove those larger than cut_off
  SDLByDouble sorted_index_list;
  IndexedDouble *ID;  
  CubitVector vec;
  cut_off *= cut_off;
  temp_point_list.reset();
  for ( i = 0; i < temp_point_list.size(); i++)
  {
    vec = center - temp_point_list.get_and_step()->coordinates();
    double distance = vec.length_squared();
    if (distance < cut_off)
    {
      ID = new IndexedDouble( i, distance );
      sorted_index_list.append( ID );
    }
  }

  sorted_index_list.sort();
  temp_point_list.reset();
  for ( i = 0; i < sorted_index_list.size(); i++ )
  {
    ID = sorted_index_list.get_and_step();
    point_list.append( temp_point_list.next( ID->index() ) );
    delete ID;
  }
}
Beispiel #9
0
CubitStatus PartitionShell::mass_properties( CubitVector& centroid, 
                                             double& volume )
{
  PartitionCoSurf* cosurf = 0;
  DLIList<CubitFacetData*> facets;
  CubitVector p1, p2, p3, normal;
  const CubitVector p0(0.0, 0.0, 0.0);
  centroid.set(0.0, 0.0, 0.0 );
  volume = 0.0;
  
  while ((cosurf = next_co_surface( cosurf )))
  {
    if (is_nonmanifold( cosurf->get_surface() ))
      continue;
    
    facets.clean_out();
    cosurf->get_surface()->get_facet_data( facets );
    
    for (int i = facets.size(); i--; )
    {
      CubitFacet* facet = facets.step_and_get();
      p1 = facet->point(0)->coordinates();
      p2 = facet->point(1)->coordinates();
      p3 = facet->point(2)->coordinates();
      normal = (p3 - p1) * (p2 - p1);
  
      double two_area = normal.length();
      if (two_area > CUBIT_RESABS )
      {
        if (cosurf->sense() == CUBIT_REVERSED)
          normal = -normal;
        
        normal /= two_area;
        
        double height = normal % (p0 - p1);
        double vol = two_area * height;
        
        volume += vol;
        centroid += vol * (p0 + p1 + p2 + p3);
      }
    }
  }
  
  if (volume > CUBIT_RESABS)
    centroid /= 4.0 * volume;
  volume /= 6.0;
  return CUBIT_SUCCESS;
}
Beispiel #10
0
void PointGridSearch::get_neighborhood_facets( DLIList<CubitFacet*> &facet_list )
{
  // retrieve points over the current bounding box range

  facet_list.clean_out();
  DLIList<CubitPoint*> point_list;
  get_neighborhood_points( point_list );

  // retrieve all faces attached to the points in point_list

  for (int i = 0; i < point_list.size(); i++)
  {
    CubitPoint* point = point_list.get_and_step();

    DLIList<CubitFacet*> temp_facet_list;
    point->facets(temp_facet_list);

    for (int j = 0; j < temp_facet_list.size(); j++)
    {
      CubitFacet* facet = temp_facet_list.get_and_step();

      if (!facet->marked())
      {
        facet->marked(CUBIT_TRUE);
        facet_list.append(facet);
      }
    }
  }

  // unmark the found faces and return face_list

  for (int m = 0; m < facet_list.size(); m++)
  {
    facet_list.get_and_step()->marked(CUBIT_FALSE);
  }

}
Beispiel #11
0
void PointGridSearch::get_neighborhood_points( DLIList<CubitPoint*> &point_list )
{
  // retrieve points over the current bounding box range

  point_list.clean_out();

  for (int k = boundingCellMinimumZ; k <= boundingCellMaximumZ; k++)
  {
    int kn = numberGridCellsY * k;
    for (int j = boundingCellMinimumY; j <= boundingCellMaximumY; j++)
    {
      int jn = numberGridCellsX * (kn + j);
      for (int i = boundingCellMinimumX; i <= boundingCellMaximumX; i++)
      {
        int in = jn + i;
        assert( in >= 0 && in < numberGridCells );
        if (neighborhoodList[in])
        {
           point_list += *(neighborhoodList[in]);
        }
      }
    }
  }
}
Beispiel #12
0
CubitStatus make_Point()
{
  GeometryQueryTool *gti = GeometryQueryTool::instance();
  GeometryModifyTool *gmti = GeometryModifyTool::instance();

  DLIList<Body*> bodies;
  DLIList<RefEntity*>  free_entities;

  // Read in the geometry from files specified on the command line
  const char *argv = "stitch.name_occ";
  CubitStatus status = read_geometry(1, &argv, false);
  if (status == CUBIT_FAILURE) exit(1);
  //Read in 2 volumes.

  gti->bodies(bodies);
  DLIList<Body*> new_bodies;
  DLIList<Body*> from_bodies;
  BodySM* from_body = bodies.get()->get_body_sm_ptr();
  from_bodies.append(bodies.get());
  CubitVector v1(.5,1,3);
  CubitVector v2(.5,2,2);
  CubitVector v3(.5,1,1);
  BodySM* midplane_bodysm = 0;
  status = OCCModifyEngine::instance()->get_mid_plane(v1, v2, v3, from_body, midplane_bodysm);
  if(midplane_bodysm)
  {
    Body *midplane_body;
    midplane_body = gti->make_Body(midplane_bodysm);
    double d = midplane_body->measure();
    assert( d > 99.9999 && d < 100.00001);
  }

  v1.x(2);
  v2.x(2);
  v3.x(2);
  
  midplane_bodysm = 0;
  status = OCCModifyEngine::instance()->get_mid_plane(v1, v2, v3, from_body, midplane_bodysm);
  if(midplane_bodysm)
  {
    Body *midplane_body;
    midplane_body = gti->make_Body(midplane_bodysm);
    double d = midplane_body->measure();
    assert( d > 69.9999 && d < 70.00001);
  }

  DLIList<Body*> neighbor_list;
  status = gmti->webcut_with_plane(from_bodies, v1, v2, v3, new_bodies, neighbor_list, ONLY_INVOLVED_BODIES);
  double d = new_bodies.step_and_get()->measure();
  CubitVector v = new_bodies.get()->center_point();
  int n = new_bodies.get()->num_ref_faces();
  assert(n==8);
  assert(d <= 710 && d > 709.999999);
  // n = 8
  //new bodies has 2 bodies, one has a volume = 170 and the other has a 
  //volume = 710; each of them has 8 ref_faces. 

  bodies.clean_out();
  gti->bodies(bodies);
  //delete all entities
  gti->delete_Body(bodies); 
  
  gti->get_free_ref_entities(free_entities);
  assert(free_entities.size() ==0);

  return CUBIT_SUCCESS;
}
Beispiel #13
0
void CubitUtil::sort_and_print_ids( const char *const heading,
                                      DLIList<int> &id_list,
                                      int should_sort, int report_once,
                                      int wrap )
{
    // sort, if desired
  if ( should_sort ) {
    id_list.sort();
  }

  if ( report_once ) {
    DLIList <int> id_list_2( id_list );
    id_list_2.reset();
    id_list.clean_out();
    id_list.append( id_list_2.get_and_step() );
    for ( int j = id_list_2.size()-1; j--; )
    {
      if ( id_list_2.get() != id_list_2.prev() )
        id_list.append( id_list_2.get() );
      id_list_2.step();
    }
  }

  if( wrap == -1 )
  {
    // print out ranges
    int begin = id_list.get_and_step();
    int end = begin;
    int current = -1;
    PRINT_INFO("  The %d %s ids are %d", id_list.size(), heading, begin);
    for (int i=id_list.size()-1; i > 0; i--) {
      current = id_list.get_and_step();
      if (current == end+1) {
        end++;
      }
      else {
        if (end == begin) {
          PRINT_INFO(", %d", current);
        }
        else if (end == begin+1) {
          PRINT_INFO(", %d, %d", end, current);
        }
        else {
          PRINT_INFO(" to %d, %d", end, current);
        }
        begin = current;
        end = begin;
      }
    }
    if (current == begin + 1)	{
      PRINT_INFO(", %d", current);
    }
    else if (current != begin) {
      PRINT_INFO(" to %d", current);
    }
    PRINT_INFO(".\n");
  }
  else
  {
    char pre_string[67];
    sprintf( pre_string, "  The %d %s ids are: ", id_list.size(),heading );
    CubitUtil::list_entity_ids( pre_string, id_list, wrap, ".\n", CUBIT_FALSE,
                                CUBIT_FALSE );
  }
}
Beispiel #14
0
//-------------------------------------------------------------------------
// Purpose       : Read and remove attributes from underlying entities
//
// Special Notes : 
//
// Creator       : Jason Kraftcheck
//
// Creation Date : 06/30/03
//-------------------------------------------------------------------------
void CompositeGeom::read_attributes( GeometryEntity* geom_ptr )
{
  DLIList<CubitSimpleAttrib> list;
  int i;

    // remove any attributes from previous read
  rem_all_attributes();

  if (geom_ptr)
  {
      // Special case for point-curves (no real curves to write
      // attirbutes to.)  Write to passed entity instead.
    assert(entityList.size() == 0);
    geom_ptr->get_simple_attribute(COMPOSITE_DATA_ATTRIB_NAME,list);
    
    list.reset();
    for (i = list.size(); i--; )
    {
      const CubitSimpleAttrib& attrib = list.get_and_step();
      assert(attrib.int_data_list().size());
      if (attrib.int_data_list()[0] == entityList.size())
      {
        geom_ptr->remove_simple_attribute_virt(attrib);
        CubitSimpleAttrib c = attrib;
        c.int_data_list().erase(c.int_data_list().begin());
        c.string_data_list().erase(c.string_data_list().begin());
        listHead = new CompositeAttrib(c,listHead);
      }
    }
    
    return;
  }

  int index_of_entity_with_attribs = -1;

  for (i = 0; i < entityList.size(); i++)
  {
    list.clean_out();
    entityList[i].entity->get_simple_attribute(COMPOSITE_DATA_ATTRIB_NAME,list);

    if( list.size() )
      index_of_entity_with_attribs = i;
  
    list.reset();
    for (int j = list.size(); j--; )
    {
      const CubitSimpleAttrib& attrib = list.get_and_step();
      assert(attrib.int_data_list().size());
      if (attrib.int_data_list()[0] == entityList.size())
      {
        // Take the attributes off of the current entity and put them on the first entity
        // in this list.  I believe this is ok to do because the attributes should apply to
        // the whole composite surface and not just the underlying entity they are on 
        // (the one exception to this might be UNIQUE_ID but I haven't seen any problems
        // with this yet).  The reason for doing this is that there is some code (I believe
        // in uncomposite() that assumes any attributes will be on the first entity
        // in the list.  Previous code actually moved the entity to the beginning
        // of the list but this reordering of the list does not fly with composite
        // curves because there is code depending on the curves in the list being
        // ordered so that they connect end to end in a contiguous manner (the 
        // faceting code, for one, relies on this).  BWC 1/7/07.
        entityList[i].entity->remove_simple_attribute_virt(attrib);
        entityList[0].entity->append_simple_attribute_virt(attrib);

        CubitSimpleAttrib c = attrib;
        c.int_data_list().erase(c.int_data_list().begin());
        c.string_data_list().erase(c.string_data_list().begin());      

        if( NULL == listHead )
          listHead = new CompositeAttrib(c,listHead);               
        else //this assures that we are not adding duplicate attribs 
        {
          bool is_duplicate = false;

          CompositeAttrib* curr_attrib = listHead;

          while( curr_attrib )
          {
            if( curr_attrib->equals( c ) )
            {
              is_duplicate = true;
              break;
            }
            curr_attrib = curr_attrib->next;
          }

          if( false == is_duplicate )
            listHead = new CompositeAttrib(c,listHead);
        }
      }
    }
  }
}
Beispiel #15
0
CubitStatus FacetLump::mass_properties( CubitVector& centroid, double& volume )
{
  int i;
  
  DLIList<FacetShell*> shells( myShells.size() );
  CAST_LIST( myShells, shells, FacetShell );
  assert( myShells.size() == shells.size() );
  
  DLIList<FacetSurface*> surfaces;
  DLIList<FacetShell*> surf_shells;
  get_surfaces( surfaces );
  
  DLIList<CubitFacet*> facets, surf_facets;
  DLIList<CubitPoint*> junk;
  DLIList<CubitSense> senses;
  for (i = surfaces.size(); i--; )
  {
    FacetSurface* surf = surfaces.step_and_get();
    surf_shells.clean_out();
    surf->get_shells( surf_shells );
    surf_shells.intersect( shells );
    assert( surf_shells.size() );
    CubitSense sense = surf->get_shell_sense( surf_shells.get() );
    if (surf_shells.size() == 1 && CUBIT_UNKNOWN != sense)
    {
      surf_facets.clean_out();
      junk.clean_out();
      surf->get_my_facets( surf_facets, junk );
      facets += surf_facets;
      
      for (int j = surf_facets.size(); j--; )
        senses.append(sense);
    }
  }
  
  const CubitVector p0 = bounding_box().center();
  CubitVector p1, p2, p3, normal;
  centroid.set( 0.0, 0.0, 0.0 );
  volume = 0.0;
  
  facets.reset();
  senses.reset();
  for (i = facets.size(); i--; )
  {
    CubitFacet* facet = facets.get_and_step();
    CubitSense sense = senses.get_and_step();
    p1 = facet->point(0)->coordinates();
    p2 = facet->point(1)->coordinates();
    p3 = facet->point(2)->coordinates();
    normal = (p3 - p1) * (p2 - p1);

    double two_area = normal.length();
    if (two_area > CUBIT_RESABS )
    {
      if (CUBIT_REVERSED == sense)
        normal = -normal;

      normal /= two_area;

      double height = normal % (p0 - p1);
      double vol = two_area * height;

      volume += vol;
      centroid += vol * (p0 + p1 + p2 + p3);
    }
  }
  
  if (volume > CUBIT_RESABS)
    centroid /= 4.0 * volume;
  volume /= 6.0;
  return CUBIT_SUCCESS;
}
Beispiel #16
0
// order edges in list beginning at start_point
// report the endpoint
// return CUBIT_SUCCESS if all edges are connected and ordered successfully
// otherwise return CUBIT_FAILURE, in which case no changes are made
CubitStatus CubitFacetEdge::order_edge_list(DLIList<CubitFacetEdge*> &edge_list,
                                            CubitPoint *start_point,
                                            CubitPoint *&end_point)
{
  int i;
  assert(start_point);

  end_point = NULL;

  // invalid input
  if (0 == edge_list.size())
    return CUBIT_FAILURE;

  // simple case of a single edge - endpoitn
  if (1 == edge_list.size())
  {
    end_point = edge_list.get()->other_point(start_point);
    return end_point ? CUBIT_SUCCESS : CUBIT_FAILURE;
  }

  edge_list.reset();

  // note that a periodic/closed curve will fail
  // we could handle that case here if needed, but we may need more information
  // to know where to start and end the curve
  if (NULL == start_point)
    return CUBIT_FAILURE;

  // put edges in a set for faster searching
  std::set<CubitFacetEdge *> edge_set;
  for (i=0; i<edge_list.size(); i++)
    edge_set.insert(dynamic_cast<CubitFacetEdge*> (edge_list.step_and_get()));

  // a vector for the ordered list
  std::vector<CubitFacetEdge*> ordered_edges;

  // find connected edges from the start point
  CubitPoint *cur_pt = start_point;
  do
  {
    // get edges connected to the current point and find the next edge
    DLIList<CubitFacetEdge *> pt_edges;
    cur_pt->edges(pt_edges);

    std::set<CubitFacetEdge *>::iterator iter_found;
    CubitFacetEdge *cur_edge = NULL;
    for (i=0; i<pt_edges.size() && !cur_edge; i++)
    {
      CubitFacetEdge *tmp_edge = pt_edges.get_and_step();
      iter_found = edge_set.find(tmp_edge);
      if ( iter_found != edge_set.end() )
        cur_edge = tmp_edge;
    }

    // if we don't find a connection before we empty the set
    // then not all the edges are connected  -- return failure
    if (NULL == cur_edge)
      return CUBIT_FAILURE;

    // add the edge to the ordered list
    ordered_edges.push_back( cur_edge );
    edge_set.erase(iter_found);

    cur_pt = cur_edge->other_point(cur_pt);
  }
  while ( edge_set.size());

  if (ordered_edges.size() != edge_list.size())
    return CUBIT_FAILURE;

  // store the edges in the correct order
  edge_list.clean_out();

  std::vector<CubitFacetEdge*>::iterator iter;
  for (iter=ordered_edges.begin(); iter!=ordered_edges.end(); iter++)
    edge_list.append(*iter);

  // get the end point
  CubitFacetEdge *edge1 = edge_list[edge_list.size() - 1];
  CubitFacetEdge *edge2 = edge_list[edge_list.size() - 2];

  end_point = edge1->other_point( edge1->shared_point(edge2) );

  return CUBIT_SUCCESS;
}
Beispiel #17
0
CubitStatus ModelEntity::remove_from_DAG(CubitBoolean recurse_flag)
{
     // This counter will be used in the recursion to test whether
     // the call is from outside or from the function itself. When
     // the call comes from outside, the counter should always be
     // zero.

  CubitBoolean this_recurse = recurse_flag;
  if (recurse_flag == CUBIT_FALSE) recurse_flag = CUBIT_TRUE;
  
  DLIList<ModelEntity*> childModEntList;
   
     // Check to see if there are no parents of this object. 
   if ( get_parents() == 0 )
   {
      if (this_recurse == CUBIT_FALSE)
      {
         // Since we are not recursing, this is a top-level entity.
         // Notify the static observers that a top-level entity is being
         // destructed.  This must be done before children are disconnected.
       CubitObservable *top_level = CAST_TO(this, CubitObservable);
       CubitObserver::notify_static_observers(top_level, TOP_LEVEL_ENTITY_DESTRUCTED);
      }

        // Go through all the children and remove their link to
        // the current object.
      
      ModelEntity* tempModEntPtr = NULL ;
      ModelEntity* childModEntPtr = NULL ;
      
      childModEntList.clean_out();
      disconnect_all_children(&childModEntList);
      
        // The following while conditional may not work...it depends on
        // what is_at_end does when you step over the end...CHECK THIS
      int i;
      for( i = 0 ; i < childModEntList.size() ; i++ )
      {
           // Get the next ModelEnti in the child list and make sure its
           // pointer to its parent is removed.
         tempModEntPtr = childModEntList.get_and_step();
          
           // Try remove() on the child ModEnt. If it comes back with
           // a success, then delete it.
         childModEntPtr = tempModEntPtr;
         
         if ( childModEntPtr->remove_from_DAG(recurse_flag) == CUBIT_SUCCESS )
         {
              // Now deactivate the child ModEnt
            childModEntPtr->deactivated(CUBIT_TRUE) ;

              // remove it from observables, just before we go to delete it
            CubitObservable *observable = CAST_TO(childModEntPtr, CubitObservable);
            if (observable) 
            {
              if( !observable->notify_observers( MODEL_ENTITY_DESTRUCTED ) )
                 return CUBIT_FAILURE;
            }
         }
      }
      
      
        // If this is the top of the recursion, then clean out all the deactivated
        // entities.
      if (this_recurse == CUBIT_FALSE)
      {
         this->deactivated(CUBIT_TRUE) ;

         // remove it from observables, just before we go to delete it
         CubitObservable *observable = CAST_TO(childModEntPtr, CubitObservable);
         if (observable) 
         {
           if( !observable->notify_observers( MODEL_ENTITY_DESTRUCTED ) )
              return CUBIT_FAILURE;

         }
         GeometryQueryTool::instance()->cleanout_deactivated_geometry() ;
      }
      
      return CUBIT_SUCCESS ;
   }
   else
   {
      return CUBIT_FAILURE ;
   }
}
Beispiel #18
0
void CubitUtil::process_entity_ids( int method,
                                    CubitString &ret_str,
                                    const char *pre_string, 
                                    DLIList<int> &id_list,
                                    int max_len, 
                                    const char *post_string,
                                    int sort, int unique,
                                    int tab_len, const char *sep_string,
                                    const char* post_string_none ) 
{
  // Method: 0 - to a string
  //         1 - to PRINT_INFO
  char temp[200];

  if ( id_list.size() == 0 ) {
    if( method )
      PRINT_INFO("%s%s", pre_string, post_string_none );
    else
    {
      sprintf( temp, "%s%s", pre_string, post_string_none );
      ret_str = temp;
    }
    if( fp )
      fprintf( fp, "%s%s", pre_string, post_string_none );
    return;
  }

  // sort
  if( sort )
  {
    id_list.sort();
    
    // make unique
    if( unique ) 
    {
      int i;
      DLIList <int> id_list_2( id_list );
      id_list_2.reset();
      id_list.clean_out();
      id_list.append( id_list_2.get_and_step() );
      for ( i=id_list_2.size()-1; i--; ) 
      {
        if ( id_list_2.get() != id_list_2.prev() )
          id_list.append( id_list_2.get() );
        id_list_2.step();
      }
    }
  }

  if( max_len < 0 )
    max_len = CUBIT_INT_MAX/2;
    
  // TODO: wrap prestring, if necessary
  if( method )
    PRINT_INFO( "%s", pre_string );
  else
    ret_str = pre_string;
  if( fp )
    fprintf( fp, "%s", pre_string );

  // Keep track of length printed
  int curr_len = strlen(pre_string);
  
  int num = 0;
  int begin = id_list.get();
  int previous = begin;
  int current;
  int comma = 0; // Is comma needed
  int beg_len, prev_len;
  int sep_len = strlen( sep_string );

  // Setup the tab
  char* tab = new char[tab_len+1];
  for( int i=0; i<tab_len; i++ )
     tab[i] = ' ';
  tab[tab_len] = '\0';

  // Loop until all the ids are printed.  Use ranges if possible.
  while( num < id_list.size()+1 )
  {
    current = id_list.get_and_step();
    num++;

    // Handle last entity
    if( num <= id_list.size() )
    {
      if( num==1 ) // Handle 1st time in loop
        continue;
      
      if( current==previous+1 )
      {
        previous = current;
        continue;
      }
    }

    // If we are here, we are no longer tracking a range and
    // need to print the range or a number.
    if( comma )
    {
      if( method )
        PRINT_INFO("%s", sep_string );
      else
        ret_str += sep_string;
      if( fp )
        fprintf( fp, "%s", sep_string );
      curr_len += sep_len;
    }

    if( begin==previous )
    {
      // a single number
      prev_len = int_len(previous);

      if( curr_len+1+prev_len+sep_len > max_len )
      {
        if( method )
        {
          PRINT_INFO( "\n" );
          PRINT_INFO( "%s%d", tab, previous );
        }
        else
        {
          sprintf( temp, "\n%s%d", tab, previous );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, "\n%s%d", tab, previous );
        curr_len = tab_len + prev_len;
      }
      else
      {
        if( comma ) // Don't print space before first item
        {
          if( method )
            PRINT_INFO( " " );
          else
            ret_str += " ";
          if( fp )
            fprintf( fp, " " );
          curr_len++;
        }

        if( method )
          PRINT_INFO( "%d", previous );
        else
        {
          sprintf( temp, "%d", previous );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, "%d", previous );
        curr_len = curr_len + prev_len;
      }
    }
    else if( previous==begin+1 )
    {
      // a range, but only 2 consecutive numbers
      prev_len = int_len(previous);
      beg_len = int_len(begin);

      // Print 1st
      if( curr_len+1+beg_len+sep_len > max_len )
      {
        if( method )
        {
          PRINT_INFO( "\n" );
          PRINT_INFO( "%s%d%s", tab, begin, sep_string );
        }
        else
        {
          sprintf( temp, "\n%s%d%s", tab, begin, sep_string );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, "\n%s%d%s", tab, begin, sep_string );
        curr_len = tab_len + beg_len + sep_len;
      }
      else
      {
        if( comma ) // Don't print space before first item
        {
          if( method )
            PRINT_INFO( " " );
          else
            ret_str += " ";
          if( fp )
            fprintf( fp, " " );
          curr_len++;
        }

        if( method )
          PRINT_INFO( "%d%s", begin, sep_string );
        else
        {
          sprintf( temp, "%d%s", begin, sep_string );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, "%d%s", begin, sep_string );
        curr_len = curr_len + beg_len + sep_len;
      }

      // Print 2nd
      if( curr_len+1+prev_len+sep_len > max_len )
      {
        if( method )
        {
          PRINT_INFO( "\n" );
          PRINT_INFO( "%s%d", tab, previous );
        }
        else
        {
          sprintf( temp, "\n%s%d", tab, previous );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, "\n%s%d", tab, previous );
        curr_len = tab_len + prev_len;
      }
      else
      {
        if( method )
          PRINT_INFO( " %d", previous );
        else
        {
          sprintf( temp, " %d", previous );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, " %d", previous );
        curr_len = curr_len + 1+prev_len;
      }
    }
    else
    {
      // a range of 3 or more consecutive numbers
      prev_len = int_len(previous);
      beg_len = int_len(begin);

      if( curr_len+beg_len+prev_len+5+sep_len > max_len )
      {
        if( method )
        {
          PRINT_INFO( "\n" );
          PRINT_INFO( "%s%d to %d", tab, begin, previous );
        }
        else
        {
          sprintf( temp, "\n%s%d to %d", tab, begin, previous );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, "\n%s%d to %d", tab, begin, previous );
        curr_len = tab_len + beg_len+prev_len+4;
      }
      else
      {
        if( comma ) // Don't print space before first item
        {
          if( method )
            PRINT_INFO( " " );
          else
            ret_str += " ";
          if( fp )
            fprintf( fp, " " );
          curr_len++;
        }

        if( method )
          PRINT_INFO( "%d to %d", begin, previous );
        else
        {
          sprintf( temp, "%d to %d", begin, previous );
          ret_str += temp;
        }
        if( fp )
          fprintf( fp, "%d to %d", begin, previous );
        curr_len = curr_len + beg_len+4+prev_len;
      }
    }

    begin = current;
    previous = current;
    comma = 1;

  }

  //TODO: wrap poststring, if required
  if (post_string) {
    
    if( method )
      PRINT_INFO( "%s", post_string );
    else
      ret_str += post_string;
    if( fp )
      fprintf( fp, "%s", post_string );
  }
  
  delete [] tab;
}
// The main midsurface function
// lower_tol, upper_tol and preview are optional
CubitStatus AutoMidsurfaceTool::midsurface(
	DLIList<Body*> &body_list_in,
	DLIList<BodySM*> &body_list_out,
    DLIList<Body*> &old_bodies_midsurfaced,
    DLIList<double> &thickness_out,
	double lower_limit,
	double upper_limit,
    CubitBoolean delete_midsurfaced,
    CubitBoolean preview)
{
    if(lower_limit == CUBIT_DBL_MAX)// no limit set
        lower_limit = -CUBIT_DBL_MAX;
    double lower_tol = CUBIT_DBL_MAX;
    double upper_tol = CUBIT_DBL_MAX;
    const double auto_thickness_margin = 0.05; // if the user wants to automatically find the search
	                                          // thickness then this var give the search margin around the
	                                          // guess
    ProgressTool* prog_tool = 0;
    if(body_list_in.size()>5)
        prog_tool = AppUtil::instance()->progress_tool();

	// At lease one body must be provided
	if(body_list_in.size() < 1)
	{
		PRINT_ERROR( "No bodies given for midsurfacing\n" );
		return CUBIT_FAILURE;
	}

	// The surfaceOverlapTool is persistent so we need to save the 
	// max_gap and such to restore them at the end or if we error out
	// save current settings
	double max_gap_save = SurfaceOverlapTool::instance()->get_gap_max();
	double min_gap_save = SurfaceOverlapTool::instance()->get_gap_min();
	int normal_type = SurfaceOverlapTool::instance()->get_normal_type();
	CubitBoolean cubit_bool_save = SurfaceOverlapTool::instance()->get_check_within_bodies();
    CubitBoolean skip_facing_surfaces = SurfaceOverlapTool::instance()->get_skip_facing_surfaces();

    // we want to only find overlap within a body
    SurfaceOverlapTool::instance()->set_check_within_bodies(CUBIT_TRUE);
    // 1=any, 2=opposite, 3=same  - we want to find only the overlaps that normals
    // pointing in the opposite directions
    SurfaceOverlapTool::instance()->set_normal_type(2);
    // Don't pickup surfaces that face each other
    SurfaceOverlapTool::instance()->set_skip_facing_surfaces(CUBIT_TRUE);

    // list of bodies that fail to midsurface
    DLIList<Body*> failing_bodies; 

    GeometryModifyEngine* gme = 0;
    GeometryQueryEngine* gqe = 0;

	// loop over every body and try to create midsurface(s)
	int i = 0;
	CubitStatus return_status = CUBIT_FAILURE;

    if(prog_tool)
        prog_tool->start(0,body_list_in.size());

    for(i = body_list_in.size();i--;)
    {
        if(prog_tool)
            prog_tool->step();

		Body* cur_body = body_list_in[i];
		if(!cur_body)
			continue;

		BodySM* body_sm = cur_body->get_body_sm_ptr();
		if(!body_sm)
			continue;

        if(cur_body->is_sheet_body())
        {
            PRINT_INFO("Body %d is a sheet body.\n",cur_body->id());
            continue;
        }

		// Grab the geometrymodify and geometryquery engines to use later
		gqe = cur_body->get_geometry_query_engine();
		gme = GeometryModifyTool::instance()->get_engine(body_sm);

		if(!gqe || !gme)
			continue;

		// Here are the steps to finding/creating the midsurface
		// 1. If the user did not give a thickness range to search then
		//    make an educated guess at the proper thickness range. The assumption
		//    is that the midsurface is a square and the thickness is constant.
		//    The resulting equation is a third order polynomial that is solved using
		//    a few newton iterations. The initial thickness guess is Volume/Area
		// 2. Using the given search distances use the SurfaceOverlapTool to find
		//    surface pairs.
        // 3. If there is only one surface pair then use the existing midsurface commands
		// 4. Find if the surface pairs represent two surface patches
		// 5. If there are only two surface patches try to offset one of the patches
		// 6. (this step is commented out for now) - If 5 fails or there are more than
        //           two surface patches then try the following:
		//         - Use the manual midsurface creation function to create midsurfaces for each
		//           pair of surfaces.
		//         - Unite all of the created midsurfaces together
		//         - remove any surfaces that have a curve touching a surface pair 
		//         - Regularize the resulting body
		// 7. Done

		{
			PRINT_DEBUG_198("AUTOMATICALLY calculating search range\n");
			DLIList<RefVolume*> vol_list;
			cur_body->ref_volumes(vol_list);
			double total_vol = 0;
            double total_vol_bb = 0;
			for(int vol_cnt = 0; vol_cnt < vol_list.size(); vol_cnt++)
			{
                CubitVector cg;
                double temp_volume;
                vol_list[vol_cnt]->mass_properties(cg,temp_volume);
                CubitBox vol_bb = vol_list[vol_cnt]->bounding_box();
                total_vol += temp_volume;
                total_vol_bb += vol_bb.x_range()*vol_bb.y_range()*vol_bb.z_range();
            }

            if(total_vol<0 || total_vol > total_vol_bb)
            {
                PRINT_INFO("Could not midsurface Body %d - try healing the body.\n",cur_body->id());
                failing_bodies.append(cur_body);
                continue;
            }
                
			PRINT_DEBUG_198("Volume of %f\n",total_vol);

			DLIList<RefFace*> face_list;
			cur_body->ref_faces(face_list);
			double total_surf = 0;
			for(int surf_cnt = 0; surf_cnt < face_list.size(); surf_cnt++)
				total_surf += face_list[surf_cnt]->area();
			PRINT_DEBUG_198("Area of %f\n",total_surf);

			double t_g = total_vol/(total_surf/2.0);
            double initial_guess = t_g;
			PRINT_DEBUG_198("Initial guess of thickness %f\n",t_g);
			// use a newton solver to get a more accurate estimate the thickness of the volume
			for(int n_i = 0;n_i<100;n_i++)
			{
				double tol_newton = GEOMETRY_RESABS;
				double t_gn = t_g + tol_newton;
				double f_prime = ((2.0*total_vol + sqrt(total_vol*t_g*t_g*t_g)*4.0 - total_surf*t_g)
					-(2.0*total_vol + sqrt(total_vol*t_gn*t_gn*t_gn)*4.0 - total_surf*t_gn))/
					(t_g-t_gn);

				// avoid divide by zero
				if(fabs(f_prime)<tol_newton)
					break;

				double t_old = t_g;
				t_g = t_g - (2.0*total_vol + sqrt(total_vol*t_g*t_g*t_g)*4.0 - total_surf*t_g)/f_prime;
				
				PRINT_DEBUG_198("Guess %d Thickness %f\n",n_i,t_g);
				if(fabs(t_g-t_old)<tol_newton)
				{
					PRINT_DEBUG_198("Converged with thickness of %f in %d steps\n",t_g,n_i);
					break;
				}
                if(t_g<0.0)
                {
					PRINT_DEBUG_198("thickness less than zero setting back to initial guess\n");
                    t_g = fabs(initial_guess);
					break;
                }
			}
			upper_tol = t_g + t_g*auto_thickness_margin;
			lower_tol = t_g - t_g*auto_thickness_margin;
            upper_tol = upper_tol <= upper_limit?upper_tol:upper_limit;
            lower_tol = lower_tol >= lower_limit?lower_tol:lower_limit;

			PRINT_DEBUG_198("Guessing a thickness of %f to %f\n",lower_tol,upper_tol);
		}

		// set the lower and upper search distances
		SurfaceOverlapTool::instance()->set_gap_max(upper_tol);
		SurfaceOverlapTool::instance()->set_gap_min(lower_tol);

		DLIList<RefFace*> ref_face_list,list1,list2;
        DLIList<RefEntity*> faces_to_draw; 
        cur_body->ref_faces(ref_face_list);
        // find the surface pairs
        SurfaceOverlapTool::instance()->find_overlapping_surfaces(ref_face_list,list1,list2,faces_to_draw);

        int tweak_iters = 4;
        for(int tweak = 0;tweak<tweak_iters;tweak++)
        {
            // if we didn't find anything then the part may be long and selender so grow the search thickness
            if(list1.size()==0 && list2.size() == 0)
            {
                if(tweak == tweak_iters-1 && lower_limit != -CUBIT_DBL_MAX && upper_limit != CUBIT_DBL_MAX)
                {
                    // on the last try use the user defined limits
                    lower_tol = lower_limit;
                    upper_tol = upper_limit;
                }
                else
                {
                    lower_tol = (upper_tol + lower_tol)/2.0;
                    upper_tol += lower_tol*auto_thickness_margin*2;
                    upper_tol = upper_tol <= upper_limit?upper_tol:upper_limit;
                    lower_tol = lower_tol >= lower_limit?lower_tol:lower_limit;
                }

                PRINT_DEBUG_198("Guessing again with thickness of %f to %f\n",lower_tol,upper_tol);
                SurfaceOverlapTool::instance()->set_gap_max(upper_tol);
                SurfaceOverlapTool::instance()->set_gap_min(lower_tol);
                SurfaceOverlapTool::instance()->find_overlapping_surfaces(ref_face_list,list1,list2,faces_to_draw);
            }

            DLIList<RefFace*> check_list;
            check_list += list1;
            check_list += list2;

            if(check_list.size() == 0 )
                continue;

            // make sure the pairs will match the solid within 10% or so
            if(!check_surf_pairs(lower_tol,upper_tol,check_list,cur_body))
            {
                list1.clean_out();
                list2.clean_out();
                continue;
            }
            break;
        }

        if(list1.size() != list2.size())
        {
            PRINT_INFO("Could not find workable surface pairs for Body %d - try using the Sheet Offset command. \n",cur_body->id());
            failing_bodies.append(cur_body);
            continue;
        }
		else if(list1.size() == 0 || list2.size() == 0)
		{
				PRINT_INFO("No surface pairs found for Body %d - try changing the search range\n",cur_body->id());
			failing_bodies.append(cur_body);
			continue;
		}

		// get the first pair and see if there are only two patches
		DLIList<RefFace*> red_faces;
		red_faces.append(list1[0]);
		DLIList<RefFace*> yellow_faces;
		yellow_faces.append(list2[0]);
		DLIList<RefFace*> paired_faces;
		paired_faces += list1;
		paired_faces += list2;
		paired_faces.uniquify_unordered();

		// red surfaces
		while(1)
		{
			int start_cnt = red_faces.size();
			DLIList<RefEdge*> red_edges;
			int j = 0;
			for(j =0;j<red_faces.size();j++)
				red_faces[j]->ref_edges(red_edges);
			red_edges.uniquify_unordered();
			for(j =0;j<red_edges.size();j++)
				red_edges[j]->ref_faces(red_faces);
			red_faces.uniquify_unordered();
			red_faces.intersect_unordered(paired_faces);
			if(start_cnt == red_faces.size())
				break;
		}

		// yellow surfaces
		while(1)
		{
			int start_cnt = yellow_faces.size();
			DLIList<RefEdge*> yellow_edges;
			int j = 0;
			for(j =0;j<yellow_faces.size();j++)
				yellow_faces[j]->ref_edges(yellow_edges);
			yellow_edges.uniquify_unordered();
			for(j =0;j<yellow_edges.size();j++)
				yellow_edges[j]->ref_faces(yellow_faces);
			yellow_faces.uniquify_unordered();
			yellow_faces.intersect_unordered(paired_faces);
			if(start_cnt == yellow_faces.size())
				break;
		}

        DLIList<BodySM*> results;
        bool midsurface_done = false;

        if(DEBUG_FLAG(198))
        {
            int j = 0;
            PRINT_INFO("Trying surface offset to create the mid_surface\n");
            PRINT_INFO("Red surface ");
            for(j = 0;j < red_faces.size();j++)
            {
                GfxDebug::draw_ref_face(red_faces[j],CUBIT_RED);
                PRINT_INFO("%d ",red_faces[j]->id());
            }

            PRINT_INFO("\nYellow surface ");
            for(j = 0;j < yellow_faces.size();j++)
            {
                GfxDebug::draw_ref_face(yellow_faces[j],CUBIT_YELLOW);
                PRINT_INFO("%d ",yellow_faces[j]->id());
            }

            PRINT_INFO("\n");
        }

        // first check to see if we can use the simple midsurface functions
        if(red_faces.size() == 1 && yellow_faces.size() == 1 &&
            paired_faces.size() == red_faces.size() + yellow_faces.size()) 
        {
            RefFace* face_1 = red_faces[0];
            RefFace* face_2 = yellow_faces[0];
            midsurface_done = false;

            if(face_1->geometry_type() == face_2->geometry_type())
            {
                Surface* surf_1 = face_1->get_surface_ptr();
                Surface* surf_2 = face_2->get_surface_ptr();
                BodySM* result_body;
                // grab the distance between surfaces
                CubitVector temp_vec0;
                CubitVector temp_vec1;
                double temp_dist = 0;
                gqe->entity_entity_distance(
                    face_1->get_surface_ptr(),
                    face_2->get_surface_ptr(),
                    temp_vec0,temp_vec1,temp_dist);

                switch(face_1->geometry_type())
                {
                case CONE_SURFACE_TYPE:
                    if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
                    {
                        midsurface_done = true;
                        results.append(result_body);
                        thickness_out.append(fabs(temp_dist));
                    }
                    break;
                case PLANE_SURFACE_TYPE:
                    if(get_planar_mid_surface(face_1,face_2,body_sm,result_body,gme) == CUBIT_SUCCESS)
                    {
                        midsurface_done = true;
                        results.append(result_body);
                        thickness_out.append(fabs(temp_dist));
                    }
                    break;
                case SPHERE_SURFACE_TYPE:
                    if(gme->get_spheric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
                    {
                        midsurface_done = true;
                        results.append(result_body);
                        thickness_out.append(fabs(temp_dist));
                    }
                    break;
                case TORUS_SURFACE_TYPE:
                    if(gme->get_toric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
                    {
                        midsurface_done = true;
                        results.append(result_body);
                        thickness_out.append(fabs(temp_dist));
                    }
                    break;
                case CYLINDER_SURFACE_TYPE:
                    if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
                    {
                        midsurface_done = true;
                        results.append(result_body);
                        thickness_out.append(fabs(temp_dist));
                    }
                    break;
                default:
                    break;
                }
            }
        }

		if(!midsurface_done &&
            paired_faces.size() == red_faces.size() + yellow_faces.size()) // just do the offset
		{
			int j = 0;
            DLIList<double> offset_distances;
            for(j = 0;j<list1.size();j++)
            {
                CubitVector temp_vec0;
                CubitVector temp_vec1;
				double temp_dist = 0;
				if(!gqe->entity_entity_distance(
					list1[j]->get_surface_ptr(),
					list2[j]->get_surface_ptr(),
					temp_vec0,temp_vec1,temp_dist))
				{
					break;
				}
				offset_distances.append(-temp_dist*.5);
			}

			DLIList<Surface*> red_surfs;
			for(j = 0;j<red_faces.size();j++)
				red_surfs.append(red_faces[j]->get_surface_ptr());

			DLIList<Surface*> yellow_surfs;
			for(j = 0;j<yellow_faces.size();j++)
				yellow_surfs.append(yellow_faces[j]->get_surface_ptr());

            // all of the surfaces are offset the same distance
			double offset_distance = offset_distances[0];
            bool old_error_flag = GET_ERROR_FLAG();
            SET_ERROR_FLAG(false); // don't throw any gme errors
			if( gme->create_offset_sheet(red_surfs,offset_distance,
				NULL,NULL,results))
            {
                midsurface_done = true;
                for(j = 0;j<results.size();j++) // for every body add a thickness
                    thickness_out.append(fabs(offset_distance*2.));
            }
            else if( gme->create_offset_sheet(yellow_surfs,offset_distance,
				NULL,NULL,results)) // try the other direction
            {
                midsurface_done = true;
                for(j = 0;j<results.size();j++) // for every body add a thickness
                    thickness_out.append(fabs(offset_distance*2.));
            }
            else
            {
                PRINT_INFO("Could not create midsurface for Body %d - try using the surface offset command\n",cur_body->id());
                failing_bodies.append(cur_body);
            }
            SET_ERROR_FLAG(old_error_flag); // turn errors back on
        }
        
        if(!midsurface_done && paired_faces.size() != red_faces.size() + yellow_faces.size())
        {
            PRINT_INFO("Could not find workable surface pairs for Body %d - try changing the search range or \n"
                "        using the Sheet Offset command.\n",cur_body->id());
        }

      /*if(!midsurface_done)
        {
			if(DEBUG_FLAG(198))
				PRINT_INFO("Trying the extend, unite, and trim method\n");

			// okay now remove duplicate pairs and unsupported pairs
			DLIList<Surface*> surf_list1;
			DLIList<Surface*> surf_list2;
			bool delete_and_exit = false;
			for(int j = 0;j<list1.size();j++)
			{
				RefFace* face_1 = list1[j];
				RefFace* face_2 = list2[j];

				if(DEBUG_FLAG(198))
				{
					PRINT_INFO("Red surface ");
					GfxDebug::draw_ref_face(face_1,CUBIT_RED);
					PRINT_INFO("%d ",face_1->id());

					PRINT_INFO("\nYellow surface ");
					GfxDebug::draw_ref_face(face_2,CUBIT_YELLOW);
					PRINT_INFO("%d ",face_2->id());

					PRINT_INFO("\n");
				}

				if(face_1->geometry_type() != 	face_2->geometry_type())
					continue;

				Surface* surf_1 = face_1->get_surface_ptr();
				surf_list1.append(surf_1);
				Surface* surf_2 = face_2->get_surface_ptr();
				surf_list2.append(surf_2);
				BodySM* result_body;
				switch(face_1->geometry_type())
				{
				case CONE_SURFACE_TYPE:
					if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
						results.append(result_body);
					else
					    delete_and_exit = true;
					break;
				case PLANE_SURFACE_TYPE:
					if(get_planar_mid_surface(face_1,face_2,body_sm,result_body,gme) == CUBIT_SUCCESS)
						results.append(result_body);
					else
					    delete_and_exit = true;
					break;
				case SPHERE_SURFACE_TYPE:
					if(gme->get_spheric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
						results.append(result_body);
					else
					    delete_and_exit = true;
					break;
				case TORUS_SURFACE_TYPE:
					if(gme->get_toric_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
						results.append(result_body);
					else
					    delete_and_exit = true;
					break;
				case CYLINDER_SURFACE_TYPE:
					if(gme->get_conic_mid_surface(surf_1,surf_2,body_sm,result_body) == CUBIT_SUCCESS)
						results.append(result_body);
					else
					    delete_and_exit = true;
					break;
				default:
					delete_and_exit = true;
					break;
				}

				if(delete_and_exit)
				{
					PRINT_WARNING("Failed to pair surface %d with surface %d\n",face_1->id(),face_2->id());
					break;
				}
			}

			if(delete_and_exit)
			{
				failing_bodies.append(cur_body);
    			gqe->delete_solid_model_entities(results);
				continue;
			}

			DLIList<BodySM*> unite_results;
			if(results.size()>1)
			{
				bool reg_result = GeometryModifyTool::instance()->boolean_regularize();
				GeometryModifyTool::instance()->boolean_regularize(true);
				if(gme->unite(results,unite_results)== CUBIT_SUCCESS)
				{
					// if the unite works just add them to the result list
					results = unite_results;
				}
				else
				{
					// clean up the created surfaces and move on to the next
					// body
					failing_bodies.append(cur_body);
					gqe->delete_solid_model_entities(results);
					GeometryModifyTool::instance()->boolean_regularize(reg_result);
					continue;
				}

				GeometryModifyTool::instance()->boolean_regularize(reg_result);
			}

			// trim the hanging surfaces 
			DLIList<Surface*> paired_surfs;
			paired_surfs += surf_list1;
			paired_surfs += surf_list2;

			DLIList<Curve*> all_curves;

			int k = 0;
			for(k = 0;k<results.size();k++)
				results[k]->curves(all_curves);

			all_curves.uniquify_unordered();

			DLIList<Surface*> remove_surfs;
			for(k = 0;k<all_curves.size();k++)
				for(int m = 0;m<paired_surfs.size();m++)
					if(curve_in_surface(all_curves[k],paired_surfs[m]))
						all_curves[k]->surfaces(remove_surfs);

			remove_surfs.uniquify_unordered();

			body_list_out += results;
			DLIList<BodySM*> tweak_results;
			if(gme->tweak_remove(remove_surfs,tweak_results,CUBIT_FALSE))
			{
				results = tweak_results;
			}
			else
			{
				// clean up the created surfaces and move on to the next
				// body
				failing_bodies.append(cur_body);
				gqe->delete_solid_model_entities(results);
				continue;
			}

			DLIList<BodySM*> regularize_results;
			// regularize the results
			for(k = 0;k < results.size();k++)
			{
				BodySM* new_body = 0;
				if(gme->regularize_body(results[k],new_body))
					regularize_results.append(new_body);
				else if(DEBUG_FLAG(198))
					PRINT_INFO("Regularize failure\n");
			}
            results = regularize_results;
        }*/

        if(!midsurface_done)
        {
           failing_bodies.append(cur_body);
           continue;
        }

        old_bodies_midsurfaced.append(cur_body);

        if(delete_midsurfaced && !preview)
            GeometryQueryTool::instance()->delete_Body(cur_body);

        return_status = CUBIT_SUCCESS;
        body_list_out += results;
    }

    if(prog_tool)
        prog_tool->end();

    PRINT_INFO("Successfully midsurface %d of %d bodies\n",body_list_out.size(),body_list_in.size());
    if(preview)
    {
        for(int k = 0;k<body_list_out.size();k++)
        {
            DLIList<Surface*> preview_surfaces;
            body_list_out[k]->surfaces(preview_surfaces);
            for(int p = 0;p<preview_surfaces.size();p++)
                GfxPreview::draw_surface_facets_shaded(preview_surfaces[p],CUBIT_BLUE);
        }
        GfxPreview::flush();
        if(gqe)
            gqe->delete_solid_model_entities(body_list_out);
        body_list_out.clean_out();
    }

	if(failing_bodies.size() > 0)
	{
        PRINT_INFO("\n");
		PRINT_INFO("Failed to midsurface Body ");
		for(i = 0;i<failing_bodies.size();i++)
			PRINT_INFO("%d ",failing_bodies[i]->id());
		PRINT_INFO("\n");
	}

	if(DEBUG_FLAG(198))
		GfxDebug::flush();

	SurfaceOverlapTool::instance()->set_check_within_bodies(cubit_bool_save);
	SurfaceOverlapTool::instance()->set_gap_max(max_gap_save);
	SurfaceOverlapTool::instance()->set_normal_type(normal_type);
	SurfaceOverlapTool::instance()->set_gap_min(min_gap_save);
    SurfaceOverlapTool::instance()->set_skip_facing_surfaces(skip_facing_surfaces);

	return return_status;
}