cgma
|
00001 #include "RefEntityName.hpp" 00002 #include "CubitString.hpp" 00003 #include "RefEntity.hpp" 00004 #include "CubitMessage.hpp" 00005 #include "CubitUtil.hpp" 00006 #include "CastTo.hpp" 00007 #include "RefGroup.hpp" 00008 #include "CubitAttribUser.hpp" 00009 #include "CADefines.hpp" 00010 #include <algorithm> 00011 00012 #include "SettingHandler.hpp" 00013 00014 #include <ctype.h> 00015 #include <assert.h> 00016 00017 // template needed to sort CubitStrings 00018 00019 template <> struct DLIListSorter<CubitString> 00020 { 00021 bool operator()(const CubitString &a, const CubitString &b) { return a < b; } 00022 }; 00023 00024 00025 RefEntityName* RefEntityName::instance_ = 0; 00026 CubitBoolean RefEntityName::mergeBaseNames = CUBIT_FALSE; 00027 int RefEntityName::generateDefaultNames = CUBIT_FALSE; 00028 int RefEntityName::fixDuplicateNames = CUBIT_TRUE; 00029 char RefEntityName::suffixCharacter = '@'; 00030 char RefEntityName::replacementCharacter = '_'; 00031 static int is_valid_char(char c); 00032 static int is_valid_first_char(char c); 00033 bool RefEntityName::printNameChangeWarnings = true; 00034 int RefEntityName::numNameChangeWarnings = 0; 00035 00036 RefEntityName* RefEntityName::instance() 00037 { 00038 if (instance_ == 0) { 00039 instance_ = new RefEntityName; 00040 } 00041 return instance_; 00042 } 00043 00044 RefEntityName::RefEntityName() 00045 { 00046 generateDefaultNames = CUBIT_FALSE; 00047 fixDuplicateNames = CUBIT_TRUE; 00048 replacementCharacter = '_'; 00049 suffixCharacter = '@'; 00050 } 00051 00052 RefEntityName::~RefEntityName() 00053 { 00054 instance_ = 0; 00055 } 00056 00057 void RefEntityName::remove_refentity_name(RefEntity* entity, 00058 const CubitString &name, 00059 CubitBoolean update_attribs) 00060 { 00061 std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(entity); 00062 std::map<CubitString, RefEntity*>::iterator jter = nameEntityList.nameMap.find(name); 00063 00064 bool changed = false; 00065 for(;iters.first != iters.second; ++iters.first) 00066 { 00067 if(iters.first->second == name) 00068 { 00069 changed = true; 00070 nameEntityList.refMap.erase(iters.first); 00071 break; 00072 } 00073 } 00074 00075 if( nameEntityList.nameMap.end() != jter && jter->second == entity) 00076 { 00077 changed = true; 00078 nameEntityList.nameMap.erase(jter); 00079 } 00080 00081 // tell the ref entity to update its names 00082 if (changed && update_attribs) 00083 { 00084 CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME); 00085 attrib->has_updated(CUBIT_FALSE); 00086 attrib->update(); 00087 if( attrib->delete_attrib() ) 00088 entity->remove_cubit_attrib( attrib ); 00089 } 00090 } 00091 00092 void RefEntityName::remove_refentity_name(RefEntity *entity, 00093 CubitBoolean update_attribs) 00094 { 00095 //update the attribute so the names are put into the entity list 00096 if (update_attribs) 00097 { 00098 CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME, 00099 CUBIT_FALSE); 00100 if (attrib) 00101 { 00102 //update the attribute so that the names are on it. 00103 attrib->has_written( CUBIT_FALSE ); 00104 attrib->has_updated(CUBIT_FALSE); 00105 attrib->update(); 00106 00107 //remove the attribute from the underlying entity 00108 //of the solid modeling kernel 00109 RefEntity *attrib_owner = attrib->attrib_owner(); 00110 attrib_owner->remove_attrib_geometry_entity( attrib ); 00111 } 00112 } 00113 00114 // NOTE: There may be multiple names for one RefEntity. Make sure to 00115 // remove all of them. 00116 00117 std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(entity); 00118 00119 for(; iters.first != iters.second;) 00120 { 00121 CubitString name = iters.first->second; 00122 00123 std::map<CubitString, RefEntity*>::iterator jter = nameEntityList.nameMap.find( name ); 00124 00125 if(nameEntityList.nameMap.end() != jter && jter->second == entity) 00126 { 00127 nameEntityList.nameMap.erase(jter); 00128 } 00129 00130 nameEntityList.refMap.erase(iters.first++); 00131 } 00132 00133 // now tell the entity to update its name attribute 00134 if (update_attribs) 00135 { 00136 CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME, 00137 CUBIT_FALSE); 00138 if (attrib) 00139 { 00140 attrib->has_updated(CUBIT_FALSE); 00141 attrib->update(); 00142 entity->remove_cubit_attrib( attrib ); 00143 delete attrib; 00144 } 00145 } 00146 } 00147 00148 CubitStatus RefEntityName::add_refentity_name(RefEntity *entity, 00149 DLIList<CubitString> &names, 00150 bool update_attribs, 00151 bool check_name_validity) 00152 { 00153 names.reset(); 00154 //int num_new_names = names.size(); 00155 00156 DLIList<CubitString> new_names; 00157 00158 for (int i=0; i<names.size(); i++) 00159 { 00160 CubitString name = names[i]; 00161 CubitString in_name = name; 00162 CubitBoolean warn_name_change = CUBIT_FALSE; 00163 00164 // first, clean the name 00165 if (check_name_validity) 00166 { 00167 if (clean(name)) 00168 { 00169 // assign original name anyway, then 00170 // continue on and assign modified name. 00171 add_refentity_name(entity, in_name, false, false); 00172 warn_name_change = CUBIT_TRUE; 00173 } 00174 } 00175 // now, check for valid name 00176 CubitBoolean name_valid = CUBIT_FALSE; 00177 00178 std::map<CubitString, RefEntity*>::iterator jter; 00179 jter = nameEntityList.nameMap.find( name ); 00180 bool name_exist = nameEntityList.nameMap.end() != jter; 00181 00182 if (name == "") 00183 { 00184 // blank name entered - do nothing 00185 } 00186 00187 else if( name_exist && jter->second == entity ) 00188 { 00189 // Tried to assign same name to entity 00190 if ( DEBUG_FLAG(92) ) 00191 { 00192 // check to see if it's the same as this entity's default name, 00193 // if so, it probably came in on an attribute, and we don't need 00194 // to hear about it; otherwise, write the warning 00195 CubitString def_name; 00196 entity->generate_default_name(def_name); 00197 if (name != def_name) 00198 PRINT_INFO("Entity name '%s' already assigned to %s %d\n", 00199 name.c_str(), 00200 entity->class_name(), entity->id()); 00201 } 00202 } 00203 else if(name_exist) 00204 { 00205 // Tried to assign existing name to another entity 00206 PRINT_DEBUG_92( "Entity name '%s' for %s %d is already used by %s %d\n", 00207 name.c_str(), entity->class_name(), entity->id(), 00208 jter->second->class_name(), 00209 jter->second->id()); 00210 00211 // either we fix it and keep it, or we don't and get rid of it 00212 name_valid = CUBIT_FALSE; 00213 if (get_fix_duplicate_names()) 00214 { 00215 //if the entity already has the base name, don't generate another 00216 DLIList<CubitString> tmp_names; 00217 get_refentity_name( entity, tmp_names ); 00218 bool gen_unique_name = true; 00219 for( int k=0; k<tmp_names.size(); k++ ) 00220 { 00221 CubitString tmp_name = tmp_names[k]; 00222 if( same_base_name( name, tmp_name ) ) 00223 { 00224 gen_unique_name = false; 00225 break; 00226 } 00227 } 00228 00229 if (gen_unique_name && generate_unique_name(name) ) 00230 { 00231 PRINT_DEBUG_92( "\t%s %d name changed to '%s'\n", 00232 entity->class_name(), entity->id(), name.c_str()); 00233 if(warn_name_change) 00234 { 00235 numNameChangeWarnings++; 00236 if(printNameChangeWarnings) 00237 { 00238 PRINT_WARNING("Entity name '%s' can't be used in commands.\n" 00239 " Additional name '%s' assigned.\n", 00240 in_name.c_str(), name.c_str()); 00241 } 00242 } 00243 00244 name_valid = CUBIT_TRUE; 00245 } 00246 } 00247 } 00248 else 00249 { 00250 if(warn_name_change) 00251 { 00252 numNameChangeWarnings++; 00253 if(printNameChangeWarnings) 00254 { 00255 PRINT_WARNING("Entity name '%s' can't be used in commands.\n" 00256 " Additional name '%s' assigned.\n", 00257 in_name.c_str(), name.c_str()); 00258 } 00259 } 00260 00261 // else the name must be valid 00262 name_valid = CUBIT_TRUE; 00263 } 00264 00265 if (name_valid == CUBIT_TRUE) 00266 { 00267 // name is valid 00268 if (name != in_name) 00269 // name was changed; change in name list too 00270 names[i] = name; 00271 00272 // save this name to later 00273 new_names.append(names[i]); 00274 } 00275 } 00276 00277 if (new_names.size() > 0) 00278 { 00279 // there are some valid, new names; add them, then update attribute 00280 new_names.reset(); 00281 00282 for (int i = new_names.size(); i > 0; i--) 00283 { 00284 CubitString name = new_names.get_and_step(); 00285 00286 std::map<CubitString, RefEntity*>::iterator jter; 00287 jter = nameEntityList.nameMap.find( name ); 00288 00289 if( nameEntityList.nameMap.end() != jter && jter->second == entity ) 00290 { 00291 PRINT_DEBUG_92("Already have name %s for %s %d.\n", 00292 name.c_str(), entity->class_name(), entity->id()); 00293 } 00294 else 00295 { 00296 nameEntityList.nameMap.insert(std::make_pair(name, entity)); 00297 nameEntityList.refMap.insert(std::make_pair(entity, name)); 00298 } 00299 } 00300 00301 if (update_attribs == CUBIT_TRUE) 00302 { 00303 // now tell the entity to update its name attribute 00304 CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME); 00305 // force update by resetting update flag 00306 attrib->has_updated(CUBIT_FALSE); 00307 attrib->update(); 00308 } 00309 } 00310 00311 return CUBIT_SUCCESS; 00312 } 00313 00314 CubitStatus RefEntityName::add_refentity_name(RefEntity *entity, 00315 CubitString &name, 00316 bool update_attribs, 00317 bool check_name_validity) 00318 { 00319 if (name == "") 00320 return CUBIT_FAILURE; 00321 00322 CubitString in_name = name; 00323 bool warn_name_change = false; 00324 00325 if (check_name_validity) 00326 { 00327 if (clean(name)) 00328 { 00329 // Assign the invalid name anyway, then continue on and 00330 // assign the modified name. 00331 add_refentity_name(entity, in_name, false, false); 00332 warn_name_change = true; 00333 } 00334 } 00335 00336 std::map<CubitString, RefEntity*>::iterator jter; 00337 jter = nameEntityList.nameMap.find( name ); 00338 00339 if(nameEntityList.nameMap.end() != jter && jter->second == entity ) 00340 { 00341 // Tried to assign same name to entity 00342 if ( DEBUG_FLAG(92) ) 00343 { 00344 PRINT_INFO("Entity name '%s' already assigned to %s %d\n", 00345 name.c_str(), 00346 entity->class_name(), entity->id()); 00347 return CUBIT_FAILURE; 00348 } 00349 return CUBIT_SUCCESS; 00350 } 00351 else if(nameEntityList.nameMap.end() != jter) 00352 { 00353 // Tried to assign existing name to another entity 00354 if ( DEBUG_FLAG(92) ) 00355 PRINT_WARNING("Entity name '%s' for %s %d is already used by %s %d\n", 00356 name.c_str(), 00357 entity->class_name(), entity->id(), 00358 jter->second->class_name(), jter->second->id()); 00359 if (get_fix_duplicate_names()) 00360 { 00361 //if the entity already has the base name, don't generate another 00362 DLIList<CubitString> tmp_names; 00363 get_refentity_name( entity, tmp_names ); 00364 bool gen_unique_name = true; 00365 for( int k=0; k<tmp_names.size(); k++ ) 00366 { 00367 CubitString tmp_name = tmp_names[k]; 00368 if( same_base_name( name, tmp_name ) ) 00369 { 00370 gen_unique_name = false; 00371 break; 00372 } 00373 } 00374 00375 if (gen_unique_name && generate_unique_name(name)) 00376 { 00377 if (warn_name_change) 00378 { 00379 numNameChangeWarnings++; 00380 if(printNameChangeWarnings) 00381 { 00382 PRINT_WARNING("Entity name '%s' can't be used in commands.\n" 00383 " Additional name '%s' assigned.\n", 00384 in_name.c_str(), name.c_str()); 00385 } 00386 } 00387 if ( DEBUG_FLAG(92) ) 00388 PRINT_WARNING("\t%s %d name changed to '%s'\n", 00389 entity->class_name(), entity->id(), name.c_str()); 00390 return add_refentity_name(entity, name, update_attribs, false); 00391 } 00392 } 00393 return CUBIT_FAILURE; 00394 } 00395 00396 if (warn_name_change) 00397 { 00398 numNameChangeWarnings++; 00399 if(printNameChangeWarnings) 00400 { 00401 PRINT_WARNING("Entity name '%s' can't be used in commands.\n" 00402 " Additional name '%s' assigned.\n", 00403 in_name.c_str(), name.c_str()); 00404 } 00405 } 00406 00407 nameEntityList.nameMap.insert(std::make_pair(name, entity)); 00408 nameEntityList.refMap.insert(std::make_pair(entity, name)); 00409 00410 if (update_attribs == CUBIT_TRUE) 00411 { 00412 // now tell the entity to update its name attribute 00413 CubitAttrib *attrib = entity->get_cubit_attrib(CA_ENTITY_NAME); 00414 // force update by resetting update flag 00415 attrib->has_updated(CUBIT_FALSE); 00416 attrib->update(); 00417 } 00418 00419 return CUBIT_SUCCESS; 00420 } 00421 00422 int RefEntityName::get_refentity_name(const RefEntity *entity, 00423 DLIList<CubitString> &names) 00424 { 00425 // NOTE: There may be multiple names for one RefEntity. Make sure to 00426 // access all of them. 00427 00428 int num_names = 0; 00429 std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(const_cast<RefEntity*>(entity)); 00430 for(; iters.first != iters.second; ++iters.first) 00431 { 00432 num_names++; 00433 names.append(iters.first->second); 00434 } 00435 00436 return num_names; 00437 } 00438 00439 RefEntity* RefEntityName::get_refentity(const CubitString &name) 00440 { 00441 NameRefEntityMap::iterator iter = nameEntityList.nameMap.find(name); 00442 if (iter != nameEntityList.nameMap.end()) 00443 { 00444 return iter->second; 00445 } 00446 return NULL; 00447 } 00448 00449 const char* RefEntityName::get_refentity_type(const CubitString &name) 00450 { 00451 RefEntity *entity = get_refentity(name); 00452 if (entity != NULL) { 00453 return entity->class_name(); 00454 } else { 00455 return NULL; 00456 } 00457 } 00458 00459 int RefEntityName::get_refentity_id(const CubitString &name) 00460 { 00461 RefEntity *entity = get_refentity(name); 00462 if (entity != NULL) { 00463 return entity->id(); 00464 } else { 00465 return 0; 00466 } 00467 } 00468 00469 void RefEntityName::merge_refentity_names(RefEntity *retained, 00470 RefEntity *dead) 00471 { 00472 // NOTE: There may be multiple names for one RefEntity. Make sure to 00473 // process all of them. 00474 00475 std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> iters = nameEntityList.refMap.equal_range(dead); 00476 if(iters.first == iters.second) 00477 return; 00478 00479 std::pair<RefEntityNameMap::iterator, RefEntityNameMap::iterator> jters = nameEntityList.refMap.equal_range(retained); 00480 00481 DLIList<CubitString> combined_names; 00482 for(RefEntityNameMap::iterator iter = jters.first; iter != jters.second; ++iter) 00483 { 00484 combined_names.append(iter->second); 00485 } 00486 for(RefEntityNameMap::iterator iter = iters.first; iter != iters.second; ++iter) 00487 { 00488 combined_names.append(iter->second); 00489 } 00490 combined_names.sort(); 00491 00492 remove_refentity_name(retained, false); 00493 remove_refentity_name(dead); 00494 00495 if (get_merge_base_names() == CUBIT_TRUE) 00496 { 00497 // remove names with identical base names, keeping lowest 00498 for(int i=1; i<combined_names.size(); i++) 00499 { 00500 if(same_base_name(combined_names[i-1], combined_names[i])) 00501 { 00502 combined_names.remove(); 00503 00504 } 00505 combined_names.step(); 00506 } 00507 } 00508 00509 for(int i=0; i<combined_names.size(); i++) 00510 { 00511 nameEntityList.nameMap.insert(std::make_pair(combined_names[i], retained)); 00512 nameEntityList.refMap.insert(std::make_pair(retained, combined_names[i])); 00513 } 00514 00515 // now tell the entity to update its name attribute 00516 CubitAttrib *attrib = retained->get_cubit_attrib(CA_ENTITY_NAME); 00517 // force update by resetting update flag 00518 attrib->has_updated(CUBIT_FALSE); 00519 attrib->update(); 00520 } 00521 00522 void RefEntityName::switch_refentity_names(RefEntity *entity1, 00523 RefEntity *entity2) 00524 { 00525 // NOTE: There may be multiple names for one RefEntity. Make sure to 00526 // process all of them. 00527 00528 DLIList<CubitString> names1, names2; 00529 get_refentity_name(entity1, names1); 00530 get_refentity_name(entity2, names2); 00531 00532 remove_refentity_name(entity1, false); 00533 remove_refentity_name(entity2, false); 00534 00535 add_refentity_name(entity1, names2, true, false); 00536 add_refentity_name(entity2, names1, true, false); 00537 } 00538 00539 void RefEntityName::list_refentity_names(const char *type) 00540 { 00541 // 'type' is a lowercase string specifying the type of entity to be 00542 // returned. (surface, body, ...) 00543 // if 'type' == "all", then all names will be listed. 00544 00545 int do_all = (strcmp("all", type) == 0 || strlen(type) == 0); 00546 00547 PRINT_INFO("\t______Name______ \t__Type__ Id\t\t_Propagated_\n"); 00548 RefEntity *entity; 00549 00550 for(NameRefEntityMap::iterator iter = nameEntityList.nameMap.begin(); iter != nameEntityList.nameMap.end(); ++iter) 00551 { 00552 entity = iter->second; 00553 if (do_all || CubitUtil::strcmp_case_insensitive(entity->class_name(), 00554 type) == 0) 00555 { 00556 PRINT_INFO("%24s %8s\t%-10d \tNo\n", iter->first.c_str(), 00557 entity->class_name(), entity->id()); 00558 } 00559 } 00560 } 00561 00562 int RefEntityName::get_generate_default_names() 00563 { 00564 return generateDefaultNames; 00565 } 00566 00567 void RefEntityName::set_generate_default_names(int on_off) 00568 { 00569 generateDefaultNames = on_off; 00570 } 00571 00572 int RefEntityName::get_fix_duplicate_names() 00573 { 00574 return fixDuplicateNames; 00575 } 00576 00577 void RefEntityName::set_fix_duplicate_names(int on_off) 00578 { 00579 fixDuplicateNames = on_off; 00580 } 00581 00582 CubitStatus RefEntityName::clean(CubitString &raw_name) 00583 { 00584 if (raw_name == "") 00585 return CUBIT_FAILURE; 00586 00587 // A valid name consists of alphanumeric characters plus '.', '_', '-', or '@' 00588 CubitStatus found_invalid_character = CUBIT_FAILURE; 00589 00590 // Initial character must be alphabetic or "_". 00591 char c = raw_name.get_at(0); 00592 if (!is_valid_first_char(c)) { 00593 if (is_valid_first_char(get_character("replace"))) 00594 raw_name.put_at(0, get_character("replace")); 00595 else 00596 raw_name.put_at(0, '_'); 00597 found_invalid_character = CUBIT_SUCCESS; 00598 } 00599 00600 for (unsigned int i = 1; i < raw_name.length(); i++) { 00601 c = raw_name.get_at(i); 00602 if (!is_valid_char(c)) { 00603 found_invalid_character = CUBIT_SUCCESS; 00604 raw_name.put_at(i, get_character("replace")); 00605 } 00606 } 00607 return found_invalid_character; 00608 } 00609 00610 void RefEntityName::set_character(char rep, const CubitString &type) 00611 { 00612 if (is_valid_char(rep)) { 00613 if (type.get_at(0) == 'R' || type.get_at(0) == 'r') 00614 replacementCharacter = rep; 00615 else if (type.get_at(0) == 'S' || type.get_at(0) == 's') 00616 suffixCharacter = rep; 00617 else 00618 PRINT_ERROR("Invalid character type '%s', must be " 00619 "'replacement' or 'suffix'\n", type.c_str()); 00620 } else { 00621 PRINT_ERROR("Character '%c' is not a valid entity name character\n", 00622 rep); 00623 } 00624 } 00625 00626 char RefEntityName::get_character(const CubitString& type) const 00627 { 00628 if (type.get_at(0) == 'R' || type.get_at(0) == 'r') 00629 return replacementCharacter; 00630 else if (type.get_at(0) == 'S' || type.get_at(0) == 's') 00631 return suffixCharacter; 00632 else { 00633 PRINT_ERROR("Invalid character type '%s', must be " 00634 "'replacement' or 'suffix'\n", type.c_str()); 00635 return '#'; 00636 } 00637 } 00638 00639 static int is_valid_char(char c) 00640 { 00641 return (!isascii(c) || isalnum(c) || c == '.' || c == '_' || c == '@'); 00642 } 00643 00644 static int is_valid_first_char(char c) 00645 { 00646 return (!isascii(c) || isalpha(c) || c == '_'); 00647 } 00648 00649 CubitStatus RefEntityName::generate_unique_name(CubitString &name ) 00650 { 00651 // The method used to generate a unique name is to append 00652 // 'suffixCharacter' and 00653 // a letter from A-Z, a-z, or 0-9 to the end of name. 00654 // If none of these produce a unique name, CUBIT_FALSE is returned. 00655 00656 CubitString alphabet = 00657 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; 00658 CubitString suffix(" "); 00659 suffix.put_at(0, suffixCharacter); 00660 00661 CubitString internal = name; 00662 00663 // See if there is an suffixCharacter sign in name already. If so, is it 00664 // the second to the last character in the string. 00665 if (name.length() < 2 || 00666 name.get_at(name.length()-2) != suffixCharacter) { 00667 // Name does not contain suffixCharacter at correct location, add one on. 00668 internal += suffix; 00669 } 00670 00671 CubitStatus found_unique = CUBIT_FAILURE; 00672 int continue_trying = CUBIT_TRUE; 00673 00674 while (!found_unique && continue_trying) { 00675 00676 continue_trying = CUBIT_FALSE; 00677 int name_length = internal.length(); 00678 unsigned int number_tested = 0; 00679 for (unsigned int i=0; i < alphabet.length(); i++) { 00680 internal.put_at(name_length-1, (char)alphabet.get_at(i)); 00681 if (nameEntityList.nameMap.find(internal) == nameEntityList.nameMap.end()) 00682 { 00683 found_unique = CUBIT_SUCCESS; 00684 break; 00685 } 00686 number_tested++; 00687 } 00688 00689 if (number_tested == alphabet.length()) { 00690 // All suffixes used. Add another suffixCharacter and try again 00691 // Name will look like 'Name@@1' or 'Name@@@1'... 00692 // Find LAST suffixCharacter in name 00693 int ch; 00694 for (ch = (int)(internal.length())-1; ch >= 0; ch--) { 00695 if (internal.get_at(ch) == suffixCharacter) { 00696 break; 00697 } 00698 } 00699 if (internal.get_at(ch) == suffixCharacter) { 00700 // Add another suffixCharacter at ch+1 00701 // Assured that position ch+1 exists or we wouldn't be here 00702 internal.put_at(ch+1, suffixCharacter); 00703 if (ch+2 < (int)internal.length()) 00704 internal.put_at(ch+2, ' '); 00705 else 00706 internal += " "; 00707 continue_trying = CUBIT_TRUE; 00708 } 00709 } 00710 } 00711 00712 if (found_unique) 00713 name = internal; 00714 00715 return found_unique; 00716 } 00717 00718 CubitString RefEntityName::base_name(const CubitString& name) 00719 { 00720 const char *pos = strchr(name.c_str(), suffixCharacter); 00721 if (!pos) 00722 return name; 00723 return name.substr(0, pos - name.c_str()); 00724 } 00725 00726 00727 // returns CUBIT_TRUE if the two names have the same base name (i.e. 00728 // the same name before the first suffixCharacter 00729 CubitBoolean RefEntityName::same_base_name(const CubitString &name1, 00730 const CubitString &name2) 00731 { 00732 const char *pos1 = strchr(name1.c_str(), suffixCharacter); 00733 const char *pos2 = strchr(name2.c_str(), suffixCharacter); 00734 00735 // check for replacement character in one but not the other 00736 int length1, length2; 00737 if (pos1 == NULL) 00738 length1 = strlen(name1.c_str()); 00739 else 00740 length1 = pos1 - name1.c_str(); 00741 00742 if (pos2 == NULL) 00743 length2 = strlen(name2.c_str()); 00744 else 00745 length2 = pos2 - name2.c_str(); 00746 00747 // if the lengths are different, the base names are also different 00748 if (length1 != length2) 00749 return CUBIT_FALSE; 00750 00751 if (strncmp(name1.c_str(), name2.c_str(), length1) == 0) 00752 return CUBIT_TRUE; 00753 else 00754 return CUBIT_FALSE; 00755 } 00756 00757 // Copy names from one entity to another. 00758 // Added Aug.14,2000 by J.Kraftcheck for propogating 00759 // names after virtual geometry operations. 00760 void RefEntityName::copy_refentity_names( const RefEntity *source, 00761 RefEntity *target, 00762 CubitBoolean update_attribs ) 00763 { 00764 //No NULL pointers. 00765 assert( source && target ); 00766 00767 //If we can't have duplicate names, then it is not possible to 00768 //copy names. 00769 if( ! get_fix_duplicate_names() ) return; 00770 00771 //Assume the name is valid already, as it is attached to 00772 //the source entity. Also, assume the name is unique to 00773 //the source entity. 00774 DLIList<CubitString> names; 00775 get_refentity_name( source, names ); 00776 names.reset(); 00777 00778 //For each of the names on the source entity 00779 for( int i = names.size(); i > 0; i-- ) 00780 { 00781 CubitString name = names.get_and_step(); 00782 //make the name unique 00783 generate_unique_name( name ); 00784 //associate name with target 00785 00786 nameEntityList.nameMap.insert( std::make_pair( name, target ) ); 00787 nameEntityList.refMap.insert( std::make_pair( target, name ) ); 00788 } 00789 00790 if( (names.size() > 0) && (update_attribs == CUBIT_TRUE) ) 00791 { 00792 // now tell the entity to update its name attribute 00793 CubitAttrib *attrib = target->get_cubit_attrib( CA_ENTITY_NAME ); 00794 // force update by resetting update flag 00795 attrib->has_updated( CUBIT_FALSE ); 00796 attrib->update(); 00797 } 00798 } 00799 00800 00801 00802 //Initialize all settings in this class 00803 void RefEntityName::initialize_settings() 00804 { 00805 00806 SettingHandler::instance()->add_setting("Default Names", 00807 RefEntityName::set_generate_default_names, 00808 RefEntityName::get_generate_default_names); 00809 00810 SettingHandler::instance()->add_setting("Fix Duplicate Names", 00811 RefEntityName::set_fix_duplicate_names, 00812 RefEntityName::get_fix_duplicate_names); 00813 00814 SettingHandler::instance()->add_setting("Replacement Character", 00815 RefEntityName::set_replacement_setting, 00816 RefEntityName::get_replacement_setting); 00817 00818 SettingHandler::instance()->add_setting("Suffix Character", 00819 RefEntityName::set_suffix_setting, 00820 RefEntityName::get_suffix_setting); 00821 00822 SettingHandler::instance()->add_setting("Merge Base Names", 00823 RefEntityName::set_merge_base_names, 00824 RefEntityName::get_merge_base_names); 00825 00826 } 00827 00828 00829 void RefEntityName::copy_refentity_names( DLIList<RefEntity*>& source_list, 00830 RefEntity* target, 00831 CubitBoolean unique_base_names, 00832 CubitBoolean update_attribs ) 00833 { 00834 //Validate input. 00835 assert( target != 0 ); 00836 if( source_list.size() < 1 ) return; 00837 00838 //If we can't have duplicate names, we can't copy. 00839 if( ! get_fix_duplicate_names() ) return; 00840 00841 //If we need to ensure no duplicate base names... 00842 if( unique_base_names ) 00843 { 00844 //Get a big list of all the names from the source_list 00845 DLIList<CubitString> name_list; 00846 source_list.reset(); 00847 for( int i = source_list.size(); i > 0; i-- ) 00848 get_refentity_name( source_list.get_and_step(), name_list ); 00849 00850 //If we don't have any names to add, we're done 00851 if( name_list.size() < 1 ) return; 00852 00853 //Get the first name 00854 name_list.sort(); 00855 name_list.reset(); 00856 CubitString prev_key = name_list.get_and_step(); 00857 00858 //Add name to target 00859 CubitString name = prev_key; 00860 generate_unique_name( name ); 00861 nameEntityList.nameMap.insert( std::make_pair( name, target ) ); 00862 nameEntityList.refMap.insert( std::make_pair( target, name ) ); 00863 00864 //For the rest of the names... 00865 for( int j = name_list.size(); j > 1; j-- ) 00866 { 00867 CubitString key_ptr = name_list.get_and_step(); 00868 00869 //If the name has a different base name than the previous, 00870 //add it to the target. 00871 if( !same_base_name( prev_key, key_ptr ) ) 00872 { 00873 name = key_ptr; 00874 generate_unique_name( name ); 00875 nameEntityList.nameMap.insert( std::make_pair( name, target ) ); 00876 nameEntityList.refMap.insert( std::make_pair( target, name ) ); 00877 } 00878 00879 prev_key = key_ptr; 00880 } 00881 00882 //update attribute, if asked to do so 00883 if( update_attribs ) 00884 { 00885 CubitAttrib *attrib = target->get_cubit_attrib( CA_ENTITY_NAME ); 00886 attrib->has_updated( CUBIT_FALSE ); 00887 attrib->update(); 00888 } 00889 00890 } 00891 else 00892 { 00893 //If we don't care about unique base names, just add them all. 00894 DLIList<CubitString> name_list; 00895 for( int i = source_list.size(); i > 0; i-- ) 00896 get_refentity_name( source_list.get_and_step(), name_list ); 00897 name_list.reset(); 00898 add_refentity_name(target, name_list, update_attribs, false); 00899 } 00900 } 00901 00902 00903 00904 void RefEntityName::set_suffix_setting(CubitString rep) 00905 { 00906 const char* tmp = rep.c_str(); 00907 suffixCharacter = tmp[0]; 00908 } 00909 00910 CubitString RefEntityName::get_suffix_setting() 00911 { 00912 char tmp[] = {suffixCharacter, '\0'}; 00913 return CubitString(tmp); 00914 } 00915 00916 void RefEntityName::set_replacement_setting(CubitString rep) 00917 { 00918 const char* tmp = rep.c_str(); 00919 replacementCharacter = tmp[0]; 00920 } 00921 00922 CubitString RefEntityName::get_replacement_setting() 00923 { 00924 char tmp[] = {replacementCharacter, '\0'}; 00925 return CubitString(tmp); 00926 } 00927 00928 00929 00930 00931 00932 00933 00934 00935 00936 00937 00938 00939 00940 00941 00942 00943 00944