cgma
RemoveBlends.cpp
Go to the documentation of this file.
00001 #include "RemoveBlends.hpp"
00002 #include "CubitUtil.hpp"
00003 //#include "Model.hpp"
00004 #include "GeometryQueryTool.hpp"
00005 
00006 //#include "SVDrawTool.hpp"
00007 #include "GMem.hpp"
00008 #include "GfxDebug.hpp"
00009 
00010 #include "VirtualQueryEngine.hpp"
00011 #include "PartitionEngine.hpp"
00012 
00013 
00014 #include "CompositeTool.hpp"
00015 #include "PartitionTool.hpp"
00016 #include "PartSurfFacetTool.hpp"
00017 
00018 #include "RefFace.hpp"
00019 #include "RefEdge.hpp"
00020 #include "RefVertex.hpp"
00021 
00022 #include "CompositeLump.hpp"
00023 #include "PartitionCurve.hpp"
00024 #include "SubSurface.hpp"
00025 #include "SplitSurfaceTool.hpp"
00026 
00027 namespace RemoveBlends
00028 {
00029 CubitStatus remove_blend(RefFace* ref_face,
00030                                           DLIList<CubitVector>& locations,
00031                                           DLIList<RefFace*>& composite_faces)
00032 {
00033    CubitStatus result = CUBIT_SUCCESS;
00034    int i;
00035 
00036    locations.reset();
00037    RefFace* the_face = ref_face;
00038    if (the_face && VirtualQueryEngine::is_virtual(the_face))
00039    {
00040       PRINT_WARNING ("Can not collapse a virtual surface.\n");
00041       return CUBIT_FAILURE;
00042    }
00043 
00044    // Find the curve to split along.
00045    SplitSurfaceTool                sst;
00046    DLIList<DLIList<CubitVector*>*> vec_lists;
00047    DLIList<Curve*>                 curve_list;
00048 
00049    DLIList<CubitVector*> *vec_list = new DLIList<CubitVector*>;
00050 
00051    vec_list->append( new CubitVector( locations.get_and_step() ) );
00052    vec_list->append( new CubitVector( locations.get_and_step() ) );
00053 
00054    vec_lists.append( vec_list );
00055 
00056    sst.calculate_split_curves(the_face, vec_lists, curve_list);
00057 
00058    //int num_segs = 2; 
00059    //double fraction =.5;
00060    //double distance = -1.;
00061    //RefEdge* from_curve_ptr = 0;
00062    //DLIList<RefVertex*> corner_vertex_list;
00063    //DLIList<RefVertex*> through_vertex_list;
00064    //RefEdge *curve_dir_ptr = 0;
00065    //CubitBoolean preview_flg = false;
00066    //CubitBoolean create_ref_edges_flg = false;
00067    //CubitBoolean just_curves_flg = false;
00068    //DLIList<DLIList<Curve*>*> curve_lists_list; 
00069 
00070 //   sst.calculate_split_curves(ref_face_list, num_segs, fraction, distance, 
00071 //                          from_curve_ptr, corner_vertex_list, through_vertex_list,
00072 //                          curve_dir_ptr,
00073 //                          preview_flg, create_ref_edges_flg, just_curves_flg,
00074 //                          curve_lists_list ); 
00075 
00076    //partition the_face
00077    DLIList<RefEdge*> new_edges;
00078    DLIList<RefFace*> result_faces;
00079    result = PartitionTool::instance()->
00080           partition_face_by_curves( the_face, curve_list, result_faces, CUBIT_TRUE, &new_edges );
00081    // clean up curves
00082    while (curve_list.size())
00083    {
00084      Curve* curve = curve_list.pop();
00085      if (curve)
00086      {
00087        GeometryQueryEngine* gqe = curve->get_geometry_query_engine();
00088        gqe->delete_solid_model_entities(curve);
00089      }
00090    }
00091    if( result == CUBIT_FAILURE )
00092    {
00093       PRINT_ERROR("Failed to partition surface %d into 2 distinct pieces\n", the_face->id());
00094       return result;
00095    }
00096 
00097    // We MUST clean up an ambiguous partition.
00098    if (new_edges.size() > 1)
00099    {
00100       PRINT_ERROR("Attempted to partition surface %d more than 2 parts,\n"
00101                     "Ambiguous surface collapse. Collapse failed.\n",
00102                     the_face->id());
00103       DLIList<RefFace*> orig_faces;
00104       PartitionTool::instance()->unpartitionAll(result_faces, orig_faces);
00105       
00106       DLIList<RefEdge*> edges, edge_results;
00107       edges.clean_out();
00108       // We started out with one face, we should the same face back
00109       assert( the_face == orig_faces.next(0) );
00110       the_face->ref_edges( edges );
00111 
00112       // Do a quick sort to find the PartitionCurves
00113       for ( i = edges.size(); i--; ) 
00114       {
00115         if ( !dynamic_cast<PartitionCurve*>(edges.step_and_get()->get_curve_ptr()))
00116           edges.change_to(0);
00117       }
00118       edges.remove_all_with_value(0);
00119 
00120       // Now remove the partitioned edges
00121       // TODO: what if we are collapsing with an adjacent partitioned surface.
00122       // What happens to the partitioned edges?
00123       if ( edges.size() )
00124         PartitionTool::instance()->unpartitionAll(edges, edge_results);
00125 
00126       return CUBIT_FAILURE;
00127    }
00128 
00129    if (result_faces.size() < 2)
00130    {
00131       PRINT_WARNING("Surface %d has been improperly partitioned,\n"
00132                     "Ambiguous surface collapse. Collapse failed.\n",
00133                     the_face->id());
00134       return result;
00135    }
00136  
00137    //if(new_face == the_face)
00138    //   new_face = GeometryQueryTool::instance()->get_last_ref_face ();   
00139 
00140    new_edges.clean_out();
00141    //Re-composite surfaces
00142    DLIList<RefFace*> composite_result_faces;
00143    DLIList<RefFace*> remaining_faces;
00144    DLIList<RefFace*> surf_list;
00145    DLIList<int> id_list;
00146    RefFace*  face_to_composite = NULL;
00147    RefFace*  temp_face = NULL;
00148    RefFace*  second_face = NULL;
00149    RefFace*  composite_face = NULL;
00150    int  num_common_edge1, num_common_edge2;
00151    int  size;
00152    int  composite_count = 0;
00153    while (0 < (composite_faces.size() + remaining_faces.size()))
00154    {
00155       if(composite_count == 2)
00156         break;
00157 
00158       size = composite_faces.size();
00159       if( size > 0)
00160       {
00161         composite_faces.reset();
00162         face_to_composite = composite_faces.get();
00163         composite_faces.remove(face_to_composite);
00164       }
00165 
00166       else
00167       {
00168         remaining_faces.reset();
00169         face_to_composite = remaining_faces.get();
00170         remaining_faces.remove(face_to_composite);
00171       }
00172       
00173       if (NULL != second_face)
00174       {
00175          num_common_edge1 = second_face->common_ref_edges(face_to_composite,
00176                                                        new_edges); 
00177          new_edges.clean_out();
00178          if (num_common_edge1 == 0)
00179            continue;
00180          
00181          if (NULL == composite_face)
00182            num_common_edge2 = 0;
00183          else
00184            num_common_edge2 = composite_face->
00185                    common_ref_edges(face_to_composite, new_edges);
00186          new_edges.clean_out();
00187       }
00188 
00189       else 
00190       {
00191          if (NULL == result_faces[0])
00192            num_common_edge1 = 0;
00193          else 
00194          {
00195             num_common_edge1 = result_faces[0]->common_ref_edges(face_to_composite, 
00196                                                        new_edges);  
00197             new_edges.clean_out();
00198          }
00199 
00200          if(NULL == result_faces[1])
00201             num_common_edge2 = 0;
00202          else
00203          {
00204             num_common_edge2 = result_faces[1]->common_ref_edges(face_to_composite,
00205                                                           new_edges);
00206             new_edges.clean_out();
00207          }
00208       }
00209 
00210       if (num_common_edge1 == 0 && num_common_edge2 == 0)
00211          continue;
00212 
00213       else if(num_common_edge1 == 0 || num_common_edge2 == 0 || size == 0)
00214       {  
00215          surf_list.clean_out();
00216          if (NULL != second_face)
00217             surf_list.append(second_face);
00218 
00219          else if (num_common_edge2 == 0 || size == 0)        
00220          {
00221             temp_face = result_faces[0];
00222             second_face = result_faces[1];
00223             surf_list.append(temp_face);
00224          }
00225 
00226          else
00227          {
00228             temp_face = result_faces[1];
00229             second_face = result_faces[0];
00230             surf_list.append(temp_face);
00231          }
00232          surf_list.append(face_to_composite);
00233      
00234          // composite the surfaces together
00235          CompositeTool::instance()->composite(surf_list, composite_result_faces);
00236          composite_count++;
00237 
00238          if( composite_result_faces.size() > 0 )
00239          {
00240             DLIList<RefEdge*> surface_edges, new_edge_list;
00241             remaining_faces.clean_out();
00242             for(  i = 0; i < composite_result_faces.size(); i++)
00243             {
00244                // now composite together the edges of the new surface
00245                surface_edges.clean_out();
00246                composite_result_faces.get_and_step()->ref_edges( surface_edges );
00247                new_edge_list.clean_out();
00248                CompositeTool::instance()->composite( surface_edges, new_edge_list);
00249 
00250                // keep the lists coherent
00251                composite_face = composite_result_faces.pop();
00252                composite_faces.remove(composite_face);
00253                id_list.append( composite_face->id() );
00254             }
00255          }
00256                                                            
00257          else
00258             PRINT_ERROR("Composite surface %d and surface %d failed.\n",
00259                 temp_face->id(), face_to_composite->id());
00260       }
00261 
00262       else 
00263          remaining_faces.append(face_to_composite);      
00264    }
00265    if (id_list.size() > 0)
00266       CubitUtil::list_entity_ids("Created composite surfaces ", id_list );
00267    return result;
00268 }
00269 
00270 CubitStatus remove_blends(DLIList<RefFace*>& ref_face_list,
00271                                         int num_segs, double fraction, double distance,
00272                                         RefEdge* from_curve_ptr,
00273                                         DLIList<RefVertex*>& corner_vertex_list,
00274                                         DLIList<RefVertex*>& through_vertex_list,
00275                                         RefEdge *curve_dir_ptr,
00276                                         CubitBoolean preview_flg,
00277                                         DLIList<CubitVector*>& locations,
00278                                         DLIList<RefFace*>& composite_faces)
00279 {
00280    CubitStatus result = CUBIT_SUCCESS;
00281    int i;
00282 
00283    if (ref_face_list.size() <= 1)
00284    {
00285       PRINT_WARNING ("Must specify a chain of surfaces.\n");
00286       return CUBIT_FAILURE;
00287    }
00288    locations.reset();
00289 
00290    // check and make sure that we aren't splitting virtual surfaces (yet)
00291    for (i = 0; i < ref_face_list.size(); i++)
00292    {
00293      RefFace* the_face = ref_face_list.get_and_step();
00294      if (the_face && VirtualQueryEngine::is_virtual(the_face))
00295      {
00296         PRINT_WARNING ("Can not collapse a virtual surface.\n");
00297         return CUBIT_FAILURE;
00298      }
00299    }
00300 
00301    // Find the curve to split along.
00302    SplitSurfaceTool                sst;
00303    DLIList<DLIList<CubitVector*>*> vec_lists;
00304    DLIList<Curve*>*                curve_list;
00305    DLIList<DLIList<Curve*>*> curve_lists_list; 
00306 
00307    DLIList<CubitVector*> *vec_list = new DLIList<CubitVector*>;
00308 
00309    vec_list->append( new CubitVector( *locations.get_and_step() ) );
00310    vec_list->append( new CubitVector( *locations.get_and_step() ) );
00311 
00312    vec_lists.append( vec_list );
00313 
00314    CubitBoolean create_ref_edges_flg = false;
00315    CubitBoolean just_curves_flg = false;
00316 
00317    sst.calculate_split_curves(ref_face_list, num_segs, fraction, distance, 
00318                           from_curve_ptr, corner_vertex_list, through_vertex_list,
00319                           curve_dir_ptr,
00320                           preview_flg, create_ref_edges_flg, just_curves_flg,
00321                           curve_lists_list ); 
00322 
00323    //partition the_face
00324    DLIList<RefEdge*> new_edges;
00325    DLIList<RefFace*> result_faces;
00326    RefFace* the_face;
00327    DLIList<int> id_list;
00328 
00329    for (i = 0; i < ref_face_list.size(); i++)
00330    {
00331      // get the face and the curves that split this face
00332      the_face = ref_face_list.get_and_step();
00333      curve_list = curve_lists_list.get_and_step();
00334 
00335      result = PartitionTool::instance()->
00336             partition_face_by_curves( the_face, *curve_list, result_faces, CUBIT_FALSE, &new_edges );
00337      if( result == CUBIT_FAILURE )
00338         return result;
00339 
00340      if (new_edges.size() > 1)
00341      {
00342         PRINT_WARNING("Surface %d has been partitioned into more than 2 parts,\n"
00343                       "Ambiguous surface collapse.\n",
00344                       the_face->id());
00345         return result;
00346      }
00347  
00348      new_edges.clean_out();
00349      //Re-composite surfaces
00350      DLIList<RefFace*> composite_result_faces;
00351      DLIList<RefFace*> remaining_faces;
00352      DLIList<RefFace*> surf_list;
00353      RefFace*  face_to_composite = NULL;
00354      RefFace*  temp_face = NULL;
00355      RefFace*  second_face = NULL;
00356      RefFace*  composite_face = NULL;
00357      int  num_common_edge1, num_common_edge2;
00358      int  size;
00359      int  composite_count = 0;
00360      while (0 < (composite_faces.size() + remaining_faces.size()))
00361      {
00362         if(composite_count == 2)
00363           break;
00364 
00365         size = composite_faces.size();
00366         if( size > 0)
00367         {
00368           composite_faces.reset();
00369           face_to_composite = composite_faces.get();
00370           composite_faces.remove(face_to_composite);
00371         }
00372         else
00373         {
00374           remaining_faces.reset();
00375           face_to_composite = remaining_faces.get();
00376           remaining_faces.remove(face_to_composite);
00377         }
00378         
00379         if (NULL != second_face)
00380         {
00381            num_common_edge1 = second_face->common_ref_edges(face_to_composite,
00382                                                          new_edges); 
00383            new_edges.clean_out();
00384            if (num_common_edge1 == 0)
00385              continue;
00386            
00387            if (NULL == composite_face)
00388              num_common_edge2 = 0;
00389            else
00390              num_common_edge2 = composite_face->
00391                      common_ref_edges(face_to_composite, new_edges);
00392            new_edges.clean_out();
00393         }
00394         else 
00395         {
00396            if (NULL == result_faces[0])
00397              num_common_edge1 = 0;
00398            else 
00399            {
00400               num_common_edge1 = result_faces[0]->common_ref_edges(face_to_composite, 
00401                                                          new_edges);  
00402               new_edges.clean_out();
00403            }
00404 
00405            if(NULL == result_faces[1])
00406               num_common_edge2 = 0;
00407            else
00408            {
00409               num_common_edge2 = result_faces[1]->common_ref_edges(face_to_composite,
00410                                                             new_edges);
00411               new_edges.clean_out();
00412            }
00413         }
00414 
00415         if (num_common_edge1 == 0 && num_common_edge2 == 0)
00416            continue;
00417 
00418         else if(num_common_edge1 == 0 || num_common_edge2 == 0 || size == 0)
00419         {  
00420            surf_list.clean_out();
00421            if (NULL != second_face)
00422               surf_list.append(second_face);
00423 
00424            else if (num_common_edge2 == 0 || size == 0)        
00425            {
00426               temp_face = result_faces[0];
00427               second_face = result_faces[1];
00428               surf_list.append(temp_face);
00429            }
00430 
00431            else
00432            {
00433               temp_face = result_faces[1];
00434               second_face = result_faces[0];
00435               surf_list.append(temp_face);
00436            }
00437            surf_list.append(face_to_composite);
00438        
00439            // composite the surfaces together
00440            CompositeTool::instance()->composite(surf_list, composite_result_faces);
00441            composite_count++;
00442 
00443            if( composite_result_faces.size() > 0 )
00444            {
00445               DLIList<RefEdge*> surface_edges, new_edge_list;
00446               remaining_faces.clean_out();
00447               for(  i = 0; i < composite_result_faces.size(); i++)
00448               {
00449                  // now composite together the edges of the new surface
00450                  surface_edges.clean_out();
00451                  composite_result_faces.get_and_step()->ref_edges( surface_edges );
00452                  new_edge_list.clean_out();
00453                  CompositeTool::instance()->composite( surface_edges, new_edge_list);
00454 
00455                  // keep the lists coherent
00456                  composite_face = composite_result_faces.pop();
00457                  composite_faces.remove(composite_face);
00458                  id_list.append( composite_face->id() );
00459               }
00460            }
00461            PRINT_ERROR("Composite surface %d and surface %d failed.\n",
00462                 temp_face->id(), face_to_composite->id());
00463        }
00464      }
00465    }
00466    if (id_list.size() > 0)
00467       CubitUtil::list_entity_ids("Created composite surfaces ", id_list );
00468    return result;
00469 }
00470 } // namespace RemoveBlends
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines