cgma
|
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 }