cgma
TDUniqueId.cpp
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include "TDUniqueId.hpp"
00003 #include "RandomMersenne.hpp"
00004 #include "DLIList.hpp"
00005 #include "ToolDataUser.hpp"
00006 #include "CubitAttribUser.hpp"
00007 #include "CubitAttrib.hpp"
00008 #include "CADefines.hpp"
00009 #include "RefEntity.hpp"
00010 #include "TopologyEntity.hpp"
00011 #include "CastTo.hpp"
00012 #include "GeometryModifyTool.hpp"
00013 #include "GeometryQueryTool.hpp"
00014 #include "GSaveOpen.hpp"
00015 #include "CAUniqueId.hpp"
00016 
00017 #include <stdio.h>
00018 #include <time.h>
00019 
00020 extern int init_genrand(unsigned long s);
00021 extern long genrand_int31(void);
00022 
00023 TDUIDList TDUniqueId::uniqueIdList;
00024 COPYUIDMap TDUniqueId::mapForCopying;
00025 
00026 int TDUniqueId::generate_unique_id()
00027 {
00028     int result;
00029 
00030 // initialize the random number generator, using time as a seed; do it here
00031 // instead of as a static variable of the class to add a little more randomness
00032 // to the seed (which uses the time)
00033     static RandomMersenne rng(time(NULL));
00034 
00035       // generate random no. and check for duplicate; keep generating until
00036       // we find a non-duplicate; initialize found to true so that we can
00037       // test for duplicates in the loop below
00038     bool found = false;
00039     TDUIDList::iterator found_value;
00040     do {
00041       result = (int)(rng.genrand_int31());
00042       found_value = uniqueIdList.lower_bound(result);
00043       if(found_value != uniqueIdList.end())
00044       {
00045         found = ((*found_value).first == result);
00046         if (found)
00047           DIAGNOSTIC("Duplicate UID found - very unusual!\n");
00048       }
00049     }
00050     while (found);
00051 
00052     return result;
00053 }
00054 
00055 
00056 TDUniqueId::TDUniqueId(ToolDataUser *owner, const int id)
00057 {
00058   ownerEntity = owner;
00059 
00060   uniqueId = id == 0 ? generate_unique_id() : id;
00061   TDUIDList::value_type this_pair(uniqueId, this);
00062   unique_id_list().insert(this_pair);
00063 
00064   ownerEntity->add_TD(this);
00065   
00066 
00067     // update the attribute if this is a CAU
00068   CubitAttribUser *cau = CAST_TO(owner, CubitAttribUser);
00069   if (cau) {
00070     CubitAttrib *attrib = cau->get_cubit_attrib(CA_UNIQUE_ID);
00071     attrib->has_updated(CUBIT_FALSE);
00072     attrib->update();
00073   }
00074 }
00075 
00076 int TDUniqueId::is_unique_id(const ToolData* td)
00077 {
00078   return (CAST_TO(const_cast<ToolData*>(td), TDUniqueId) != NULL);
00079 }
00080 
00081 TDUniqueId::~TDUniqueId()
00082 {
00083     // remove this from the list
00084     //- With multimaps, keys do not have to be unique.  With the erase(Key) function,
00085     //- the multimap code will remove all entries with that key from the multimap.  
00086     //- The erase(iterator) function only removes the information at that iteration.
00087     //- Here, we search for the proper entry if there is more than one entry for a 
00088     //- particular key.  Increment the iterator and compare the element to 'this'.  If 
00089     //- it is a match, erase it by iterator.  This will leave the other entry with
00090     //- the similar key in the list, which is necessary for save/restore, and remove the 
00091     //- deactivated geometry due to the merge.
00092 
00093   std::pair<TDUIDList::iterator, TDUIDList::iterator>
00094     bounds_pair = unique_id_list().equal_range(uniqueId);
00095 
00096   TDUIDList::iterator it;
00097   for(it = bounds_pair.first; it != bounds_pair.second; ++it)
00098   {
00099     if(it->second == this)
00100     {
00101       unique_id_list().erase( it );
00102       break;
00103     }
00104   }
00105 }
00106     
00107 int TDUniqueId::get_unique_id(ToolDataUser *owner,
00108                               const CubitBoolean create_new)
00109 {
00110   assert(owner != 0);
00111   TDUniqueId *uid = (TDUniqueId *) owner->get_TD(&TDUniqueId::is_unique_id);
00112   if (!uid && create_new == CUBIT_TRUE) {
00113     uid = new TDUniqueId(owner);
00114   }
00115 
00116   return (uid ? uid->unique_id() : 0);
00117 }
00118 
00119 int TDUniqueId::find_td_unique_id(const int temp_id,
00120                                   DLIList<ToolDataUser*> &td_list,
00121                                   const RefEntity *related_entity)
00122 {
00123   td_list.clean_out();
00124 
00125   int unique_id = temp_id;
00126 
00127   //if we are not doing an undo and importing and merging within a file...
00128   if( !GSaveOpen::performingUndo && 
00129        GeometryQueryTool::importingSolidModel &&
00130       !GeometryQueryTool::mergeGloballyOnImport)
00131   {
00132     //see if the old id maps to a new id...if so, use the new id
00133     UIDMap old_uid_to_new_uid_map = CAUniqueId::get_old_to_new_uid_map();
00134     
00135     UIDMap::iterator iter;
00136     iter = old_uid_to_new_uid_map.find( unique_id );
00137     
00138     if( iter != old_uid_to_new_uid_map.end() )
00139       unique_id = (*iter).second;
00140   }
00141   
00142   std::pair<TDUIDList::iterator, TDUIDList::iterator> 
00143     bounds_pair = unique_id_list().equal_range(unique_id);
00144 
00145   TDUIDList::iterator
00146     it = bounds_pair.first, upper = bounds_pair.second;
00147  
00148   if(it == unique_id_list().end())
00149     return 0;
00150 
00151   if ((*it).first == unique_id ) {
00152       // the lower bound key is equal to unique_id, so this id is in the list
00153 
00154       // look for duplicate id's, return one that's directly related
00155       // get all td's with that id
00156     for (; it != upper; it++) 
00157     {
00158       bool related = true;
00159       ToolDataUser *temp_tdu = (*it).second->owner_entity();
00160       if (NULL != related_entity) {
00161         TopologyEntity *topo_ent = CAST_TO(temp_tdu, TopologyEntity);
00162         RefEntity* temp_entity = const_cast<RefEntity*>(related_entity);
00163         if (!topo_ent ||
00164             !topo_ent->is_directly_related(CAST_TO(temp_entity, TopologyEntity))) 
00165           related = false;
00166       }
00167       if (related) td_list.append(temp_tdu);
00168     }
00169   }
00170 
00171   return td_list.size();
00172 }
00173 
00174 ToolDataUser *TDUniqueId::find_td_unique_id(const int temp_id,
00175                                             const RefEntity *related_entity)
00176 {
00177   //ToolDataUser *tdu = NULL;
00178   DLIList<ToolDataUser*> td_list;
00179   find_td_unique_id(temp_id, td_list, related_entity);
00180   if (0 == td_list.size()) return NULL;
00181   else {
00182     td_list.reset();
00183     return td_list.get();
00184   }
00185 }
00186 
00187 int TDUniqueId::get_unique_id_for_copy( int original_id )
00188 {
00189   //check in the map if the original is already there
00190   //if so, get the corresponding id in the map (this is the new 
00191   //unique id on the copy)
00192   COPYUIDMap::iterator iter;
00193   iter = mapForCopying.find( original_id );
00194   if( iter != mapForCopying.end() ) 
00195     return (*iter).second;
00196    
00197   //else, a) generate another unique id b) put the original id in the map with
00198   //the new id directly across from it 
00199   int new_uid = generate_unique_id();
00200   COPYUIDMap::value_type tmp_pair( original_id, new_uid );
00201   mapForCopying.insert( tmp_pair );
00202   return new_uid;
00203 }
00204           
00205   
00206 void TDUniqueId::clear_copy_map()
00207 {
00208   //remove TDs off of entities
00209   COPYUIDMap::iterator iter = mapForCopying.begin();
00210   for(; iter != mapForCopying.end(); iter++ )
00211   {
00212     DLIList<ToolDataUser*> tool_data_users;
00213     int num_tool_datas = find_td_unique_id( (*iter).second, tool_data_users );
00214     
00215     for( ; num_tool_datas--; ) 
00216     {
00217       ToolDataUser *td_user = tool_data_users.get_and_step();
00218 
00219       //make sure the pointer isn't null
00220       ToolData *tool_data = NULL;
00221       if(td_user)
00222         tool_data = td_user->remove_TD(TDUniqueId::is_unique_id);
00223       
00224       //delete the TDUniqueId as well
00225       if( tool_data )
00226         delete tool_data;
00227 
00228       td_user = find_td_unique_id( (*iter).second );
00229     } 
00230   } 
00231 
00232   //clear out the map 
00233   if (mapForCopying.empty()) return;
00234     mapForCopying.clear();
00235 
00236 }
00237  
00238 int TDUniqueId::unique_id()
00239 {
00240   //if we're doing a copy, don't use the Unique id on the original.
00241   //generate another one
00242   if( GeometryModifyTool::instance()->get_copy_entity() )
00243   {
00244     int unique_id_for_copy = get_unique_id_for_copy( uniqueId );
00245     return unique_id_for_copy;
00246   }
00247   else 
00248     return uniqueId;
00249 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines