cgma
CAMergePartner.cpp
Go to the documentation of this file.
00001 //- Class:          CAMergePartner
00002 //- Owner:          Greg Nielson
00003 //- Description:    Cubit Attribute for merge partners.
00004 //- Checked By:
00005 //- Version:
00006 
00007 #include "CAMergePartner.hpp"
00008 #include "DLIList.hpp"
00009 #include "SDLCAMergePartnerList.hpp"
00010 #include "RefEntity.hpp"
00011 #include "RefFace.hpp"
00012 #include "RefEdge.hpp"
00013 #include "RefVertex.hpp"
00014 #include "TDCompare.hpp"
00015 #include "TDUniqueId.hpp"
00016 #include "MergeTool.hpp"
00017 #include "CastTo.hpp"
00018 #include "CubitAttribUser.hpp"
00019 #include "GeometryQueryTool.hpp"
00020 #include "RefVolume.hpp"
00021 #include "TopologyBridge.hpp"
00022 
00023 #include <stdlib.h>
00024 #include <time.h>
00025 
00026 // factory function
00027 CubitAttrib* CAMergePartner_creator(RefEntity* entity, const CubitSimpleAttrib &p_csa)
00028 {
00029   return new CAMergePartner(entity, p_csa);
00030 }
00031 
00032 CAMergePartner::CAMergePartner(RefEntity* new_attrib_owner,
00033                                const CubitSimpleAttrib &csa_ptr)
00034         : CubitAttrib(new_attrib_owner)
00035 {
00036   initialize();
00037 
00038   if(!csa_ptr.isEmpty())
00039   {
00040     int i_temp = csa_ptr.int_data_list()[0];
00041     mergeID = i_temp;
00042     if( csa_ptr.int_data_list().size() > 1 )
00043     {
00044       i_temp = csa_ptr.int_data_list()[1];
00045       switch( i_temp ) {
00046         case -1: bridge_sense_ = CUBIT_REVERSED; break;
00047         case  1: bridge_sense_ = CUBIT_FORWARD;  break;
00048         case  0: bridge_sense_ = CUBIT_UNKNOWN; break;
00049         default: bridge_sense_ = CUBIT_UNKNOWN; assert(0);
00050       }
00051     }
00052   }
00053 }
00054 
00055 CAMergePartner::~CAMergePartner() 
00056 {
00057     //
00058   mergeID = 0;
00059 }
00060 
00061 
00062 void CAMergePartner::initialize()
00063 {
00064   mergeID = -1;
00065   bridge_sense_ = CUBIT_UNKNOWN;
00066   isSurvivor = 0;
00067 }
00068 
00069 
00070 CubitStatus CAMergePartner::actuate()
00071 {
00072   hasActuated = CUBIT_TRUE;
00073   return CUBIT_SUCCESS;
00074   //We don't need to actuate this attribute here since the merging
00075   //happens in GeometryQueryTool::check_mergeable_refentity.
00076   
00077   /*
00078   if (hasActuated == CUBIT_TRUE) return CUBIT_SUCCESS;
00079   
00080   BasicTopologyEntity * bte_ptr = CAST_TO(attribOwnerEntity,BasicTopologyEntity); 
00081   if (bte_ptr == NULL || bte_ptr->deactivated() == CUBIT_TRUE)
00082     return CUBIT_FAILURE;
00083   
00084   DLIList<RefEntity*> merge_list;
00085   //merge_prepare(merge_list);
00086   merge_list.append_unique(attribOwnerEntity);
00087 
00088   CubitStatus result = CUBIT_SUCCESS;
00089 
00090   if (merge_list.size() > 1)
00091     result = (NULL == MergeTool::instance()->force_merge(merge_list))
00092             ? CUBIT_FAILURE : CUBIT_SUCCESS;
00093 
00094   if( result )
00095   {
00096     hasActuated = CUBIT_TRUE;
00097   }        
00098 
00099   return result; */
00100 }
00101 
00102 void CAMergePartner::merge_prepare(DLIList<RefEntity*> &merge_list)
00103 {
00104   DLIList<CubitAttrib*> my_ca_list;
00105   CAMergePartner *my_camp_ptr;
00106   RefEntity* re_ptr;
00107 
00108     // get all the merge partner attributes that are on my owner
00109   attribOwnerEntity->find_cubit_attrib_type(CA_MERGE_PARTNER, my_ca_list);
00110   merge_list.clean_out();
00111   DLIList<ToolDataUser*> td_list, temp_td_list;
00112   int i;
00113   for (i = my_ca_list.size(); i > 0; i--)
00114   {
00115     my_camp_ptr = CAST_TO(my_ca_list.get(),CAMergePartner);
00116     my_ca_list.step();
00117     td_list.clean_out();
00118       // get all the objects with this unique id (which is also the merge id)
00119     TDUniqueId::find_td_unique_id(my_camp_ptr->merge_id(), temp_td_list);
00120     td_list += temp_td_list;
00121   }
00122   
00123     // now put those entities into the merge_list
00124   for (i = td_list.size(); i > 0; i--) 
00125   {
00126     re_ptr = CAST_TO(td_list.get(), RefEntity);
00127     if (re_ptr) 
00128     {
00129       CubitAttrib *tmp_attrib = re_ptr->get_cubit_attrib( CA_MERGE_PARTNER, CUBIT_FALSE );
00130       if( tmp_attrib )
00131         merge_list.append(re_ptr);
00132     }
00133     td_list.step();
00134   }
00135   
00136     // Now get bridge sense for each entity in list.
00137     // Add this entity to list, too.
00138   merge_list.append( attribOwnerEntity );
00139   for( i = merge_list.size(); i--; )
00140   {
00141     RefEntity* ent = merge_list.get_and_step();
00142     TopologyEntity* te = dynamic_cast<TopologyEntity*>(ent);
00143     if( te->bridge_manager()->number_of_bridges() != 1 )
00144       continue;
00145     
00146     my_ca_list.clean_out();
00147     ent->find_cubit_attrib_type(CA_MERGE_PARTNER, my_ca_list);
00148     assert( my_ca_list.size() < 2);
00149     if( !my_ca_list.size() )
00150       continue;
00151     
00152     my_camp_ptr = dynamic_cast<CAMergePartner*>(my_ca_list.get());
00153     if( my_camp_ptr->bridge_sense() == CUBIT_UNKNOWN )
00154       continue;
00155   }  
00156   merge_list.pop(); // take attribOwnerEntity back off list
00157     
00158   return;
00159 }
00160   
00161 CubitStatus CAMergePartner::actuate_list(DLIList<RefEntity*> entity_list)
00162 {
00163 
00164     // given a list of ref entities (usually all entities of a given type),
00165     // actuate the camp's on those entities
00166   RefEntity *ref_ent, *keeper;
00167   DLIList<CubitAttrib*> ca_list;
00168   DLIList<TopologyBridge*> bridge_list(entity_list.size());
00169   SDLCAMergePartnerList sorted_camp_list;
00170   int i;
00171   for(i = entity_list.size(); i > 0; i--)
00172   {
00173     ref_ent = entity_list.get_and_step();
00174     ca_list.clean_out();
00175     ref_ent->find_cubit_attrib_type(CA_MERGE_PARTNER, ca_list);
00176     assert(ca_list.size() < 2); // There should only be one
00177                                 //  merge partner per entity
00178     if(ca_list.size() > 0)
00179     {
00180       CAMergePartner* attrib = dynamic_cast<CAMergePartner*>(ca_list.get());
00181       sorted_camp_list.append( attrib );
00182       TopologyEntity* te = dynamic_cast<TopologyEntity*>(ref_ent);
00183       TopologyBridge* bridge = te->bridge_manager()->topology_bridge();
00184       bridge_list.append(bridge);
00185     }
00186   }
00187   sorted_camp_list.sort();
00188   sorted_camp_list.reset();
00189 
00190   if (DEBUG_FLAG(90)) {
00191     for (i = sorted_camp_list.size(); i > 0; i--) {
00192       CAMergePartner *camp_ptr = sorted_camp_list.get_and_step();
00193       ref_ent = camp_ptr->attrib_owner();
00194       PRINT_DEBUG_90("%s %d, unique id = %d\n", ref_ent->class_name(),
00195                      ref_ent->id(), camp_ptr->merge_id());
00196     }
00197   }
00198   
00199     // now go through all the camp's for the entity list; peel off
00200     // camp's with the same id, and merge the associated entities together
00201   while (sorted_camp_list.size() > 0) 
00202   {
00203     DLIList<RefEntity*> refent_list;
00204     DLIList<CubitAttrib*> camp_list;
00205     keeper = NULL;
00206 
00207       // get the next list of entities with the same camp id
00208     sorted_camp_list.last();
00209     CAMergePartner *camp_ptr = sorted_camp_list.remove();
00210     sorted_camp_list.back();
00211     camp_list.append(camp_ptr);
00212     int current_id = camp_ptr->merge_id();
00213     while (sorted_camp_list.size() > 0 &&
00214            sorted_camp_list.get()->merge_id() == current_id) {
00215       camp_list.append(sorted_camp_list.remove());
00216       sorted_camp_list.back();
00217     }
00218     
00219     if (camp_list.size() == 1) continue;
00220     
00221     CubitBoolean has_actuated = camp_list.get()->has_actuated();
00222 
00223       // check the has actuated flag; if one is set, they all should be;
00224       // also, compile list of ref entities while we're at it
00225     for (current_id = camp_list.size(); current_id > 0; current_id--) {
00226       ref_ent = camp_list.get()->attrib_owner();
00227       refent_list.append(ref_ent);
00228       if (!keeper || ref_ent->id() < keeper->id()) keeper = ref_ent;
00229       assert(camp_list.get()->has_actuated() == has_actuated);
00230       camp_list.step();
00231     }
00232 
00233       // if they have already actuated, go on to next ones
00234     if (has_actuated == CUBIT_TRUE) continue;
00235 
00236       // otherwise merge
00237     if(refent_list.size() > 1)
00238       MergeTool::instance()->force_merge(refent_list);
00239 
00240         // remove the cubit attribute from the surviving parent
00241     keeper->remove_cubit_attrib(CA_MERGE_PARTNER);
00242 
00243   } // loop over existing camp's
00244   
00245   return CUBIT_SUCCESS;
00246 }
00247 
00248 CubitStatus CAMergePartner::update()
00249 {
00250   if (hasUpdated) return CUBIT_SUCCESS;
00251   
00252     // set the updated flag
00253   hasUpdated = CUBIT_TRUE;
00254   BasicTopologyEntity* bte_ptr = CAST_TO(attribOwnerEntity, BasicTopologyEntity);
00255 
00256   if( (bte_ptr == NULL) || (dynamic_cast<RefVolume*>(bte_ptr) != NULL))
00257   {
00258     delete_attrib(CUBIT_TRUE);
00259   }
00260   else if( (bte_ptr->bridge_manager()->number_of_bridges() == 1) &&
00261            (bte_ptr->bridge_manager()->topology_bridge()->bridge_sense() != CUBIT_REVERSED) )
00262   {
00263     delete_attrib(CUBIT_TRUE);
00264   }
00265   else
00266   {
00267       // get the merge id from the TDUniqueId for the owner entity
00268     mergeID = TDUniqueId::get_unique_id(attribOwnerEntity);
00269     bridge_sense_ = CUBIT_UNKNOWN;
00270     isSurvivor = 0;
00271   }
00272 
00273   return CUBIT_SUCCESS;
00274 }
00275 
00276 CubitSimpleAttrib CAMergePartner::cubit_simple_attrib()
00277 {
00278   std::vector<CubitString> cs_list;
00279   std::vector<double> d_list;
00280   std::vector<int> i_list;
00281 
00282   i_list.push_back(mergeID);
00283   cs_list.push_back(att_internal_name());
00284 
00285   return CubitSimpleAttrib(&cs_list, &d_list, &i_list);
00286 }
00287 
00288 void CAMergePartner::set_survivor( CubitSimpleAttrib& csa, int is_survivor )
00289 {
00290   //get the list we want to modify from the CSA
00291   std::vector<int>& data = csa.int_data_list();
00292   
00293   //change or append?
00294   if( data.size() >= 4 )
00295   {
00296     data[3] = is_survivor;
00297   }
00298   else 
00299   {
00300     assert( data.size() == 3 );
00301     data.push_back(is_survivor);
00302   }
00303 }
00304 
00305 void CAMergePartner::set_bridge_sense( CubitSimpleAttrib& csa, CubitSense sense )
00306 {
00307   //encode/decode sense as:
00308   // CUBIT_FORWARD :  1
00309   // CUBIT_REVERSE : -1
00310   // CUBIT_UNKNOWN :  0
00311   int i = 0;
00312   switch( sense ) { 
00313     case CUBIT_FORWARD  : i =  1; break;
00314     case CUBIT_REVERSED : i = -1; break;
00315     case CUBIT_UNKNOWN  : i =  0; break;
00316     default: assert(0);
00317   }
00318   
00319   //get the list we want to modify from the CSA
00320   std::vector<int>& data = csa.int_data_list();
00321   
00322   //change or append?
00323   if( data.size() >= 2 )
00324   {
00325     data[1] = i;
00326   }
00327   else 
00328   {
00329     assert( data.size() == 1 );
00330     data.push_back(i);
00331   }
00332 }
00333 CubitBoolean CAMergePartner::is_survivor( const CubitSimpleAttrib& csa )
00334 {
00335   const std::vector<int>& data = csa.int_data_list();
00336   if( data.size() >= 4)
00337   {
00338     int i = data[3];
00339     if( i == 1 )
00340       return true;
00341   }
00342   return false;
00343 }
00344 
00345 
00346 CubitSense CAMergePartner::get_bridge_sense( const CubitSimpleAttrib& csa )
00347 {
00348   const std::vector<int>& data = csa.int_data_list();
00349   if( data.size() >= 2)
00350   {
00351     int i = data[1];
00352     switch(i) {
00353       case  1: return CUBIT_FORWARD;
00354       case -1: return CUBIT_REVERSED;
00355       default: assert(0);  // if -DNDEBUG, fall through to unknown
00356       case  0: return CUBIT_UNKNOWN;
00357     }
00358   }
00359 
00360   return CUBIT_UNKNOWN;
00361 }
00362 
00363 void CAMergePartner::set_saved_id( CubitSimpleAttrib& csa, int id )
00364 {
00365    //get the list we want to modify from the CSA
00366   std::vector<int>& data = csa.int_data_list();
00367 
00368     // ID goes after bridge sense, so save bridge sense first
00369   if (data.size() == 1)
00370     set_bridge_sense( csa, CUBIT_UNKNOWN );
00371   
00372     // change?
00373   if (data.size() > 2 )
00374   {
00375     data[2] = id;
00376   }
00377     // set?
00378   else
00379   {
00380     assert(data.size() == 2);
00381     data.push_back(id);
00382   }
00383 }
00384 
00385 int CAMergePartner::get_saved_id( const CubitSimpleAttrib& csa )
00386 {
00387    //get the list we want to modify from the CSA
00388   const std::vector<int>& data = csa.int_data_list();
00389 
00390   if (data.size() < 3)
00391     return 0;
00392   
00393   return data[2];
00394 }
00395     
00396   
00397 
00398 void CAMergePartner::print() 
00399 {
00400   PRINT_INFO("Attribute MERGE_PARTNER, %s %d: mergeId = %d, sense = %d.\n",
00401              attribOwnerEntity->class_name(), attribOwnerEntity->id(),
00402              mergeID, bridge_sense_);
00403 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines