//------------------------------------------------------------------------- // 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; } }
//------------------------------------------------------------------------- // 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()); }
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; }
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) ); }
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 ); } }
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(); }
//============================================================================= //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(); }
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; } }
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; }
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); } }
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]); } } } } }
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; }
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 ); } }
//------------------------------------------------------------------------- // 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); } } } } }
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; }
// 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; }
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 ; } }
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; }