Branch data Line data Source code
1 : : #include <stdlib.h>
2 : : #include "TDUniqueId.hpp"
3 : : #include "RandomMersenne.hpp"
4 : : #include "DLIList.hpp"
5 : : #include "ToolDataUser.hpp"
6 : : #include "CubitAttribUser.hpp"
7 : : #include "CubitAttrib.hpp"
8 : : #include "CADefines.hpp"
9 : : #include "RefEntity.hpp"
10 : : #include "TopologyEntity.hpp"
11 : : #include "CastTo.hpp"
12 : : #include "GeometryModifyTool.hpp"
13 : : #include "GeometryQueryTool.hpp"
14 : : #include "GSaveOpen.hpp"
15 : : #include "CAUniqueId.hpp"
16 : :
17 : : #include <stdio.h>
18 : : #include <time.h>
19 : :
20 : : extern int init_genrand(unsigned long s);
21 : : extern long genrand_int31(void);
22 : :
23 : 1635 : TDUIDList TDUniqueId::uniqueIdList;
24 : 1635 : COPYUIDMap TDUniqueId::mapForCopying;
25 : :
26 : 954 : int TDUniqueId::generate_unique_id()
27 : : {
28 : : int result;
29 : :
30 : : // initialize the random number generator, using time as a seed; do it here
31 : : // instead of as a static variable of the class to add a little more randomness
32 : : // to the seed (which uses the time)
33 [ + + ][ + - ]: 954 : static RandomMersenne rng(time(NULL));
[ + - ][ # # ]
34 : :
35 : : // generate random no. and check for duplicate; keep generating until
36 : : // we find a non-duplicate; initialize found to true so that we can
37 : : // test for duplicates in the loop below
38 : 954 : bool found = false;
39 [ + - ]: 954 : TDUIDList::iterator found_value;
40 [ - + ]: 954 : do {
41 [ + - ]: 954 : result = (int)(rng.genrand_int31());
42 [ + - ]: 954 : found_value = uniqueIdList.lower_bound(result);
43 [ + - ][ + - ]: 954 : if(found_value != uniqueIdList.end())
[ + + ]
44 : : {
45 [ + - ]: 783 : found = ((*found_value).first == result);
46 [ - + ]: 783 : if (found)
47 [ # # ][ # # ]: 0 : DIAGNOSTIC("Duplicate UID found - very unusual!\n");
[ # # ][ # # ]
48 : : }
49 : : }
50 : : while (found);
51 : :
52 : 954 : return result;
53 : : }
54 : :
55 : :
56 : 2628 : TDUniqueId::TDUniqueId(ToolDataUser *owner, const int id)
57 : : {
58 : 1314 : ownerEntity = owner;
59 : :
60 [ + + ][ + - ]: 1314 : uniqueId = id == 0 ? generate_unique_id() : id;
61 [ + - ]: 1314 : TDUIDList::value_type this_pair(uniqueId, this);
62 [ + - ][ + - ]: 1314 : unique_id_list().insert(this_pair);
63 : :
64 [ + - ]: 1314 : ownerEntity->add_TD(this);
65 : :
66 : :
67 : : // update the attribute if this is a CAU
68 [ - + ]: 1314 : CubitAttribUser *cau = CAST_TO(owner, CubitAttribUser);
69 [ + - ]: 1314 : if (cau) {
70 [ + - ]: 1314 : CubitAttrib *attrib = cau->get_cubit_attrib(CA_UNIQUE_ID);
71 [ + - ]: 1314 : attrib->has_updated(CUBIT_FALSE);
72 [ + - ]: 1314 : attrib->update();
73 : : }
74 : 1314 : }
75 : :
76 : 1785 : int TDUniqueId::is_unique_id(const ToolData* td)
77 : : {
78 [ + - ][ + + ]: 1785 : return (CAST_TO(const_cast<ToolData*>(td), TDUniqueId) != NULL);
79 : : }
80 : :
81 : 0 : TDUniqueId::~TDUniqueId()
82 : : {
83 : : // remove this from the list
84 : : //- With multimaps, keys do not have to be unique. With the erase(Key) function,
85 : : //- the multimap code will remove all entries with that key from the multimap.
86 : : //- The erase(iterator) function only removes the information at that iteration.
87 : : //- Here, we search for the proper entry if there is more than one entry for a
88 : : //- particular key. Increment the iterator and compare the element to 'this'. If
89 : : //- it is a match, erase it by iterator. This will leave the other entry with
90 : : //- the similar key in the list, which is necessary for save/restore, and remove the
91 : : //- deactivated geometry due to the merge.
92 : :
93 : : std::pair<TDUIDList::iterator, TDUIDList::iterator>
94 [ # # ][ # # ]: 0 : bounds_pair = unique_id_list().equal_range(uniqueId);
95 : :
96 [ # # ]: 0 : TDUIDList::iterator it;
97 [ # # ][ # # ]: 0 : for(it = bounds_pair.first; it != bounds_pair.second; ++it)
[ # # ]
98 : : {
99 [ # # ][ # # ]: 0 : if(it->second == this)
100 : : {
101 [ # # ][ # # ]: 0 : unique_id_list().erase( it );
102 : 0 : break;
103 : : }
104 : : }
105 [ # # ]: 0 : }
106 : :
107 : 4758 : int TDUniqueId::get_unique_id(ToolDataUser *owner,
108 : : const CubitBoolean create_new)
109 : : {
110 [ - + ]: 4758 : assert(owner != 0);
111 : 4758 : TDUniqueId *uid = (TDUniqueId *) owner->get_TD(&TDUniqueId::is_unique_id);
112 [ + + ][ + + ]: 4758 : if (!uid && create_new == CUBIT_TRUE) {
113 [ + - ]: 756 : uid = new TDUniqueId(owner);
114 : : }
115 : :
116 [ + + ]: 4758 : return (uid ? uid->unique_id() : 0);
117 : : }
118 : :
119 : 1116 : int TDUniqueId::find_td_unique_id(const int temp_id,
120 : : DLIList<ToolDataUser*> &td_list,
121 : : const RefEntity *related_entity)
122 : : {
123 [ + - ]: 1116 : td_list.clean_out();
124 : :
125 : 1116 : int unique_id = temp_id;
126 : :
127 : : //if we are not doing an undo and importing and merging within a file...
128 [ + - ][ + - ]: 1116 : if( !GSaveOpen::performingUndo &&
129 [ + - ]: 1116 : GeometryQueryTool::importingSolidModel &&
130 : 1116 : !GeometryQueryTool::mergeGloballyOnImport)
131 : : {
132 : : //see if the old id maps to a new id...if so, use the new id
133 [ + - ]: 1116 : UIDMap old_uid_to_new_uid_map = CAUniqueId::get_old_to_new_uid_map();
134 : :
135 [ + - ]: 1116 : UIDMap::iterator iter;
136 [ + - ]: 1116 : iter = old_uid_to_new_uid_map.find( unique_id );
137 : :
138 [ + - ][ + - ]: 1116 : if( iter != old_uid_to_new_uid_map.end() )
[ + + ]
139 [ + - ][ + - ]: 1116 : unique_id = (*iter).second;
140 : : }
141 : :
142 : : std::pair<TDUIDList::iterator, TDUIDList::iterator>
143 [ + - ][ + - ]: 1116 : bounds_pair = unique_id_list().equal_range(unique_id);
144 : :
145 : : TDUIDList::iterator
146 : 1116 : it = bounds_pair.first, upper = bounds_pair.second;
147 : :
148 [ + - ][ + - ]: 1116 : if(it == unique_id_list().end())
[ + - ][ + + ]
149 : 80 : return 0;
150 : :
151 [ + - ][ + + ]: 1036 : if ((*it).first == unique_id ) {
152 : : // the lower bound key is equal to unique_id, so this id is in the list
153 : :
154 : : // look for duplicate id's, return one that's directly related
155 : : // get all td's with that id
156 [ + - ][ + - ]: 1512 : for (; it != upper; it++)
[ + + ]
157 : : {
158 : 756 : bool related = true;
159 [ + - ][ + - ]: 756 : ToolDataUser *temp_tdu = (*it).second->owner_entity();
160 [ - + ]: 756 : if (NULL != related_entity) {
161 [ # # ]: 0 : TopologyEntity *topo_ent = CAST_TO(temp_tdu, TopologyEntity);
162 : 0 : RefEntity* temp_entity = const_cast<RefEntity*>(related_entity);
163 [ # # ][ # # ]: 0 : if (!topo_ent ||
[ # # ]
164 [ # # ][ # # ]: 0 : !topo_ent->is_directly_related(CAST_TO(temp_entity, TopologyEntity)))
165 : 0 : related = false;
166 : : }
167 [ + - ][ + - ]: 756 : if (related) td_list.append(temp_tdu);
168 : : }
169 : : }
170 : :
171 [ + - ]: 1116 : return td_list.size();
172 : : }
173 : :
174 : 1116 : ToolDataUser *TDUniqueId::find_td_unique_id(const int temp_id,
175 : : const RefEntity *related_entity)
176 : : {
177 : : //ToolDataUser *tdu = NULL;
178 [ + - ]: 1116 : DLIList<ToolDataUser*> td_list;
179 [ + - ]: 1116 : find_td_unique_id(temp_id, td_list, related_entity);
180 [ + - ][ + + ]: 1116 : if (0 == td_list.size()) return NULL;
181 : : else {
182 [ + - ]: 756 : td_list.reset();
183 [ + - ]: 756 : return td_list.get();
184 [ + - ]: 1116 : }
185 : : }
186 : :
187 : 0 : int TDUniqueId::get_unique_id_for_copy( int original_id )
188 : : {
189 : : //check in the map if the original is already there
190 : : //if so, get the corresponding id in the map (this is the new
191 : : //unique id on the copy)
192 [ # # ]: 0 : COPYUIDMap::iterator iter;
193 [ # # ]: 0 : iter = mapForCopying.find( original_id );
194 [ # # ][ # # ]: 0 : if( iter != mapForCopying.end() )
[ # # ]
195 [ # # ]: 0 : return (*iter).second;
196 : :
197 : : //else, a) generate another unique id b) put the original id in the map with
198 : : //the new id directly across from it
199 [ # # ]: 0 : int new_uid = generate_unique_id();
200 [ # # ]: 0 : COPYUIDMap::value_type tmp_pair( original_id, new_uid );
201 [ # # ]: 0 : mapForCopying.insert( tmp_pair );
202 : 0 : return new_uid;
203 : : }
204 : :
205 : :
206 : 0 : void TDUniqueId::clear_copy_map()
207 : : {
208 : : //remove TDs off of entities
209 [ # # ]: 0 : COPYUIDMap::iterator iter = mapForCopying.begin();
210 [ # # ][ # # ]: 0 : for(; iter != mapForCopying.end(); iter++ )
[ # # ][ # # ]
211 : : {
212 [ # # ]: 0 : DLIList<ToolDataUser*> tool_data_users;
213 [ # # ][ # # ]: 0 : int num_tool_datas = find_td_unique_id( (*iter).second, tool_data_users );
214 : :
215 [ # # ]: 0 : for( ; num_tool_datas--; )
216 : : {
217 [ # # ]: 0 : ToolDataUser *td_user = tool_data_users.get_and_step();
218 : :
219 : : //make sure the pointer isn't null
220 : 0 : ToolData *tool_data = NULL;
221 [ # # ]: 0 : if(td_user)
222 [ # # ]: 0 : tool_data = td_user->remove_TD(TDUniqueId::is_unique_id);
223 : :
224 : : //delete the TDUniqueId as well
225 [ # # ]: 0 : if( tool_data )
226 [ # # ][ # # ]: 0 : delete tool_data;
227 : :
228 [ # # ][ # # ]: 0 : td_user = find_td_unique_id( (*iter).second );
229 : : }
230 [ # # ]: 0 : }
231 : :
232 : : //clear out the map
233 [ # # ][ # # ]: 0 : if (mapForCopying.empty()) return;
234 [ # # ]: 0 : mapForCopying.clear();
235 : :
236 : : }
237 : :
238 : 2530 : int TDUniqueId::unique_id()
239 : : {
240 : : //if we're doing a copy, don't use the Unique id on the original.
241 : : //generate another one
242 [ - + ]: 2530 : if( GeometryModifyTool::instance()->get_copy_entity() )
243 : : {
244 : 0 : int unique_id_for_copy = get_unique_id_for_copy( uniqueId );
245 : 0 : return unique_id_for_copy;
246 : : }
247 : : else
248 : 2530 : return uniqueId;
249 [ + - ][ + - ]: 6540 : }
|