Branch data Line data Source code
1 : : #include "RefEntityName.hpp"
2 : : #include "CubitString.hpp"
3 : : #include "RefEntity.hpp"
4 : : #include "CubitMessage.hpp"
5 : : #include "CubitUtil.hpp"
6 : : #include "CastTo.hpp"
7 : : #include "RefGroup.hpp"
8 : : #include "CubitAttribUser.hpp"
9 : : #include "CADefines.hpp"
10 : : #include <algorithm>
11 : :
12 : : #include "SettingHandler.hpp"
13 : :
14 : : #include <ctype.h>
15 : : #include <assert.h>
16 : :
17 : : // template needed to sort CubitStrings
18 : :
19 : : template <> struct DLIListSorter<CubitString>
20 : : {
21 : : bool operator()(const CubitString &a, const CubitString &b) { return a < b; }
22 : : };
23 : :
24 : :
25 : : RefEntityName* RefEntityName::instance_ = 0;
26 : : CubitBoolean RefEntityName::mergeBaseNames = CUBIT_FALSE;
27 : : int RefEntityName::generateDefaultNames = CUBIT_FALSE;
28 : : int RefEntityName::fixDuplicateNames = CUBIT_TRUE;
29 : : char RefEntityName::suffixCharacter = '@';
30 : : char RefEntityName::replacementCharacter = '_';
31 : : static int is_valid_char(char c);
32 : : static int is_valid_first_char(char c);
33 : : bool RefEntityName::printNameChangeWarnings = true;
34 : : int RefEntityName::numNameChangeWarnings = 0;
35 : :
36 : 207746 : RefEntityName* RefEntityName::instance()
37 : : {
38 [ + + ]: 207746 : if (instance_ == 0) {
39 [ + - ]: 693 : instance_ = new RefEntityName;
40 : : }
41 : 207746 : return instance_;
42 : : }
43 : :
44 : 1386 : RefEntityName::RefEntityName()
45 : : {
46 : 693 : generateDefaultNames = CUBIT_FALSE;
47 : 693 : fixDuplicateNames = CUBIT_TRUE;
48 : 693 : replacementCharacter = '_';
49 : 693 : suffixCharacter = '@';
50 : 693 : }
51 : :
52 : 382 : RefEntityName::~RefEntityName()
53 : : {
54 : 191 : instance_ = 0;
55 : 191 : }
56 : :
57 : 0 : void RefEntityName::remove_refentity_name(RefEntity* entity,
58 : : const CubitString &name,
59 : : CubitBoolean update_attribs)
60 : : {
61 [ # # ]: 0 : std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(entity);
62 [ # # ]: 0 : std::map<CubitString, RefEntity*>::iterator jter = nameEntityList.nameMap.find(name);
63 : :
64 : 0 : bool changed = false;
65 [ # # ][ # # ]: 0 : for(;iters.first != iters.second; ++iters.first)
[ # # ]
66 : : {
67 [ # # ][ # # ]: 0 : if(iters.first->second == name)
[ # # ]
68 : : {
69 : 0 : changed = true;
70 [ # # ]: 0 : nameEntityList.refMap.erase(iters.first);
71 : 0 : break;
72 : : }
73 : : }
74 : :
75 [ # # ][ # # ]: 0 : if( nameEntityList.nameMap.end() != jter && jter->second == entity)
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
76 : : {
77 : 0 : changed = true;
78 [ # # ]: 0 : nameEntityList.nameMap.erase(jter);
79 : : }
80 : :
81 : : // tell the ref entity to update its names
82 [ # # ][ # # ]: 0 : if (changed && update_attribs)
83 : : {
84 [ # # ]: 0 : CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME);
85 [ # # ]: 0 : attrib->has_updated(CUBIT_FALSE);
86 [ # # ]: 0 : attrib->update();
87 [ # # ][ # # ]: 0 : if( attrib->delete_attrib() )
88 [ # # ]: 0 : entity->remove_cubit_attrib( attrib );
89 : : }
90 : 0 : }
91 : :
92 : 52534 : void RefEntityName::remove_refentity_name(RefEntity *entity,
93 : : CubitBoolean update_attribs)
94 : : {
95 : : //update the attribute so the names are put into the entity list
96 [ + + ]: 52534 : if (update_attribs)
97 : : {
98 : : CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME,
99 [ + - ]: 2161 : CUBIT_FALSE);
100 [ + + ]: 2161 : if (attrib)
101 : : {
102 : : //update the attribute so that the names are on it.
103 [ + - ]: 192 : attrib->has_written( CUBIT_FALSE );
104 [ + - ]: 192 : attrib->has_updated(CUBIT_FALSE);
105 [ + - ]: 192 : attrib->update();
106 : :
107 : : //remove the attribute from the underlying entity
108 : : //of the solid modeling kernel
109 [ + - ]: 192 : RefEntity *attrib_owner = attrib->attrib_owner();
110 [ + - ]: 2161 : attrib_owner->remove_attrib_geometry_entity( attrib );
111 : : }
112 : : }
113 : :
114 : : // NOTE: There may be multiple names for one RefEntity. Make sure to
115 : : // remove all of them.
116 : :
117 [ + - ]: 52534 : std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(entity);
118 : :
119 [ + - ][ + + ]: 53838 : for(; iters.first != iters.second;)
120 : : {
121 [ + - ][ + - ]: 1304 : CubitString name = iters.first->second;
122 : :
123 [ + - ]: 1304 : std::map<CubitString, RefEntity*>::iterator jter = nameEntityList.nameMap.find( name );
124 : :
125 [ + - ][ + - ]: 1304 : if(nameEntityList.nameMap.end() != jter && jter->second == entity)
[ + - ][ + - ]
[ + - ][ + - ]
[ + - # # ]
126 : : {
127 [ + - ]: 1304 : nameEntityList.nameMap.erase(jter);
128 : : }
129 : :
130 [ + - ][ + - ]: 1304 : nameEntityList.refMap.erase(iters.first++);
131 [ + - ]: 1304 : }
132 : :
133 : : // now tell the entity to update its name attribute
134 [ + + ]: 52534 : if (update_attribs)
135 : : {
136 : : CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME,
137 [ + - ]: 2161 : CUBIT_FALSE);
138 [ + + ]: 2161 : if (attrib)
139 : : {
140 [ + - ]: 192 : attrib->has_updated(CUBIT_FALSE);
141 [ + - ]: 192 : attrib->update();
142 [ + - ]: 192 : entity->remove_cubit_attrib( attrib );
143 [ + - ][ + - ]: 2161 : delete attrib;
144 : : }
145 : : }
146 : 52534 : }
147 : :
148 : 1329 : CubitStatus RefEntityName::add_refentity_name(RefEntity *entity,
149 : : DLIList<CubitString> &names,
150 : : bool update_attribs,
151 : : bool check_name_validity)
152 : : {
153 [ + - ]: 1329 : names.reset();
154 : : //int num_new_names = names.size();
155 : :
156 [ + - ]: 1329 : DLIList<CubitString> new_names;
157 : :
158 [ + - ][ + + ]: 2968 : for (int i=0; i<names.size(); i++)
159 : : {
160 [ + - ][ + - ]: 1639 : CubitString name = names[i];
161 [ + - ][ + - ]: 3278 : CubitString in_name = name;
162 : 1639 : CubitBoolean warn_name_change = CUBIT_FALSE;
163 : :
164 : : // first, clean the name
165 [ + - ]: 1639 : if (check_name_validity)
166 : : {
167 [ + - ][ + + ]: 1639 : if (clean(name))
168 : : {
169 : : // assign original name anyway, then
170 : : // continue on and assign modified name.
171 [ + - ]: 44 : add_refentity_name(entity, in_name, false, false);
172 : 44 : warn_name_change = CUBIT_TRUE;
173 : : }
174 : : }
175 : : // now, check for valid name
176 : 1639 : CubitBoolean name_valid = CUBIT_FALSE;
177 : :
178 [ + - ]: 1639 : std::map<CubitString, RefEntity*>::iterator jter;
179 [ + - ]: 1639 : jter = nameEntityList.nameMap.find( name );
180 [ + - ][ + - ]: 1639 : bool name_exist = nameEntityList.nameMap.end() != jter;
181 : :
182 [ + - ][ + - ]: 1639 : if (name == "")
[ + - ][ + - ]
183 : : {
184 : : // blank name entered - do nothing
185 : : }
186 : :
187 [ + + ][ + - ]: 1639 : else if( name_exist && jter->second == entity )
[ - + ][ - + ]
188 : : {
189 : : // Tried to assign same name to entity
190 [ # # ][ # # ]: 0 : if ( DEBUG_FLAG(92) )
[ # # ]
191 : : {
192 : : // check to see if it's the same as this entity's default name,
193 : : // if so, it probably came in on an attribute, and we don't need
194 : : // to hear about it; otherwise, write the warning
195 [ # # ]: 0 : CubitString def_name;
196 [ # # ]: 0 : entity->generate_default_name(def_name);
197 [ # # ][ # # ]: 0 : if (name != def_name)
198 [ # # ][ # # ]: 0 : PRINT_INFO("Entity name '%s' already assigned to %s %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
199 : : name.c_str(),
200 [ # # ][ # # ]: 0 : entity->class_name(), entity->id());
201 : : }
202 : : }
203 [ + + ]: 1639 : else if(name_exist)
204 : : {
205 : : // Tried to assign existing name to another entity
206 [ + - ][ + - ]: 583 : PRINT_DEBUG_92( "Entity name '%s' for %s %d is already used by %s %d\n",
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
207 : : name.c_str(), entity->class_name(), entity->id(),
208 : : jter->second->class_name(),
209 [ # # ]: 0 : jter->second->id());
210 : :
211 : : // either we fix it and keep it, or we don't and get rid of it
212 : 583 : name_valid = CUBIT_FALSE;
213 [ + - ][ + - ]: 583 : if (get_fix_duplicate_names())
214 : : {
215 : : //if the entity already has the base name, don't generate another
216 [ + - ]: 583 : DLIList<CubitString> tmp_names;
217 [ + - ]: 583 : get_refentity_name( entity, tmp_names );
218 : 583 : bool gen_unique_name = true;
219 [ + - ][ - + ]: 583 : for( int k=0; k<tmp_names.size(); k++ )
220 : : {
221 [ # # ][ # # ]: 0 : CubitString tmp_name = tmp_names[k];
222 [ # # ][ # # ]: 0 : if( same_base_name( name, tmp_name ) )
223 : : {
224 : 0 : gen_unique_name = false;
225 [ # # ][ # # ]: 0 : break;
226 : : }
227 : 0 : }
228 : :
229 [ + - ][ + - ]: 583 : if (gen_unique_name && generate_unique_name(name) )
[ + - ][ + - ]
230 : : {
231 [ + - ][ + - ]: 583 : PRINT_DEBUG_92( "\t%s %d name changed to '%s'\n",
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
232 [ # # ]: 0 : entity->class_name(), entity->id(), name.c_str());
233 [ - + ]: 583 : if(warn_name_change)
234 : : {
235 : 0 : numNameChangeWarnings++;
236 [ # # ]: 0 : if(printNameChangeWarnings)
237 : : {
238 [ # # ][ # # ]: 0 : PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
[ # # ][ # # ]
[ # # ]
239 : : " Additional name '%s' assigned.\n",
240 [ # # ]: 0 : in_name.c_str(), name.c_str());
241 : : }
242 : : }
243 : :
244 : 583 : name_valid = CUBIT_TRUE;
245 [ + - ]: 583 : }
246 : : }
247 : : }
248 : : else
249 : : {
250 [ + + ]: 1056 : if(warn_name_change)
251 : : {
252 : 44 : numNameChangeWarnings++;
253 [ - + ]: 44 : if(printNameChangeWarnings)
254 : : {
255 [ # # ][ # # ]: 0 : PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
[ # # ][ # # ]
[ # # ]
256 : : " Additional name '%s' assigned.\n",
257 [ # # ]: 0 : in_name.c_str(), name.c_str());
258 : : }
259 : : }
260 : :
261 : : // else the name must be valid
262 : 1056 : name_valid = CUBIT_TRUE;
263 : : }
264 : :
265 [ + - ]: 1639 : if (name_valid == CUBIT_TRUE)
266 : : {
267 : : // name is valid
268 [ + - ][ + + ]: 1639 : if (name != in_name)
269 : : // name was changed; change in name list too
270 [ + - ][ + - ]: 627 : names[i] = name;
271 : :
272 : : // save this name to later
273 [ + - ][ + - ]: 1639 : new_names.append(names[i]);
274 : : }
275 [ + - ]: 1639 : }
276 : :
277 [ + - ][ + - ]: 1329 : if (new_names.size() > 0)
278 : : {
279 : : // there are some valid, new names; add them, then update attribute
280 [ + - ]: 1329 : new_names.reset();
281 : :
282 [ + - ][ + + ]: 2968 : for (int i = new_names.size(); i > 0; i--)
283 : : {
284 [ + - ][ + - ]: 1639 : CubitString name = new_names.get_and_step();
285 : :
286 [ + - ]: 1639 : std::map<CubitString, RefEntity*>::iterator jter;
287 [ + - ]: 1639 : jter = nameEntityList.nameMap.find( name );
288 : :
289 [ + - ][ + - ]: 1639 : if( nameEntityList.nameMap.end() != jter && jter->second == entity )
[ + + ][ + - ]
[ + - ][ + - ]
[ + + # # ]
290 : : {
291 [ + - ][ + - ]: 70 : PRINT_DEBUG_92("Already have name %s for %s %d.\n",
[ - + ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
292 [ # # ]: 0 : name.c_str(), entity->class_name(), entity->id());
293 : : }
294 : : else
295 : : {
296 [ + - ][ + - ]: 1569 : nameEntityList.nameMap.insert(std::make_pair(name, entity));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
297 [ + - ][ + - ]: 1569 : nameEntityList.refMap.insert(std::make_pair(entity, name));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
298 : : }
299 [ + - ]: 1639 : }
300 : :
301 [ + - ]: 1329 : if (update_attribs == CUBIT_TRUE)
302 : : {
303 : : // now tell the entity to update its name attribute
304 [ + - ]: 1329 : CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME);
305 : : // force update by resetting update flag
306 [ + - ]: 1329 : attrib->has_updated(CUBIT_FALSE);
307 [ + - ]: 1329 : attrib->update();
308 : : }
309 : : }
310 : :
311 [ + - ]: 1329 : return CUBIT_SUCCESS;
312 : : }
313 : :
314 : 498 : CubitStatus RefEntityName::add_refentity_name(RefEntity *entity,
315 : : CubitString &name,
316 : : bool update_attribs,
317 : : bool check_name_validity)
318 : : {
319 [ + - ][ + - ]: 498 : if (name == "")
[ + - ][ - + ]
320 : 0 : return CUBIT_FAILURE;
321 : :
322 [ + - ]: 498 : CubitString in_name = name;
323 : 498 : bool warn_name_change = false;
324 : :
325 [ + + ]: 498 : if (check_name_validity)
326 : : {
327 [ + - ][ - + ]: 414 : if (clean(name))
328 : : {
329 : : // Assign the invalid name anyway, then continue on and
330 : : // assign the modified name.
331 [ # # ]: 0 : add_refentity_name(entity, in_name, false, false);
332 : 0 : warn_name_change = true;
333 : : }
334 : : }
335 : :
336 [ + - ]: 498 : std::map<CubitString, RefEntity*>::iterator jter;
337 [ + - ]: 498 : jter = nameEntityList.nameMap.find( name );
338 : :
339 [ + - ][ + - ]: 498 : if(nameEntityList.nameMap.end() != jter && jter->second == entity )
[ + + ][ + - ]
[ - + ][ + - ]
[ - + # # ]
340 : : {
341 : : // Tried to assign same name to entity
342 [ # # ][ # # ]: 0 : if ( DEBUG_FLAG(92) )
[ # # ]
343 : : {
344 [ # # ][ # # ]: 0 : PRINT_INFO("Entity name '%s' already assigned to %s %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
345 : : name.c_str(),
346 [ # # ]: 0 : entity->class_name(), entity->id());
347 : 0 : return CUBIT_FAILURE;
348 : : }
349 : 0 : return CUBIT_SUCCESS;
350 : : }
351 [ + - ][ + - ]: 498 : else if(nameEntityList.nameMap.end() != jter)
[ + + ]
352 : : {
353 : : // Tried to assign existing name to another entity
354 [ + - ][ + - ]: 40 : if ( DEBUG_FLAG(92) )
[ - + ]
355 [ # # ][ # # ]: 0 : PRINT_WARNING("Entity name '%s' for %s %d is already used by %s %d\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
356 : : name.c_str(),
357 : : entity->class_name(), entity->id(),
358 [ # # ]: 0 : jter->second->class_name(), jter->second->id());
359 [ + - ][ + - ]: 40 : if (get_fix_duplicate_names())
360 : : {
361 : : //if the entity already has the base name, don't generate another
362 [ + - ]: 40 : DLIList<CubitString> tmp_names;
363 [ + - ]: 40 : get_refentity_name( entity, tmp_names );
364 : 40 : bool gen_unique_name = true;
365 [ + - ][ - + ]: 40 : for( int k=0; k<tmp_names.size(); k++ )
366 : : {
367 [ # # ][ # # ]: 0 : CubitString tmp_name = tmp_names[k];
368 [ # # ][ # # ]: 0 : if( same_base_name( name, tmp_name ) )
369 : : {
370 : 0 : gen_unique_name = false;
371 [ # # ][ # # ]: 0 : break;
372 : : }
373 : 0 : }
374 : :
375 [ + - ][ + - ]: 40 : if (gen_unique_name && generate_unique_name(name))
[ + - ][ + - ]
376 : : {
377 [ - + ]: 40 : if (warn_name_change)
378 : : {
379 : 0 : numNameChangeWarnings++;
380 [ # # ]: 0 : if(printNameChangeWarnings)
381 : : {
382 [ # # ][ # # ]: 0 : PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
[ # # ][ # # ]
[ # # ]
383 : : " Additional name '%s' assigned.\n",
384 [ # # ]: 0 : in_name.c_str(), name.c_str());
385 : : }
386 : : }
387 [ + - ][ + - ]: 40 : if ( DEBUG_FLAG(92) )
[ - + ]
388 [ # # ][ # # ]: 0 : PRINT_WARNING("\t%s %d name changed to '%s'\n",
[ # # ][ # # ]
[ # # ][ # # ]
389 [ # # ]: 0 : entity->class_name(), entity->id(), name.c_str());
390 [ + - ][ + - ]: 40 : return add_refentity_name(entity, name, update_attribs, false);
[ - + ]
391 : 40 : }
392 : : }
393 : 0 : return CUBIT_FAILURE;
394 : : }
395 : :
396 [ - + ]: 458 : if (warn_name_change)
397 : : {
398 : 0 : numNameChangeWarnings++;
399 [ # # ]: 0 : if(printNameChangeWarnings)
400 : : {
401 [ # # ][ # # ]: 0 : PRINT_WARNING("Entity name '%s' can't be used in commands.\n"
[ # # ][ # # ]
[ # # ]
402 : : " Additional name '%s' assigned.\n",
403 [ # # ]: 0 : in_name.c_str(), name.c_str());
404 : : }
405 : : }
406 : :
407 [ + - ][ + - ]: 458 : nameEntityList.nameMap.insert(std::make_pair(name, entity));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
408 [ + - ][ + - ]: 458 : nameEntityList.refMap.insert(std::make_pair(entity, name));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
409 : :
410 [ + + ]: 458 : if (update_attribs == CUBIT_TRUE)
411 : : {
412 : : // now tell the entity to update its name attribute
413 [ + - ]: 414 : CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME);
414 : : // force update by resetting update flag
415 [ + - ]: 414 : attrib->has_updated(CUBIT_FALSE);
416 [ + - ]: 414 : attrib->update();
417 : : }
418 : :
419 [ + - ]: 498 : return CUBIT_SUCCESS;
420 : : }
421 : :
422 : 65803 : int RefEntityName::get_refentity_name(const RefEntity *entity,
423 : : DLIList<CubitString> &names)
424 : : {
425 : : // NOTE: There may be multiple names for one RefEntity. Make sure to
426 : : // access all of them.
427 : :
428 : 65803 : int num_names = 0;
429 [ + - ]: 65803 : std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(const_cast<RefEntity*>(entity));
430 [ + - ][ + - ]: 72295 : for(; iters.first != iters.second; ++iters.first)
[ + + ]
431 : : {
432 : 6492 : num_names++;
433 [ + - ][ + - ]: 6492 : names.append(iters.first->second);
434 : : }
435 : :
436 : 65803 : return num_names;
437 : : }
438 : :
439 : 0 : RefEntity* RefEntityName::get_refentity(const CubitString &name)
440 : : {
441 [ # # ]: 0 : NameRefEntityMap::iterator iter = nameEntityList.nameMap.find(name);
442 [ # # ][ # # ]: 0 : if (iter != nameEntityList.nameMap.end())
[ # # ]
443 : : {
444 [ # # ]: 0 : return iter->second;
445 : : }
446 : 0 : return NULL;
447 : : }
448 : :
449 : 0 : const char* RefEntityName::get_refentity_type(const CubitString &name)
450 : : {
451 : 0 : RefEntity *entity = get_refentity(name);
452 [ # # ]: 0 : if (entity != NULL) {
453 : 0 : return entity->class_name();
454 : : } else {
455 : 0 : return NULL;
456 : : }
457 : : }
458 : :
459 : 0 : int RefEntityName::get_refentity_id(const CubitString &name)
460 : : {
461 : 0 : RefEntity *entity = get_refentity(name);
462 [ # # ]: 0 : if (entity != NULL) {
463 : 0 : return entity->id();
464 : : } else {
465 : 0 : return 0;
466 : : }
467 : : }
468 : :
469 : 846 : void RefEntityName::merge_refentity_names(RefEntity *retained,
470 : : RefEntity *dead)
471 : : {
472 : : // NOTE: There may be multiple names for one RefEntity. Make sure to
473 : : // process all of them.
474 : :
475 [ + - ]: 846 : std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(dead);
476 [ + - ][ + + ]: 846 : if(iters.first == iters.second)
477 : 846 : return;
478 : :
479 [ + - ]: 40 : std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> jters = nameEntityList.refMap.equal_range(retained);
480 : :
481 [ + - ]: 40 : DLIList<CubitString> combined_names;
482 [ + - ][ + - ]: 80 : for(RefEntityNameMap::iterator iter = jters.first; iter != jters.second; ++iter)
[ + + ]
483 : : {
484 [ + - ][ + - ]: 40 : combined_names.append(iter->second);
485 : : }
486 [ + - ][ + - ]: 80 : for(RefEntityNameMap::iterator iter = iters.first; iter != iters.second; ++iter)
[ + + ]
487 : : {
488 [ + - ][ + - ]: 40 : combined_names.append(iter->second);
489 : : }
490 [ + - ]: 40 : combined_names.sort();
491 : :
492 [ + - ]: 40 : remove_refentity_name(retained, false);
493 [ + - ]: 40 : remove_refentity_name(dead);
494 : :
495 [ + - ][ - + ]: 40 : if (get_merge_base_names() == CUBIT_TRUE)
496 : : {
497 : : // remove names with identical base names, keeping lowest
498 [ # # ][ # # ]: 0 : for(int i=1; i<combined_names.size(); i++)
499 : : {
500 [ # # ][ # # ]: 0 : if(same_base_name(combined_names[i-1], combined_names[i]))
[ # # ][ # # ]
501 : : {
502 [ # # ][ # # ]: 0 : combined_names.remove();
503 : :
504 : : }
505 [ # # ]: 0 : combined_names.step();
506 : : }
507 : : }
508 : :
509 [ + - ][ + + ]: 120 : for(int i=0; i<combined_names.size(); i++)
510 : : {
511 [ + - ][ + - ]: 80 : nameEntityList.nameMap.insert(std::make_pair(combined_names[i], retained));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
512 [ + - ][ + - ]: 80 : nameEntityList.refMap.insert(std::make_pair(retained, combined_names[i]));
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
513 : : }
514 : :
515 : : // now tell the entity to update its name attribute
516 [ + - ]: 40 : CubitAttrib *attrib = retained->get_cubit_attrib(CA_ENTITY_NAME);
517 : : // force update by resetting update flag
518 [ + - ]: 40 : attrib->has_updated(CUBIT_FALSE);
519 [ + - ][ + - ]: 40 : attrib->update();
520 : : }
521 : :
522 : 0 : void RefEntityName::switch_refentity_names(RefEntity *entity1,
523 : : RefEntity *entity2)
524 : : {
525 : : // NOTE: There may be multiple names for one RefEntity. Make sure to
526 : : // process all of them.
527 : :
528 [ # # ][ # # ]: 0 : DLIList<CubitString> names1, names2;
[ # # ]
529 [ # # ]: 0 : get_refentity_name(entity1, names1);
530 [ # # ]: 0 : get_refentity_name(entity2, names2);
531 : :
532 [ # # ]: 0 : remove_refentity_name(entity1, false);
533 [ # # ]: 0 : remove_refentity_name(entity2, false);
534 : :
535 [ # # ]: 0 : add_refentity_name(entity1, names2, true, false);
536 [ # # ][ # # ]: 0 : add_refentity_name(entity2, names1, true, false);
537 : 0 : }
538 : :
539 : 0 : void RefEntityName::list_refentity_names(const char *type)
540 : : {
541 : : // 'type' is a lowercase string specifying the type of entity to be
542 : : // returned. (surface, body, ...)
543 : : // if 'type' == "all", then all names will be listed.
544 : :
545 [ # # ][ # # ]: 0 : int do_all = (strcmp("all", type) == 0 || strlen(type) == 0);
546 : :
547 [ # # ][ # # ]: 0 : PRINT_INFO("\t______Name______ \t__Type__ Id\t\t_Propagated_\n");
548 : : RefEntity *entity;
549 : :
550 [ # # ][ # # ]: 0 : for(NameRefEntityMap::iterator iter = nameEntityList.nameMap.begin(); iter != nameEntityList.nameMap.end(); ++iter)
[ # # ][ # # ]
[ # # ]
551 : : {
552 [ # # ]: 0 : entity = iter->second;
553 [ # # ][ # # ]: 0 : if (do_all || CubitUtil::strcmp_case_insensitive(entity->class_name(),
[ # # ]
554 [ # # ][ # # ]: 0 : type) == 0)
555 : : {
556 [ # # ][ # # ]: 0 : PRINT_INFO("%24s %8s\t%-10d \tNo\n", iter->first.c_str(),
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
557 [ # # ]: 0 : entity->class_name(), entity->id());
558 : : }
559 : : }
560 : 0 : }
561 : :
562 : 82811 : int RefEntityName::get_generate_default_names()
563 : : {
564 : 82811 : return generateDefaultNames;
565 : : }
566 : :
567 : 0 : void RefEntityName::set_generate_default_names(int on_off)
568 : : {
569 : 0 : generateDefaultNames = on_off;
570 : 0 : }
571 : :
572 : 623 : int RefEntityName::get_fix_duplicate_names()
573 : : {
574 : 623 : return fixDuplicateNames;
575 : : }
576 : :
577 : 0 : void RefEntityName::set_fix_duplicate_names(int on_off)
578 : : {
579 : 0 : fixDuplicateNames = on_off;
580 : 0 : }
581 : :
582 : 2053 : CubitStatus RefEntityName::clean(CubitString &raw_name)
583 : : {
584 [ + - ][ - + ]: 2053 : if (raw_name == "")
585 : 0 : return CUBIT_FAILURE;
586 : :
587 : : // A valid name consists of alphanumeric characters plus '.', '_', '-', or '@'
588 : 2053 : CubitStatus found_invalid_character = CUBIT_FAILURE;
589 : :
590 : : // Initial character must be alphabetic or "_".
591 : 2053 : char c = raw_name.get_at(0);
592 [ - + ]: 2053 : if (!is_valid_first_char(c)) {
593 [ # # ][ # # ]: 0 : if (is_valid_first_char(get_character("replace")))
594 [ # # ][ # # ]: 0 : raw_name.put_at(0, get_character("replace"));
595 : : else
596 : 0 : raw_name.put_at(0, '_');
597 : 0 : found_invalid_character = CUBIT_SUCCESS;
598 : : }
599 : :
600 [ + + ]: 22760 : for (unsigned int i = 1; i < raw_name.length(); i++) {
601 : 20707 : c = raw_name.get_at(i);
602 [ + + ]: 20707 : if (!is_valid_char(c)) {
603 : 44 : found_invalid_character = CUBIT_SUCCESS;
604 [ + - ][ + - ]: 44 : raw_name.put_at(i, get_character("replace"));
605 : : }
606 : : }
607 : 2053 : return found_invalid_character;
608 : : }
609 : :
610 : 0 : void RefEntityName::set_character(char rep, const CubitString &type)
611 : : {
612 [ # # ]: 0 : if (is_valid_char(rep)) {
613 [ # # ][ # # ]: 0 : if (type.get_at(0) == 'R' || type.get_at(0) == 'r')
[ # # ]
614 : 0 : replacementCharacter = rep;
615 [ # # ][ # # ]: 0 : else if (type.get_at(0) == 'S' || type.get_at(0) == 's')
[ # # ]
616 : 0 : suffixCharacter = rep;
617 : : else
618 [ # # ]: 0 : PRINT_ERROR("Invalid character type '%s', must be "
619 [ # # ]: 0 : "'replacement' or 'suffix'\n", type.c_str());
620 : : } else {
621 [ # # ]: 0 : PRINT_ERROR("Character '%c' is not a valid entity name character\n",
622 [ # # ]: 0 : rep);
623 : : }
624 : 0 : }
625 : :
626 : 44 : char RefEntityName::get_character(const CubitString& type) const
627 : : {
628 [ + - ][ + - ]: 44 : if (type.get_at(0) == 'R' || type.get_at(0) == 'r')
[ + - ]
629 : 44 : return replacementCharacter;
630 [ # # ][ # # ]: 0 : else if (type.get_at(0) == 'S' || type.get_at(0) == 's')
[ # # ]
631 : 0 : return suffixCharacter;
632 : : else {
633 [ # # ]: 0 : PRINT_ERROR("Invalid character type '%s', must be "
634 [ # # ]: 0 : "'replacement' or 'suffix'\n", type.c_str());
635 : 44 : return '#';
636 : : }
637 : : }
638 : :
639 : 20707 : static int is_valid_char(char c)
640 : : {
641 [ + - ][ + + ]: 20707 : return (!isascii(c) || isalnum(c) || c == '.' || c == '_' || c == '@');
[ + - ][ + + ]
[ + + ]
642 : : }
643 : :
644 : 2053 : static int is_valid_first_char(char c)
645 : : {
646 [ + - ][ + + ]: 2053 : return (!isascii(c) || isalpha(c) || c == '_');
[ + - ]
647 : : }
648 : :
649 : 623 : CubitStatus RefEntityName::generate_unique_name(CubitString &name )
650 : : {
651 : : // The method used to generate a unique name is to append
652 : : // 'suffixCharacter' and
653 : : // a letter from A-Z, a-z, or 0-9 to the end of name.
654 : : // If none of these produce a unique name, CUBIT_FALSE is returned.
655 : :
656 : : CubitString alphabet =
657 [ + - ]: 623 : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
658 [ + - ][ + - ]: 1246 : CubitString suffix(" ");
659 [ + - ]: 623 : suffix.put_at(0, suffixCharacter);
660 : :
661 [ + - ][ + - ]: 1246 : CubitString internal = name;
662 : :
663 : : // See if there is an suffixCharacter sign in name already. If so, is it
664 : : // the second to the last character in the string.
665 [ + - ][ + + ]: 1224 : if (name.length() < 2 ||
[ + + ][ + + ]
666 [ + - ][ + - ]: 601 : name.get_at(name.length()-2) != suffixCharacter) {
667 : : // Name does not contain suffixCharacter at correct location, add one on.
668 [ + - ]: 452 : internal += suffix;
669 : : }
670 : :
671 : 623 : CubitStatus found_unique = CUBIT_FAILURE;
672 : 623 : int continue_trying = CUBIT_TRUE;
673 : :
674 [ + + ][ + - ]: 1246 : while (!found_unique && continue_trying) {
675 : :
676 : 623 : continue_trying = CUBIT_FALSE;
677 [ + - ]: 623 : int name_length = internal.length();
678 : 623 : unsigned int number_tested = 0;
679 [ + - ][ + - ]: 1264 : for (unsigned int i=0; i < alphabet.length(); i++) {
680 [ + - ][ + - ]: 1264 : internal.put_at(name_length-1, (char)alphabet.get_at(i));
681 [ + - ][ + - ]: 1264 : if (nameEntityList.nameMap.find(internal) == nameEntityList.nameMap.end())
[ + - ][ + + ]
682 : : {
683 : 623 : found_unique = CUBIT_SUCCESS;
684 : 623 : break;
685 : : }
686 : 641 : number_tested++;
687 : : }
688 : :
689 [ + - ][ - + ]: 623 : if (number_tested == alphabet.length()) {
690 : : // All suffixes used. Add another suffixCharacter and try again
691 : : // Name will look like 'Name@@1' or 'Name@@@1'...
692 : : // Find LAST suffixCharacter in name
693 : : int ch;
694 [ # # ][ # # ]: 0 : for (ch = (int)(internal.length())-1; ch >= 0; ch--) {
695 [ # # ][ # # ]: 0 : if (internal.get_at(ch) == suffixCharacter) {
696 : 0 : break;
697 : : }
698 : : }
699 [ # # ][ # # ]: 0 : if (internal.get_at(ch) == suffixCharacter) {
700 : : // Add another suffixCharacter at ch+1
701 : : // Assured that position ch+1 exists or we wouldn't be here
702 [ # # ]: 0 : internal.put_at(ch+1, suffixCharacter);
703 [ # # ][ # # ]: 0 : if (ch+2 < (int)internal.length())
704 [ # # ]: 0 : internal.put_at(ch+2, ' ');
705 : : else
706 [ # # ][ # # ]: 0 : internal += " ";
[ # # ]
707 : 0 : continue_trying = CUBIT_TRUE;
708 : : }
709 : : }
710 : : }
711 : :
712 [ + - ]: 623 : if (found_unique)
713 [ + - ]: 623 : name = internal;
714 : :
715 [ + - ]: 623 : return found_unique;
716 : : }
717 : :
718 : 0 : CubitString RefEntityName::base_name(const CubitString& name)
719 : : {
720 : 0 : const char *pos = strchr(name.c_str(), suffixCharacter);
721 [ # # ]: 0 : if (!pos)
722 : 0 : return name;
723 : 0 : return name.substr(0, pos - name.c_str());
724 : : }
725 : :
726 : :
727 : : // returns CUBIT_TRUE if the two names have the same base name (i.e.
728 : : // the same name before the first suffixCharacter
729 : 0 : CubitBoolean RefEntityName::same_base_name(const CubitString &name1,
730 : : const CubitString &name2)
731 : : {
732 : 0 : const char *pos1 = strchr(name1.c_str(), suffixCharacter);
733 : 0 : const char *pos2 = strchr(name2.c_str(), suffixCharacter);
734 : :
735 : : // check for replacement character in one but not the other
736 : : int length1, length2;
737 [ # # ]: 0 : if (pos1 == NULL)
738 : 0 : length1 = strlen(name1.c_str());
739 : : else
740 : 0 : length1 = pos1 - name1.c_str();
741 : :
742 [ # # ]: 0 : if (pos2 == NULL)
743 : 0 : length2 = strlen(name2.c_str());
744 : : else
745 : 0 : length2 = pos2 - name2.c_str();
746 : :
747 : : // if the lengths are different, the base names are also different
748 [ # # ]: 0 : if (length1 != length2)
749 : 0 : return CUBIT_FALSE;
750 : :
751 [ # # ]: 0 : if (strncmp(name1.c_str(), name2.c_str(), length1) == 0)
752 : 0 : return CUBIT_TRUE;
753 : : else
754 : 0 : return CUBIT_FALSE;
755 : : }
756 : :
757 : : // Copy names from one entity to another.
758 : : // Added Aug.14,2000 by J.Kraftcheck for propogating
759 : : // names after virtual geometry operations.
760 : 0 : void RefEntityName::copy_refentity_names( const RefEntity *source,
761 : : RefEntity *target,
762 : : CubitBoolean update_attribs )
763 : : {
764 : : //No NULL pointers.
765 [ # # ][ # # ]: 0 : assert( source && target );
766 : :
767 : : //If we can't have duplicate names, then it is not possible to
768 : : //copy names.
769 [ # # ][ # # ]: 0 : if( ! get_fix_duplicate_names() ) return;
770 : :
771 : : //Assume the name is valid already, as it is attached to
772 : : //the source entity. Also, assume the name is unique to
773 : : //the source entity.
774 [ # # ]: 0 : DLIList<CubitString> names;
775 [ # # ]: 0 : get_refentity_name( source, names );
776 [ # # ]: 0 : names.reset();
777 : :
778 : : //For each of the names on the source entity
779 [ # # ][ # # ]: 0 : for( int i = names.size(); i > 0; i-- )
780 : : {
781 [ # # ][ # # ]: 0 : CubitString name = names.get_and_step();
782 : : //make the name unique
783 [ # # ]: 0 : generate_unique_name( name );
784 : : //associate name with target
785 : :
786 [ # # ][ # # ]: 0 : nameEntityList.nameMap.insert( std::make_pair( name, target ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
787 [ # # ][ # # ]: 0 : nameEntityList.refMap.insert( std::make_pair( target, name ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
788 [ # # ]: 0 : }
789 : :
790 [ # # ][ # # ]: 0 : if( (names.size() > 0) && (update_attribs == CUBIT_TRUE) )
[ # # ][ # # ]
791 : : {
792 : : // now tell the entity to update its name attribute
793 [ # # ]: 0 : CubitAttrib *attrib = target->get_cubit_attrib( CA_ENTITY_NAME );
794 : : // force update by resetting update flag
795 [ # # ]: 0 : attrib->has_updated( CUBIT_FALSE );
796 [ # # ]: 0 : attrib->update();
797 [ # # ]: 0 : }
798 : : }
799 : :
800 : :
801 : :
802 : : //Initialize all settings in this class
803 : 874 : void RefEntityName::initialize_settings()
804 : : {
805 : :
806 : : SettingHandler::instance()->add_setting("Default Names",
807 : : RefEntityName::set_generate_default_names,
808 : 874 : RefEntityName::get_generate_default_names);
809 : :
810 : : SettingHandler::instance()->add_setting("Fix Duplicate Names",
811 : : RefEntityName::set_fix_duplicate_names,
812 : 874 : RefEntityName::get_fix_duplicate_names);
813 : :
814 : : SettingHandler::instance()->add_setting("Replacement Character",
815 : : RefEntityName::set_replacement_setting,
816 : 874 : RefEntityName::get_replacement_setting);
817 : :
818 : : SettingHandler::instance()->add_setting("Suffix Character",
819 : : RefEntityName::set_suffix_setting,
820 : 874 : RefEntityName::get_suffix_setting);
821 : :
822 : : SettingHandler::instance()->add_setting("Merge Base Names",
823 : : RefEntityName::set_merge_base_names,
824 : 874 : RefEntityName::get_merge_base_names);
825 : :
826 : 874 : }
827 : :
828 : :
829 : 0 : void RefEntityName::copy_refentity_names( DLIList<RefEntity*>& source_list,
830 : : RefEntity* target,
831 : : CubitBoolean unique_base_names,
832 : : CubitBoolean update_attribs )
833 : : {
834 : : //Validate input.
835 [ # # ]: 0 : assert( target != 0 );
836 [ # # ]: 0 : if( source_list.size() < 1 ) return;
837 : :
838 : : //If we can't have duplicate names, we can't copy.
839 [ # # ]: 0 : if( ! get_fix_duplicate_names() ) return;
840 : :
841 : : //If we need to ensure no duplicate base names...
842 [ # # ]: 0 : if( unique_base_names )
843 : : {
844 : : //Get a big list of all the names from the source_list
845 [ # # ]: 0 : DLIList<CubitString> name_list;
846 [ # # ]: 0 : source_list.reset();
847 [ # # ][ # # ]: 0 : for( int i = source_list.size(); i > 0; i-- )
848 [ # # ][ # # ]: 0 : get_refentity_name( source_list.get_and_step(), name_list );
849 : :
850 : : //If we don't have any names to add, we're done
851 [ # # ][ # # ]: 0 : if( name_list.size() < 1 ) return;
852 : :
853 : : //Get the first name
854 [ # # ]: 0 : name_list.sort();
855 [ # # ]: 0 : name_list.reset();
856 [ # # ][ # # ]: 0 : CubitString prev_key = name_list.get_and_step();
[ # # ][ # # ]
[ # # ]
857 : :
858 : : //Add name to target
859 [ # # ][ # # ]: 0 : CubitString name = prev_key;
860 [ # # ]: 0 : generate_unique_name( name );
861 [ # # ][ # # ]: 0 : nameEntityList.nameMap.insert( std::make_pair( name, target ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
862 [ # # ][ # # ]: 0 : nameEntityList.refMap.insert( std::make_pair( target, name ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
863 : :
864 : : //For the rest of the names...
865 [ # # ][ # # ]: 0 : for( int j = name_list.size(); j > 1; j-- )
866 : : {
867 [ # # ][ # # ]: 0 : CubitString key_ptr = name_list.get_and_step();
868 : :
869 : : //If the name has a different base name than the previous,
870 : : //add it to the target.
871 [ # # ][ # # ]: 0 : if( !same_base_name( prev_key, key_ptr ) )
872 : : {
873 [ # # ]: 0 : name = key_ptr;
874 [ # # ]: 0 : generate_unique_name( name );
875 [ # # ][ # # ]: 0 : nameEntityList.nameMap.insert( std::make_pair( name, target ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
876 [ # # ][ # # ]: 0 : nameEntityList.refMap.insert( std::make_pair( target, name ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
877 : : }
878 : :
879 [ # # ]: 0 : prev_key = key_ptr;
880 [ # # ]: 0 : }
881 : :
882 : : //update attribute, if asked to do so
883 [ # # ]: 0 : if( update_attribs )
884 : : {
885 [ # # ]: 0 : CubitAttrib *attrib = target->get_cubit_attrib( CA_ENTITY_NAME );
886 [ # # ]: 0 : attrib->has_updated( CUBIT_FALSE );
887 [ # # ]: 0 : attrib->update();
888 : 0 : }
889 : :
890 : : }
891 : : else
892 : : {
893 : : //If we don't care about unique base names, just add them all.
894 [ # # ]: 0 : DLIList<CubitString> name_list;
895 [ # # ][ # # ]: 0 : for( int i = source_list.size(); i > 0; i-- )
896 [ # # ][ # # ]: 0 : get_refentity_name( source_list.get_and_step(), name_list );
897 [ # # ]: 0 : name_list.reset();
898 [ # # ][ # # ]: 0 : add_refentity_name(target, name_list, update_attribs, false);
899 : : }
900 : : }
901 : :
902 : :
903 : :
904 : 0 : void RefEntityName::set_suffix_setting(CubitString rep)
905 : : {
906 : 0 : const char* tmp = rep.c_str();
907 : 0 : suffixCharacter = tmp[0];
908 : 0 : }
909 : :
910 : 0 : CubitString RefEntityName::get_suffix_setting()
911 : : {
912 : 0 : char tmp[] = {suffixCharacter, '\0'};
913 [ # # ]: 0 : return CubitString(tmp);
914 : : }
915 : :
916 : 0 : void RefEntityName::set_replacement_setting(CubitString rep)
917 : : {
918 : 0 : const char* tmp = rep.c_str();
919 : 0 : replacementCharacter = tmp[0];
920 : 0 : }
921 : :
922 : 0 : CubitString RefEntityName::get_replacement_setting()
923 : : {
924 : 0 : char tmp[] = {replacementCharacter, '\0'};
925 [ # # ]: 0 : return CubitString(tmp);
926 [ + - ][ + - ]: 6540 : }
927 : :
928 : :
929 : :
930 : :
931 : :
932 : :
933 : :
934 : :
935 : :
936 : :
937 : :
938 : :
939 : :
940 : :
941 : :
942 : :
943 : :
944 : :
|