cgma
|
00001 00024 #include <algorithm> 00025 #include <iostream> 00026 00027 #include "CATag.hpp" 00028 #include "RefEntity.hpp" 00029 #include "RefEntityName.hpp" 00030 #include "RefEntityFactory.hpp" 00031 #include "CubitAttribManager.hpp" 00032 #include "RefGroup.hpp" 00033 #include "TDUniqueId.hpp" 00034 #include "CGMApp.hpp" 00035 #include "iGeomError.h" 00036 #include "TopologyEntity.hpp" 00037 #include "CubitMessage.hpp" 00038 00039 #define CHECK_SIZE(array, type, this_size, retval) \ 00040 if (0 == array ## _allocated || array ## _allocated < this_size) {\ 00041 if (NULL != array) free(array); \ 00042 array = (type*)malloc(this_size*sizeof(type));\ 00043 array ## _allocated=this_size;\ 00044 if (NULL == array) { \ 00045 CGM_iGeom_setLastError(iBase_MEMORY_ALLOCATION_FAILED);\ 00046 return retval; \ 00047 }\ 00048 }; \ 00049 array ## _size = this_size; 00050 00051 static inline iBase_ErrorType tag_check_size( char*& array, 00052 int& allocated, 00053 int size ) 00054 { 00055 if (!array || !allocated) { 00056 allocated = size; 00057 array = (char*)malloc(allocated); 00058 if (!array) 00059 return iBase_MEMORY_ALLOCATION_FAILED; 00060 } 00061 else if (allocated < size) { 00062 return iBase_BAD_ARRAY_SIZE; 00063 } 00064 00065 return iBase_SUCCESS; 00066 } 00067 00068 #define TAG_CHECK_SIZE(array, allocated, size) \ 00069 if (iBase_ErrorType tag_check_size_tmp = tag_check_size( array, allocated, size )) \ 00070 return tag_check_size_tmp; 00071 00072 #define RETURN(a) {CGM_iGeom_setLastError(a); return a;} 00073 00074 const char *CGMTagManager::CATag_NAME = "ITAPS_Tag"; 00075 const char *CGMTagManager::CATag_NAME_INTERNAL = "ITAPS_TAG"; 00076 00077 00078 class CSATagData 00079 { 00080 public: 00081 CSATagData() 00082 : dblData(0), dblDataSize(0), intData(0), intDataSize(0), 00083 stringData(0), stringDataSize(0), indivStringSize(0) 00084 {} 00085 00086 ~CSATagData() 00087 { 00088 } 00089 00090 void reset(); 00091 00092 double *dblData; 00093 int dblDataSize; 00094 00095 int *intData; 00096 int intDataSize; 00097 00098 char *stringData; 00099 int stringDataSize; 00100 int indivStringSize; 00101 }; 00102 00103 00104 CubitAttrib *CGMTagManager::CATag_creator(RefEntity* entity, const CubitSimpleAttrib &p_csa) 00105 { 00106 CubitSimpleAttrib csa = p_csa; 00107 CATag *this_ca = new CATag(&instance(), entity, &csa); 00108 return this_ca; 00109 } 00110 00111 00112 static CGMTagManager::TagInfo preset_tag_list[] = { 00113 // tag size tag name tag data type default active 00114 { 0, "", iBase_BYTES, NULL, false }, 00115 { 32, "NAME", iBase_BYTES, NULL, true }, 00116 { sizeof(int), "GLOBAL_ID", iBase_INTEGER, NULL, true }, 00117 { sizeof(int), "UNIQUE_ID", iBase_INTEGER, NULL, true }, 00118 { sizeof(int), "MESH_INTERVAL", iBase_INTEGER, NULL, true }, 00119 { sizeof(double), "MESH_SIZE", iBase_DOUBLE, NULL, true }, 00120 { 4, "SIZE_FIRMNESS", iBase_BYTES, NULL, true } }; 00121 00122 00123 CGMTagManager::TagInfo* const CGMTagManager::presetTagInfo = preset_tag_list; 00124 const int CGMTagManager::numPresetTag = sizeof(preset_tag_list)/sizeof(preset_tag_list[0]); 00125 00126 CGMTagManager::CGMTagManager() 00127 : interfaceGroup(NULL) 00128 { 00129 pcTag = 0; 00130 tagInfo.push_back(preset_tag_list[0]); 00131 00132 // get the tag number for CATag 00133 DLIList<int> tag_types; 00134 int max_type = 0; 00135 CubitAttribManager *cam = CGMApp::instance()->attrib_manager(); 00136 cam->get_registered_types(tag_types); 00137 for (int i = 0; i < tag_types.size(); i++) { 00138 int this_type = tag_types.get_and_step(); 00139 max_type = (max_type < this_type ? this_type : max_type); 00140 } 00141 00142 max_type++; 00143 CubitStatus status = cam->register_attrib_type(max_type, CATag_NAME, CATag_NAME_INTERNAL, 00144 &CGMTagManager::CATag_creator, false, true, 00145 true, true, true, false); 00146 if (CUBIT_FAILURE == status) { 00147 CGM_iGeom_setLastError( iBase_FAILURE, "Couldn't create cgm attribute for tags." ); 00148 } 00149 else 00150 CATag_att_type = max_type; 00151 00152 // create preset tags, for CGM attributes we want to be visible as tags 00153 // name - make same as in MBTagConventions 00154 for (int i = 1; i < numPresetTag; ++i) 00155 tagNameMap[presetTagInfo[i].tagName] = -i; // neg handles beginning with -1 00156 } 00157 00158 CGMTagManager::~CGMTagManager() 00159 { 00160 00161 } 00162 00163 long CGMTagManager::pc_tag(const bool create_if_missing) 00164 { 00165 if (0 == pcTag && create_if_missing) { 00166 pcTag = getTagHandle("__cgm_parent_child_tag"); 00167 if (0 == pcTag) { 00168 // ok, one doesn't exist, create one 00169 void *def_val[] = {NULL, NULL}; 00170 00171 createTag("__cgm_parent_child_tag", 2*sizeof(std::vector<RefGroup*>*), 00172 iBase_BYTES, (char*)def_val, &pcTag); 00173 } 00174 } 00175 00176 return pcTag; 00177 } 00178 00179 void CSATagData::reset() 00180 { 00181 if (0 != dblData) free(dblData); 00182 if (0 != intData) free(intData); 00183 if (0 != stringData) free(stringData); 00184 } 00185 00186 iBase_ErrorType CGMTagManager::create_csa_tag(const char *tag_name, long *tag_handle) 00187 { 00188 // make a special tag type to hold csa data from CGM; this tag holds, in this order: 00189 // a) dbl_data (double*), dbl_data_size (int) 00190 // b) int_data (int*), int_data_size (int) 00191 // c) string_data (char*), string_data_size (int), indiv_string_size (int) 00192 // 00193 // For string data, multiple strings are packed into a single string, with each string 00194 // occupying indiv_string_size bytes and string_size indicating number of such strings 00195 // in packed string 00196 // 00197 // So, size of this tag is 3*sizeof(void*) + 4*sizeof(int), assuming pointers occupy 00198 // same space regardless of what they point to 00199 00200 CSATagData dum_data; 00201 return createTag(tag_name, sizeof(CSATagData), iBase_BYTES, (char*)&dum_data, tag_handle); 00202 } 00203 00204 iBase_ErrorType CGMTagManager::set_csa_tag(RefEntity *this_ent, 00205 long tag_handle, 00206 CubitSimpleAttrib *csa_ptr) 00207 { 00208 CSATagData this_data; 00209 CSATagData *this_data_ptr = &this_data; 00210 int this_data_size = sizeof(CSATagData), this_data_alloc = this_data_size; 00211 00212 // if data was set on this tag, reset in an attempt to not leak memory 00213 iBase_ErrorType result = getArrData(&this_ent, 1, tag_handle, 00214 (char**)&this_data_ptr, &this_data_alloc, &this_data_size); 00215 if (iBase_SUCCESS != result && iBase_TAG_NOT_FOUND != result) return result; 00216 00217 if (iBase_TAG_NOT_FOUND != result) this_data.reset(); 00218 00219 // set the data 00220 this_data.dblDataSize = csa_ptr->double_data_list().size(); 00221 this_data.dblData = (double*) malloc(this_data.dblDataSize*sizeof(double)); 00222 for (int i = 0; i < this_data.dblDataSize; i++) 00223 this_data.dblData[i] = csa_ptr->double_data_list()[0]; 00224 00225 this_data.intDataSize = csa_ptr->int_data_list().size(); 00226 this_data.intData = (int*) malloc(this_data.intDataSize*sizeof(int)); 00227 for (int i = 0; i < this_data.intDataSize; i++) 00228 this_data.intData[i] = csa_ptr->int_data_list()[i]; 00229 00230 // find longest string, then allocate 00231 std::vector<CubitString> sd = csa_ptr->string_data_list(); 00232 this_data.indivStringSize = 0; 00233 for (int i = 0; i < (int)sd.size(); i++) { 00234 if (((int) sd[i].length()) > this_data.indivStringSize) 00235 this_data.indivStringSize = sd[i].length(); 00236 } 00237 // round to next highest multiple of sizeof(int) 00238 if (this_data.indivStringSize%sizeof(int) != 0) 00239 this_data.indivStringSize = ((this_data.indivStringSize/sizeof(int))+1)*sizeof(int); 00240 // now allocate 00241 this_data.stringDataSize = sd.size()*this_data.indivStringSize; 00242 this_data.stringData = (char*) malloc(this_data.stringDataSize); 00243 for (int i = 0; i < (int)sd.size(); i++) 00244 strncpy(this_data.stringData+i*this_data.indivStringSize, sd[i].c_str(), 00245 this_data.indivStringSize); 00246 00247 result = setArrData(&this_ent, 1, tag_handle, (const char*)&this_data_ptr, sizeof(CSATagData)); 00248 00249 return result; 00250 } 00251 00252 iBase_ErrorType CGMTagManager::createTag (/*in*/ const char *tag_name, 00253 /*in*/ const int tag_length, 00254 /*in*/ const int tag_type, 00255 /*in*/ char* default_value, 00256 /*out*/ long *tag_handle) 00257 { 00258 std::string tmp_name(tag_name); 00259 TagInfo tmp_info = {tag_length, tmp_name, tag_type, NULL, true}; 00260 00261 std::map<std::string,long>::iterator mit = tagNameMap.find(tmp_name); 00262 if (mit != tagNameMap.end()) { 00263 // we found a tag with this name; is it still active? 00264 bool active = (mit->second > 0 ? tagInfo[mit->second] : 00265 presetTagInfo[-mit->second]).isActive; 00266 *tag_handle = mit->second; 00267 if (active) { 00268 CGM_iGeom_setLastError( iBase_TAG_ALREADY_EXISTS ); 00269 return iBase_TAG_ALREADY_EXISTS; 00270 } 00271 00272 tagInfo[*tag_handle] = tmp_info; 00273 } 00274 else { 00275 // create a new tag entirely 00276 tagInfo.push_back(tmp_info); 00277 *tag_handle = tagInfo.size() - 1; 00278 00279 // put the name and handle into the map too 00280 tagNameMap[std::string(tag_name)] = *tag_handle; 00281 } 00282 00283 if (default_value != NULL) { 00284 tagInfo[*tag_handle].defaultValue = (char *) malloc(tag_length); 00285 memcpy(tagInfo[*tag_handle].defaultValue, default_value, tag_length); 00286 } 00287 00288 RETURN(iBase_SUCCESS); 00289 } 00290 00291 00292 iBase_ErrorType CGMTagManager::destroyTag (/*in*/ const long tag_handle, 00293 /*in*/ const bool forced) 00294 { 00295 if (!forced) { 00296 // see whether this tag is still assigned anywhere 00297 // not implemented yet 00298 RETURN(iBase_NOT_SUPPORTED); 00299 } 00300 00301 // if we got here, assume we can delete it 00302 TagInfo *tinfo = (tag_handle > 0 ? &tagInfo[tag_handle] : &presetTagInfo[-tag_handle]); 00303 tinfo->isActive = false; 00304 00305 RETURN(iBase_SUCCESS); 00306 } 00307 00308 const char *CGMTagManager::getTagName (/*in*/ const long tag_handle) 00309 { 00310 CGM_iGeom_clearLastError(); 00311 return (tag_handle > 0 ? tagInfo[tag_handle].tagName.c_str() : 00312 presetTagInfo[-tag_handle].tagName.c_str()); 00313 } 00314 00315 int CGMTagManager::getTagSize (/*in*/ const long tag_handle) 00316 { 00317 CGM_iGeom_clearLastError(); 00318 return (tag_handle > 0 ? 00319 tagInfo[tag_handle].tagLength : 00320 presetTagInfo[-tag_handle].tagLength); 00321 } 00322 00323 long CGMTagManager::getTagHandle (/*in*/ const char *tag_name) 00324 { 00325 std::map<std::string,long>::iterator it = 00326 tagNameMap.find(std::string(tag_name)); 00327 if (it != tagNameMap.end()) { 00328 bool active = (it->second > 0 ? tagInfo[it->second] : 00329 presetTagInfo[-it->second]).isActive; 00330 if (active) { 00331 CGM_iGeom_clearLastError(); 00332 return it->second; 00333 } 00334 } 00335 00336 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND ); 00337 return 0; 00338 } 00339 00340 int CGMTagManager::getTagType (/*in*/ const long tag_handle) 00341 { 00342 CGM_iGeom_clearLastError(); 00343 return (tag_handle > 0 ? 00344 tagInfo[tag_handle].tagType : 00345 presetTagInfo[-tag_handle].tagType); 00346 } 00347 00348 iBase_ErrorType CGMTagManager::getArrData (ARRAY_IN_DECL(RefEntity*, entity_handles), 00349 /*in*/ const long tag_handle, 00350 /*inout*/ ARRAY_INOUT_DECL(char, tag_value)) 00351 { 00352 TagInfo *tinfo = (tag_handle > 0 ? &tagInfo[tag_handle] : &presetTagInfo[-tag_handle]); 00353 int tag_size = tinfo->tagLength; 00354 // either way, we have to have that many bytes when we leave this function 00355 const bool allocated_data_arr = (*tag_value_allocated == 0); 00356 TAG_CHECK_SIZE(*tag_value, *tag_value_allocated, entity_handles_size*tinfo->tagLength); 00357 char *val_ptr = *tag_value; 00358 if (tag_handle < 0) { 00359 for (int i = 0; i < entity_handles_size; i++) { 00360 bool result; 00361 if (NULL == entity_handles[i]) 00362 result = getPresetTagData(interface_group(), tag_handle, val_ptr, tinfo->tagLength); 00363 else 00364 result = getPresetTagData(entity_handles[i], tag_handle, val_ptr, tinfo->tagLength); 00365 if (!result) { 00366 if (allocated_data_arr) { 00367 free(*tag_value); 00368 *tag_value = 0; 00369 *tag_value_allocated = 0; 00370 } 00371 RETURN(iBase_TAG_NOT_FOUND); 00372 } 00373 val_ptr += tinfo->tagLength; 00374 } 00375 *tag_value_size = entity_handles_size*tinfo->tagLength; 00376 RETURN(iBase_SUCCESS); 00377 } 00378 00379 iBase_ErrorType result = iBase_SUCCESS, tmp_result; 00380 00381 for (int i = 0; i < entity_handles_size; i++) { 00382 // ok to cast away const-ness because "false" passed in for create_if_missing 00383 RefEntity *this_ent = (NULL == entity_handles[i] ? interface_group() : 00384 const_cast<RefEntity*>(entity_handles[i])); 00385 CATag *catag = get_catag(this_ent); 00386 if (NULL != catag) { 00387 tmp_result = catag->get_tag_data(tag_handle, val_ptr); 00388 if (iBase_SUCCESS != tmp_result) 00389 CGM_iGeom_setLastError( tmp_result, "Problem getting tag data." ); 00390 } 00391 else if (NULL != tinfo->defaultValue) { 00392 memcpy(val_ptr, tinfo->defaultValue, tinfo->tagLength); 00393 tmp_result = iBase_SUCCESS; 00394 } 00395 else { 00396 tmp_result = iBase_TAG_NOT_FOUND; 00397 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND ); 00398 } 00399 00400 if (iBase_SUCCESS != tmp_result) result = tmp_result; 00401 00402 val_ptr += tag_size; 00403 } 00404 00405 if (iBase_SUCCESS != result) 00406 *tag_value_size = 0; 00407 else 00408 *tag_value_size = entity_handles_size*tinfo->tagLength; 00409 00410 RETURN(result); 00411 } 00412 00413 iBase_ErrorType CGMTagManager::setArrData (/*in*/ ARRAY_IN_DECL(RefEntity*, entity_handles), 00414 /*in*/ const long tag_handle, 00415 /*in*/ const char *tag_values, const int tag_values_size) 00416 { 00417 TagInfo *tinfo = (tag_handle > 0 ? &tagInfo[tag_handle] : &presetTagInfo[-tag_handle]); 00418 int tag_size = tinfo->tagLength; 00419 00420 const char *val_ptr = tag_values; 00421 00422 iBase_ErrorType result = iBase_SUCCESS, tmp_result; 00423 00424 if (tag_handle < 0) { 00425 for (int i = 0; i < entity_handles_size; i++) { 00426 if (NULL == entity_handles[i]) 00427 tmp_result = setPresetTagData(interface_group(), tag_handle, val_ptr, tag_size); 00428 else 00429 tmp_result = setPresetTagData(entity_handles[i], tag_handle, val_ptr, tag_size); 00430 00431 val_ptr += tag_size; 00432 if (iBase_SUCCESS != tmp_result) result = tmp_result; 00433 } 00434 RETURN(result); 00435 } 00436 00437 for (int i = 0; i < entity_handles_size; i++) { 00438 RefEntity *this_ent = (NULL == entity_handles[i] ? interface_group() : 00439 entity_handles[i]); 00440 CATag *catag = get_catag(this_ent, true); 00441 assert(NULL != catag); 00442 catag->set_tag_data(tag_handle, val_ptr); 00443 val_ptr += tag_size; 00444 } 00445 00446 RETURN(iBase_SUCCESS); 00447 } 00448 00449 iBase_ErrorType CGMTagManager::rmvArrTag (/*in*/ ARRAY_IN_DECL(RefEntity*, entity_handles), 00450 /*in*/ const long tag_handle) 00451 { 00452 for (int i = 0; i < entity_handles_size; i++) { 00453 CATag *catag = get_catag((entity_handles[i] == NULL ? 00454 interface_group() : entity_handles[i])); 00455 if (NULL != catag) catag->remove_tag(tag_handle); 00456 } 00457 00458 RETURN(iBase_SUCCESS); 00459 } 00460 00461 iBase_ErrorType CGMTagManager::getAllTags (/*in*/ const RefEntity* entity_handle, 00462 /*inout*/ ARRAY_INOUT_DECL(long, tag_handles)) 00463 { 00464 int i = 0, uid = 0, tag_size; 00465 char *uid_ptr = (char*) &uid; 00466 bool has_uid = getPresetTagData(entity_handle, -3, uid_ptr, tag_size); 00467 int num_tags = (has_uid ? 3 : 2); 00468 00469 RefEntity *this_ent = (NULL == entity_handle ? interface_group() : 00470 const_cast<RefEntity*>(entity_handle)); 00471 00472 // const-cast because we're passing in false for create_if_missing 00473 CATag *catag = get_catag(this_ent); 00474 if (NULL != catag) { 00475 // need to check whether entity has a uid 00476 num_tags += catag->tagData.size(); 00477 CHECK_SIZE(*tag_handles, long, num_tags, iBase_FAILURE); 00478 for (std::map<int,void*>::iterator tag_it = catag->tagData.begin(); 00479 tag_it != catag->tagData.end(); tag_it++) 00480 (*tag_handles)[i++] = (*tag_it).first; 00481 } 00482 else { 00483 CHECK_SIZE(*tag_handles, long, num_tags, iBase_FAILURE); 00484 } 00485 (*tag_handles)[i++] = -1; 00486 (*tag_handles)[i++] = -2; 00487 if (has_uid) (*tag_handles)[i++] = -3; 00488 00489 RETURN(iBase_SUCCESS); 00490 } 00491 00492 CATag *CGMTagManager::get_catag(RefEntity *ent, 00493 const bool create_if_missing) 00494 { 00495 CubitAttrib *this_attrib = ent->get_cubit_attrib(CATag_att_type, create_if_missing); 00496 if (NULL != this_attrib) 00497 return dynamic_cast<CATag*>(this_attrib); 00498 else 00499 return NULL; 00500 } 00501 00502 RefGroup *CGMTagManager::interface_group(const bool create_if_missing) 00503 { 00504 if (NULL == interfaceGroup) 00505 interfaceGroup = 00506 dynamic_cast<RefGroup*>(RefEntityName::instance()->get_refentity("interface_group")); 00507 00508 if (NULL == interfaceGroup && create_if_missing) 00509 interfaceGroup = RefEntityFactory::instance()->construct_RefGroup("interface_group"); 00510 00511 return interfaceGroup; 00512 } 00513 00514 iBase_ErrorType CGMTagManager::setPresetTagData(RefEntity *entity, 00515 const long tag_handle, 00516 const char *tag_value, 00517 const int tag_size) 00518 { 00519 switch (-tag_handle) { 00520 case 1: 00521 // entity name 00522 if (presetTagInfo[-tag_handle].tagLength != tag_size) { 00523 std::string tmp_str = "Tag of type '"; 00524 tmp_str += presetTagInfo[-tag_handle].tagName + "' is the wrong size."; 00525 CGM_iGeom_setLastError(iBase_INVALID_ARGUMENT, tmp_str.c_str()); 00526 return iBase_INVALID_ARGUMENT; 00527 } 00528 entity->entity_name(CubitString(tag_value)); 00529 RETURN(iBase_SUCCESS); 00530 case 2: 00531 // entity id 00532 CGM_iGeom_setLastError( iBase_NOT_SUPPORTED, "Can't set id of entities with this implementation." ); 00533 return iBase_NOT_SUPPORTED; 00534 case 3: 00535 // unique id 00536 CGM_iGeom_setLastError( iBase_NOT_SUPPORTED, "Can't set unique id of entities with this implementation." ); 00537 return iBase_NOT_SUPPORTED; 00538 case 4: // mesh interval 00539 case 5: // mesh size 00540 case 6: // mesh interval firmness 00541 default: 00542 CGM_iGeom_setLastError( iBase_NOT_SUPPORTED, "Can't set this tag on entities with this implementation." ); 00543 return iBase_NOT_SUPPORTED; 00544 } 00545 00546 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND ); 00547 return iBase_TAG_NOT_FOUND; 00548 } 00549 00550 CubitSimpleAttrib* CGMTagManager::get_simple_attrib(RefEntity* entity, 00551 const char* name ) 00552 { 00553 TopologyEntity* te_ptr = dynamic_cast<TopologyEntity*>(entity); 00554 TopologyBridge* tb_ptr = te_ptr ? te_ptr->bridge_manager()->topology_bridge() : 0; 00555 if (!tb_ptr) { 00556 CGM_iGeom_setLastError( iBase_INVALID_ENTITY_HANDLE, "Entity not topology" ); 00557 return 0; 00558 } 00559 DLIList<CubitSimpleAttrib> attr_list; 00560 tb_ptr->get_simple_attribute("MESH_INTERVAL", attr_list); 00561 if (attr_list.size() == 0) { 00562 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "No MESH_INTERVAL attribute" ); 00563 return 0; 00564 } 00565 CubitSimpleAttrib result = attr_list.pop(); 00566 CubitSimpleAttrib *p_result = new CubitSimpleAttrib(result); 00567 return p_result; 00568 } 00569 00570 00571 bool CGMTagManager::getPresetTagData(const RefEntity *entity, 00572 const long tag_handle, 00573 char *tag_value, 00574 int &tag_size) 00575 { 00576 const char *this_name; 00577 int name_len, val; 00578 double dval; 00579 int *this_id; 00580 int *this_uid; 00581 00582 if (-tag_handle >= numPresetTag || tag_handle >= 0) { 00583 CGM_iGeom_setLastError( iBase_INVALID_TAG_HANDLE, "Invalid tag handle" ); 00584 return false; 00585 } 00586 00587 const TagInfo& info = presetTagInfo[-tag_handle]; 00588 tag_size = info.tagLength; 00589 CubitSimpleAttrib* csa; 00590 CubitString str; 00591 00592 switch (-tag_handle) { 00593 case 1: 00594 // entity name 00595 this_name = entity->entity_name().c_str(); 00596 name_len = strlen(this_name); 00597 // if name is too long, truncate 00598 if (name_len > info.tagLength) 00599 name_len = info.tagLength; 00600 strncpy( tag_value, this_name, name_len ); 00601 // if name is too short, pad with zero bytes 00602 if (name_len < info.tagLength) 00603 memset( tag_value + name_len, 0, (info.tagLength - name_len) ); 00604 return true; 00605 case 2: 00606 // entity id 00607 tag_size = sizeof(int); 00608 this_id = reinterpret_cast<int*>(tag_value); 00609 *this_id = entity->id(); 00610 return true; 00611 case 3: 00612 // unique id 00613 tag_size = sizeof(int); 00614 this_uid = reinterpret_cast<int*>(tag_value); 00615 // const_cast because we're passing false for create_if_missing 00616 *this_uid = TDUniqueId::get_unique_id(const_cast<RefEntity*>(entity), false); 00617 return (*this_uid == 0 ? false : true); 00618 case 4: // mesh interval 00619 csa = get_simple_attrib( const_cast<RefEntity*>(entity), "MESH_INTERVAL" ); 00620 if (!csa) 00621 return false; 00622 val = csa->int_data_list()[0]; 00623 // check if interval is set 00624 // If a) the size is set and b) the firmness is LIMP, then 00625 // the interval count has not been set. 00626 if ( csa->string_data_list().size() && 00627 csa->string_data_list()[0] == "LIMP" && 00628 csa->int_data_list().size() > 1 && 00629 !csa->int_data_list()[0]) 00630 val = 0; 00631 delete csa; 00632 if (val == 0 || val == CUBIT_INT_MIN) { 00633 if (info.defaultValue) 00634 val = *(int*)info.defaultValue; 00635 else { 00636 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "Interval not set" ); 00637 return 0; 00638 } 00639 } 00640 *(int*)tag_value = val; 00641 return true; 00642 case 5: // mesh size 00643 csa = get_simple_attrib( const_cast<RefEntity*>(entity), "MESH_INTERVAL" ); 00644 if (!csa) 00645 return false; 00646 // if size value is invalid or flag indicates size has not been set... 00647 if (csa->double_data_list().size() == 0 || 00648 csa->double_data_list()[0] == CUBIT_DBL_MIN || 00649 (csa->int_data_list().size() > 1 && !csa->int_data_list()[1])) { 00650 if (info.defaultValue) 00651 dval = *(double*)info.defaultValue; 00652 else { 00653 delete csa; 00654 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "Mesh size not set" ); 00655 return false; 00656 } 00657 } 00658 else 00659 dval = csa->double_data_list()[0]; 00660 delete csa; 00661 *(double*)tag_value = dval; 00662 return true; 00663 case 6: // interval firmness 00664 csa = get_simple_attrib( const_cast<RefEntity*>(entity), "MESH_INTERVAL" ); 00665 if (!csa) 00666 return false; 00667 if (csa->string_data_list().size() < 2) { 00668 delete csa; 00669 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND, "Interval firmness not set" ); 00670 return false; 00671 } 00672 str = csa->string_data_list()[1]; 00673 memcpy( tag_value, str.c_str(), 4 ); 00674 delete csa; 00675 return true; 00676 } 00677 00678 return false; 00679 } 00680 00681 std::vector<RefGroup*> *CGMTagManager::pc_list(RefEntity *gentity, int list_no, 00682 const bool create_if_missing) 00683 { 00684 if (NULL == gentity) return NULL; 00685 00686 int dum_tag_size = sizeof(std::vector<RefGroup*>*); 00687 int dum = 2*dum_tag_size; 00688 std::vector<RefGroup*> *pc_lists[2]; 00689 char *dum_ptr = (char*) pc_lists; 00690 iBase_ErrorType result = 00691 getArrData(&gentity, 1, pc_tag(create_if_missing), &dum_ptr, 00692 &dum, &dum); 00693 assert(iBase_SUCCESS == result); 00694 if (iBase_SUCCESS != result) { 00695 PRINT_ERROR("Failed to get array data.\n"); 00696 return NULL; 00697 } 00698 00699 if (0 > list_no || 1 < list_no) return NULL; 00700 00701 if (NULL == pc_lists[list_no] && create_if_missing) { 00702 pc_lists[list_no] = new std::vector<RefGroup*>(); 00703 result = 00704 setArrData(&gentity, 1, pc_tag(), (char*)pc_lists, 2*dum_tag_size); 00705 assert(iBase_SUCCESS == result); 00706 if (iBase_SUCCESS != result) { 00707 PRINT_ERROR("Failed to set array data.\n"); 00708 return NULL; 00709 } 00710 } 00711 00712 return pc_lists[list_no]; 00713 } 00714 00715 void CGMTagManager::pc_list(RefEntity *gentity, std::vector<RefGroup*> *&parents, 00716 std::vector<RefGroup*> *&children, 00717 const bool create_if_missing) 00718 { 00719 if (NULL == gentity) return; 00720 00721 int dum_tag_size = sizeof(std::vector<RefGroup*>*); 00722 int dum = 2*dum_tag_size; 00723 std::vector<RefGroup*> *pc_lists[2]; 00724 char *dum_ptr = (char*) pc_lists; 00725 iBase_ErrorType result = 00726 getArrData(&gentity, 1, pc_tag(), 00727 &dum_ptr, &dum, &dum); 00728 assert(iBase_SUCCESS == result); 00729 if (iBase_SUCCESS != result) { 00730 PRINT_ERROR("Failed to get array data.\n"); 00731 return; 00732 } 00733 00734 if ((NULL == pc_lists[0] || NULL == pc_lists[1]) && create_if_missing) { 00735 bool must_set = false; 00736 for (int i = 0; i < 2; i++) { 00737 if (NULL == pc_lists[i]) { 00738 pc_lists[i] = new std::vector<RefGroup*>(); 00739 must_set = true; 00740 } 00741 } 00742 if (must_set) { 00743 result = setArrData(&gentity, 1, pc_tag(), (char*)pc_lists, 00744 2*dum_tag_size); 00745 assert(iBase_SUCCESS == result); 00746 if (iBase_SUCCESS != result) { 00747 PRINT_ERROR("Failed to set array data.\n"); 00748 return; 00749 } 00750 } 00751 } 00752 00753 parents = pc_lists[0]; 00754 children = pc_lists[1]; 00755 } 00756 00757 void CGMTagManager::get_pc_groups(RefGroup *this_grp, const int p_or_c, const int num_hops, 00758 std::vector<RefGroup *> &group_ptrs) 00759 { 00760 if (NULL == this_grp) return; 00761 00762 int next_hop = num_hops - 1; 00763 std::vector<RefGroup*> tmp_groups; 00764 00765 // get my children 00766 std::vector<RefGroup*> *my_children = pc_list(this_grp, p_or_c, false); 00767 if (NULL != my_children) 00768 tmp_groups = *my_children; 00769 00770 // get their children if we're not out of hops 00771 std::vector<RefGroup*>::iterator vit; 00772 if (0 < next_hop) { 00773 for (vit = tmp_groups.begin(); vit != tmp_groups.end(); vit++) 00774 get_pc_groups(*vit, p_or_c, next_hop, group_ptrs); 00775 } 00776 00777 // now add mine to the list; make sure it isn't there already 00778 for (vit = tmp_groups.begin(); vit != tmp_groups.end(); vit++) { 00779 if (std::find(group_ptrs.begin(), group_ptrs.end(), *vit) == group_ptrs.end()) 00780 group_ptrs.push_back(*vit); 00781 } 00782 } 00783 00784 CATag::~CATag() 00785 { 00786 for (std::map<int, void*>::iterator 00787 mit = tagData.begin(); mit != tagData.end(); mit++) 00788 if (NULL != (*mit).second) free ((*mit).second); 00789 } 00790 00791 00792 CATag::CATag(CGMTagManager *manager, RefEntity *entity) 00793 : CubitAttrib(entity), myManager(manager) 00794 { 00795 } 00796 00797 CATag::CATag(CGMTagManager *manager, RefEntity *owner, CubitSimpleAttrib *csa_ptr) 00798 : CubitAttrib(owner), myManager(manager) 00799 { 00800 if (NULL != csa_ptr) add_csa_data(csa_ptr); 00801 } 00802 00803 CubitStatus CATag::reset() 00804 { 00805 for (std::map<int, void*>::iterator 00806 mit = tagData.begin(); mit != tagData.end(); mit++) 00807 if (NULL != (*mit).second) free ((*mit).second); 00808 00809 tagData.clear(); 00810 00811 return CUBIT_SUCCESS; 00812 } 00813 00814 CubitSimpleAttrib CATag::cubit_simple_attrib() 00815 { 00816 //if (tagData.size() == 0) return NULL; 00817 00818 std::vector<int, std::allocator<int> >int_data; 00819 std::vector<CubitString> str_data; 00820 std::vector<double> dbl_data; 00821 00822 str_data.push_back(myManager->CATag_NAME_INTERNAL); 00823 00824 // int data first gets the # tags on this entity 00825 int_data.push_back(tagData.size()); 00826 00827 // for each tag: 00828 for (std::map<int, void*>::iterator 00829 mit = tagData.begin(); mit != tagData.end(); mit++) { 00830 long tag_handle = (*mit).first; 00831 CGMTagManager::TagInfo *tinfo = (tag_handle > 0 ? 00832 &(myManager->tagInfo[tag_handle]) : 00833 &(myManager->presetTagInfo[-tag_handle])); 00834 00835 // store the name 00836 str_data.push_back(tinfo->tagName.c_str()); 00837 00838 // store the length in bytes 00839 int_data.push_back(tinfo->tagLength); 00840 00841 // now the data 00842 // store the raw memory interpreted as an array of ints, padded to a full int 00843 int tag_ints = tinfo->tagLength/4; 00844 if (tinfo->tagLength % 4 != 0) tag_ints++; 00845 00846 int *tag_data = reinterpret_cast<int*>((*mit).second); 00847 for (int i = 0; i < tag_ints; i++) 00848 int_data.push_back(tag_data[i]); 00849 } 00850 00851 // store the data on the csa 00852 CubitSimpleAttrib csa(&str_data, &dbl_data, &int_data); 00853 00854 return csa; 00855 } 00856 00857 void CATag::add_csa_data(CubitSimpleAttrib *csa_ptr) 00858 { 00859 // make sure it's a CATag 00860 static CubitString my_type("CA_TAG"); 00861 if (csa_ptr->character_type() != my_type) 00862 return; 00863 00864 int num_attribs = csa_ptr->int_data_list()[0]; 00865 00866 int *tmp_data; 00867 00868 for (int i = 0; i < num_attribs; i++) { 00869 00870 // map the attrib name to a tag 00871 std::map<std::string,long>::iterator pos = 00872 myManager->tagNameMap.find(std::string(csa_ptr->string_data_list()[i].c_str())); 00873 00874 long thandle = 0; 00875 00876 if (pos == myManager->tagNameMap.end()) { 00877 // tag doesn't exist - create one 00878 myManager->createTag(csa_ptr->string_data_list()[i].c_str(), 00879 csa_ptr->int_data_list()[i], iBase_BYTES, 00880 NULL, &thandle); 00881 } 00882 else thandle = (*pos).second; 00883 00884 00885 long tag_handle = thandle; 00886 00887 // copy the ints to a temporary space we can get a ptr to... 00888 int int_length = csa_ptr->int_data_list()[i]; 00889 if (int_length % 4 != 0) int_length++; 00890 tmp_data = (int*) malloc(int_length*sizeof(int)); 00891 for (int j = 0; j < int_length; j++) 00892 tmp_data[j] = csa_ptr->int_data_list()[j]; 00893 00894 // now actually set the data 00895 this->set_tag_data(tag_handle, tmp_data, true); 00896 } 00897 } 00898 00899 void CATag::print() 00900 { 00901 std::cout << "This entity has " << tagData.size() << " tags. Types are: " << std::endl; 00902 for (std::map<int,void*>::iterator mit = tagData.begin(); mit != tagData.end(); mit++) 00903 { 00904 if ((*mit).first > 0) 00905 std::cout << myManager->tagInfo[(*mit).first].tagName << std::endl; 00906 else 00907 std::cout << myManager->presetTagInfo[-(*mit).first].tagName << std::endl; 00908 } 00909 } 00910 00911 iBase_ErrorType CATag::get_tag_data(long tag_handle, void *tag_data) 00912 { 00913 assert(NULL != tag_data); 00914 00915 CGMTagManager::TagInfo *tinfo = (tag_handle > 0 ? 00916 &(myManager->tagInfo[tag_handle]) : 00917 &(myManager->presetTagInfo[-tag_handle])); 00918 00919 // check if this attribute has this tag 00920 std::map<int, void*>::iterator tdpos = tagData.find(tag_handle); 00921 if (tdpos == tagData.end()) { 00922 if (NULL != tinfo->defaultValue) 00923 memcpy(tag_data, tinfo->defaultValue, tinfo->tagLength); 00924 else { 00925 CGM_iGeom_setLastError( iBase_TAG_NOT_FOUND ); 00926 return iBase_TAG_NOT_FOUND; 00927 } 00928 00929 } 00930 00931 else 00932 memcpy(tag_data, (*tdpos).second, tinfo->tagLength); 00933 00934 RETURN(iBase_SUCCESS); 00935 } 00936 00937 iBase_ErrorType CATag::set_tag_data(long tag_handle, const void *tag_data, 00938 const bool can_shallow_copy) 00939 { 00940 CGMTagManager::TagInfo *tinfo = (tag_handle > 0 ? 00941 &(myManager->tagInfo[tag_handle]) : 00942 &(myManager->presetTagInfo[-tag_handle])); 00943 00944 // check if this attribute has this tag 00945 std::map<int, void*>::iterator tdpos = tagData.find(tag_handle); 00946 if (tdpos == tagData.end()) 00947 tdpos = tagData.insert(tagData.end(), 00948 std::pair<int,void*>(tag_handle, 00949 reinterpret_cast<void*>(0))); // XXX(msvc2010): complains about NULL cast to void*? 00950 00951 if (!can_shallow_copy) { 00952 // need to copy the data; might need to allocate first 00953 if ((*tdpos).second == NULL) 00954 (*tdpos).second = malloc(tinfo->tagLength); 00955 00956 memcpy((*tdpos).second, tag_data, tinfo->tagLength); 00957 } 00958 else { 00959 // should shallow copy; might have to delete what's there already 00960 if ((*tdpos).second != NULL) free((*tdpos).second); 00961 00962 // if shallow copying, caller is saying we can copy, so cast away const 00963 (*tdpos).second = const_cast<void*>(tag_data); 00964 } 00965 00966 RETURN(iBase_SUCCESS); 00967 } 00968 00969 void CATag::remove_tag(long tag_handle) 00970 { 00971 tagData.erase(tag_handle); 00972 } 00973 00974 CubitStatus CATag::update() 00975 { 00976 if (tagData.empty()) 00977 this->delete_attrib(true); 00978 00979 return CUBIT_SUCCESS; 00980 }