cgma
CATag.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines