cgma
|
00001 //- Class: CAGroup 00002 //- Owner: Greg Nielson 00003 //- Description: Cubit Attribute for groups. 00004 //- Checked By: 00005 //- Version: 00006 00007 #include "CAGroup.hpp" 00008 #include "RefEntity.hpp" 00009 #include "RefEntityFactory.hpp" 00010 #include "RefGroup.hpp" 00011 #include "CubitObserver.hpp" 00012 #include "DLIList.hpp" 00013 #include "CastTo.hpp" 00014 #include "TDCAGE.hpp" 00015 #include "GeometryQueryTool.hpp" 00016 00017 #include <stdlib.h> 00018 #include <time.h> 00019 00020 // initialize this CA's static members 00021 CubitBoolean CAGroup::initialize_rand = CUBIT_TRUE; 00022 00023 CubitAttrib* CAGroup_creator(RefEntity* entity, const CubitSimpleAttrib &p_csa) 00024 { 00025 return new CAGroup(entity, p_csa); 00026 } 00027 00028 CAGroup::CAGroup(RefEntity* new_attrib_owner, 00029 const CubitSimpleAttrib& csa_ptr) 00030 : CubitAttrib(new_attrib_owner) 00031 { 00032 00033 initialize(); 00034 00035 if(!csa_ptr.isEmpty()) 00036 { 00037 00038 const std::vector<int>& i_list = csa_ptr.int_data_list(); 00039 const std::vector<CubitString>& cs_list = csa_ptr.string_data_list(); 00040 00041 // first, the ints 00042 00043 int offset = 0; 00044 int num_groups = i_list[offset++]; 00045 00046 // groupID 00047 int i; 00048 for (i = num_groups; i > 0; i--) 00049 groupID.append(i_list[offset++]); 00050 00051 // uniqueID 00052 for (i = num_groups; i > 0; i--) 00053 uniqueID.append(i_list[offset++]); 00054 00055 // sequenceNumbers 00056 for (i = num_groups; i > 0; i--) 00057 sequenceNumbers.append(i_list[offset++]); 00058 00059 // numOwningGroups 00060 for (i = num_groups; i > 0; i--) 00061 numOwningGroups.append(i_list[offset++]); 00062 00063 // total number of owning groups 00064 int total_owning_groups = i_list[offset++]; 00065 00066 // owningGroupID 00067 for (i = total_owning_groups; i > 0; i--) 00068 owningGroupID.append(i_list[offset++]); 00069 00070 // owningUniqueID 00071 for (i = total_owning_groups; i > 0; i--) 00072 owningUniqueID.append(i_list[offset++]); 00073 00074 // owningSequenceNumbers 00075 for (i = total_owning_groups; i > 0; i--) 00076 owningSequenceNumbers.append(i_list[offset++]); 00077 00078 // ancestor groups added after first implementation of CAGroup, 00079 // therefore not all attributes may have ancestor groups 00080 // setting total_ancestor_groups to zero first will short-circuit 00081 // loops below if there aren't any ancestor groups, so no need for 00082 // an 'if' statement 00083 00084 // total number of ancestor groups 00085 int total_ancestor_groups = 0; 00086 00087 if (i_list.size() > (size_t)(4*num_groups + 3*total_owning_groups + 2)) 00088 total_ancestor_groups = i_list[offset++]; 00089 00090 // ancestorGroupID 00091 for (i = total_ancestor_groups; i > 0; i--) 00092 ancestorGroupID.append(i_list[offset++]); 00093 00094 // ancestorUniqueID 00095 for (i = total_ancestor_groups; i > 0; i--) 00096 ancestorUniqueID.append(i_list[offset++]); 00097 00098 // ancestorOwnedGroupUid 00099 for (i = total_ancestor_groups; i > 0; i--) 00100 ancestorOwnedGroupUid.append(i_list[offset++]); 00101 00102 // ancestorSequenceNumbers 00103 for (i = total_ancestor_groups; i > 0; i--) 00104 ancestorSequenceNumbers.append(i_list[offset++]); 00105 00106 // now, doubles (none) 00107 00108 // now, strings 00109 // attribute internal name (just pop the list) 00110 offset = 1; 00111 00112 // groupNames 00113 for (i = num_groups; i > 0; i--) 00114 groupNames.append(cs_list[offset++]); 00115 00116 // owningGroupNames 00117 for (i = total_owning_groups; i > 0; i--) 00118 owningGroupNames.append(cs_list[offset++]); 00119 00120 // ancestorGroupName 00121 for (i = total_ancestor_groups; i > 0; i--) 00122 ancestorGroupName.append(cs_list[offset++]); 00123 00124 // ok, we're done 00125 } 00126 } 00127 00128 CAGroup::~CAGroup() 00129 { 00130 } 00131 00132 void CAGroup::initialize() 00133 { 00134 if(initialize_rand == CUBIT_TRUE) 00135 { 00136 #if defined _WIN32 || defined CUBIT_LINUX 00137 srand((unsigned)time(NULL)); 00138 #else 00139 srand48(time(NULL)); 00140 #endif 00141 initialize_rand = CUBIT_FALSE; 00142 } 00143 } 00144 00145 00146 00147 CubitStatus CAGroup::actuate() 00148 { 00149 if (hasActuated == CUBIT_TRUE) return CUBIT_SUCCESS; 00150 00151 // need to reset all the lists to keep them in sync 00152 groupID.reset(); 00153 uniqueID.reset(); 00154 groupNames.reset(); 00155 sequenceNumbers.reset(); 00156 owningGroupID.reset(); 00157 owningUniqueID.reset(); 00158 owningGroupNames.reset(); 00159 owningSequenceNumbers.reset(); 00160 numOwningGroups.reset(); 00161 00162 // go through all the groups on this CA 00163 int i; 00164 for (i = groupID.size(); i > 0; i--) { 00165 // pop the data for this group off the lists 00166 int group_id = groupID.get_and_step(); 00167 int unique_id = uniqueID.get_and_step(); 00168 CubitString group_name = groupNames.get_and_step(); 00169 int seq_num = sequenceNumbers.get_and_step(); 00170 00171 RefGroup *ref_group = 00172 assign_group(attribOwnerEntity, group_id, unique_id, 00173 group_name, seq_num); 00174 00175 00176 // check for groups owning this group 00177 int owning_groups = numOwningGroups.get_and_step(); 00178 00179 for (int j = owning_groups; j > 0; j--) 00180 { 00181 int owning_group_id = owningGroupID.get_and_step(); 00182 int owning_unique_id = owningUniqueID.get_and_step(); 00183 CubitString owning_group_name = owningGroupNames.get_and_step(); 00184 seq_num = owningSequenceNumbers.get_and_step(); 00185 00186 assign_group(ref_group, owning_group_id, owning_unique_id, 00187 owning_group_name, seq_num); 00188 } 00189 00190 } // loop over all groups in this CAGroup 00191 00192 // now do ancestors 00193 ancestorGroupID.reset(); 00194 ancestorUniqueID.reset(); 00195 ancestorOwnedGroupUid.reset(); 00196 ancestorGroupName.reset(); 00197 ancestorSequenceNumbers.reset(); 00198 00199 for (i = ancestorGroupID.size(); i > 0; i--) { 00200 /*RefGroup *ancestor_group = */ 00201 assign_ancestor_group(ancestorGroupID.get_and_step(), 00202 ancestorUniqueID.get_and_step(), 00203 ancestorGroupName.get_and_step(), 00204 ancestorOwnedGroupUid.get_and_step(), 00205 ancestorSequenceNumbers.get_and_step()); 00206 } 00207 00208 deleteAttrib = CUBIT_TRUE; 00209 hasActuated = CUBIT_TRUE; 00210 00211 return CUBIT_SUCCESS; 00212 } 00213 00214 RefGroup *CAGroup::assign_group(RefEntity *owned_entity, 00215 const int group_id, const int unique_id, 00216 const CubitString& group_name, 00217 const int seq_num) 00218 { 00219 RefGroup* parent_group = NULL; 00220 CubitBoolean group_id_exists = CUBIT_FALSE; 00221 00222 // search for the group corresponding to this id and unique id 00223 RefGroup *ref_group = GeometryQueryTool::instance()->get_last_ref_group(); 00224 for(int i = GeometryQueryTool::instance()->num_ref_groups(); i > 0 && !parent_group; i--) 00225 { 00226 ref_group = GeometryQueryTool::instance()->get_next_ref_group(); 00227 if(ref_group->id() == group_id) 00228 { 00229 group_id_exists = CUBIT_TRUE; 00230 } 00231 00232 ToolData *td_temp = ref_group->get_TD(&TDCAGE::is_cage); 00233 TDCAGE *td_cagroup = (td_temp ? CAST_TO(td_temp, TDCAGE) : NULL); 00234 if (td_cagroup != NULL && td_cagroup->unique_id() == unique_id) 00235 parent_group = ref_group; 00236 } 00237 00238 if(!parent_group) 00239 { 00240 // else make a new group, and assign id and unique id 00241 // also assign group name 00242 parent_group = RefEntityFactory::instance()->construct_RefGroup(); 00243 if(!group_id_exists) { 00244 parent_group->set_id(0); 00245 parent_group->set_id(group_id); 00246 } 00247 else 00248 PRINT_INFO("Creating group %d to hold attribute group %d\n", 00249 parent_group->id(), group_id); 00250 00251 // put a td on this new group with the right unique_id 00252 TDCAGE *td_cagroup = new TDCAGE(unique_id); 00253 parent_group->add_TD(td_cagroup); 00254 00255 // add the attribOwnerEntity to the group and name the group 00256 parent_group->entity_name(group_name); 00257 } 00258 00259 // add the entity to the group with the proper sequence number 00260 TDCAGE::insert_entity(owned_entity, seq_num, parent_group); 00261 00262 return parent_group; 00263 } 00264 00265 RefGroup *CAGroup::assign_ancestor_group(const int ancestor_id, 00266 const int ancestor_uid, 00267 const CubitString& ancestor_name, 00268 const int owned_group_uid, 00269 const int seq_num) 00270 { 00271 // for each call of this function, we: 00272 // - get an ancestor group with ancestor_id, ancestor_uid and 00273 // ancestor_name (make one if it doesn't exist) 00274 // - add group with owned_group_uid to that ancestor group 00275 // (owned_group_uid should exist, error if not) 00276 // search for the group corresponding to this id and unique id 00277 RefGroup* ancestor_group = NULL; 00278 RefGroup *owned_group = NULL; 00279 CubitBoolean ancestor_id_exists = CUBIT_FALSE; 00280 00281 RefGroup *ref_group = GeometryQueryTool::instance()->get_last_ref_group(); 00282 00283 for(int i = GeometryQueryTool::instance()->num_ref_groups(); i > 0 && 00284 (!ancestor_group || !owned_group); i--) 00285 { 00286 ref_group = GeometryQueryTool::instance()->get_next_ref_group(); 00287 00288 if(ref_group->id() == ancestor_id) 00289 { 00290 ancestor_id_exists = CUBIT_TRUE; 00291 } 00292 00293 ToolData *td_temp = ref_group->get_TD(&TDCAGE::is_cage); 00294 TDCAGE *td_cagroup = (td_temp ? CAST_TO(td_temp, TDCAGE) : NULL); 00295 if (td_cagroup != NULL && td_cagroup->unique_id() == ancestor_uid) { 00296 ancestor_group = ref_group; 00297 } 00298 00299 if (td_cagroup != NULL && td_cagroup->unique_id() == owned_group_uid) { 00300 owned_group = ref_group; 00301 } 00302 } 00303 00304 assert(owned_group != 0); 00305 00306 if (!ancestor_group) 00307 { 00308 // make a new group, and assign id and unique id 00309 // also assign group name 00310 ancestor_group = RefEntityFactory::instance()->construct_RefGroup(); 00311 ; 00312 if(!ancestor_id_exists) { 00313 ancestor_group->set_id(0); 00314 ancestor_group->set_id(ancestor_id); 00315 } 00316 else 00317 PRINT_INFO("Creating group %d to hold attribute group %d\n", 00318 ancestor_group->id(), ancestor_id); 00319 00320 // put a td on this new group with the right unique_id 00321 TDCAGE *td_cagroup = new TDCAGE(ancestor_uid); 00322 ancestor_group->add_TD(td_cagroup); 00323 00324 // add the owned group to the group and name the group 00325 ancestor_group->entity_name(ancestor_name); 00326 } 00327 00328 // add the entity to the group with the proper sequence number 00329 TDCAGE::insert_entity(owned_group, seq_num, ancestor_group); 00330 00331 return ancestor_group; 00332 } 00333 00334 CubitStatus CAGroup::update() 00335 { 00336 if (hasUpdated) return CUBIT_SUCCESS; 00337 00338 // set the updated flag 00339 hasUpdated = CUBIT_TRUE; 00340 00341 // get the groups containing attribOwnerEntity 00342 RefGroup* ref_group; 00343 DLIList<RefGroup*> ref_group_list; 00344 int i; 00345 00346 RefGroup::get_groups_within(attribOwnerEntity, ref_group_list, CUBIT_FALSE); 00347 00348 if( ref_group_list.size() == 0) 00349 { 00350 delete_attrib(CUBIT_TRUE); 00351 return CUBIT_SUCCESS; 00352 } 00353 00354 // else, this entity is owned by groups 00355 RefGroup* parent_ref_group; 00356 00357 // get a td_cage onto the attribOwnerEntity, to keep sequence numbers 00358 // for the owning groups 00359 TDCAGE *td_entity = (TDCAGE *) attribOwnerEntity->get_TD(&TDCAGE::is_cage); 00360 if (!td_entity) { 00361 td_entity = new TDCAGE(-1); 00362 attribOwnerEntity->add_TD(td_entity); 00363 } 00364 00365 // now, initialize that tdcage 00366 td_entity->initialize_group_sequence_list(attribOwnerEntity); 00367 00368 // ok, now write the data for the groups to this attribute 00369 for(i = ref_group_list.size(); i > 0; i--) 00370 { 00371 // get the refgroup which gets assigned to this CAGroup 00372 ref_group = ref_group_list.get_and_step(); 00373 00374 // First, make sure there's a TDCAGE on the RefGroup 00375 ToolData *td_temp = ref_group->get_TD(&TDCAGE::is_cage); 00376 TDCAGE *td_cagroup = (td_temp ? CAST_TO(td_temp, TDCAGE) : NULL); 00377 if (td_cagroup == NULL) { 00378 #if defined _WIN32 || defined CUBIT_LINUX 00379 td_cagroup = new TDCAGE(rand()); 00380 #else 00381 td_cagroup = new TDCAGE((int)lrand48()); 00382 #endif 00383 ref_group->add_TD(td_cagroup); 00384 td_cagroup->initialize_group_sequence_list(ref_group); 00385 } 00386 00387 // append to this CAGroup the id and the unique id of the group; 00388 // also append the group name 00389 groupID.append(ref_group->id()); 00390 uniqueID.append(td_cagroup->unique_id()); 00391 groupNames.append(ref_group->entity_name()); 00392 00393 // get and append the sequence number of the attribOwnerEntity 00394 // in this group 00395 int seq_number = td_entity->td_sequence_number(ref_group); 00396 assert(seq_number != -1); 00397 sequenceNumbers.append(seq_number); 00398 00399 // check this group for containing (parent) groups 00400 DLIList<RefGroup*> parent_ref_group_list; 00401 RefGroup::get_groups_within(ref_group, parent_ref_group_list, CUBIT_FALSE); 00402 00403 // append the number of parent groups to the right list 00404 numOwningGroups.append(parent_ref_group_list.size()); 00405 00406 // for each parent group, do essentially the same thing, adding the 00407 // data to the owningGroup lists 00408 for(int j = parent_ref_group_list.size(); j>0; j--) 00409 { 00410 parent_ref_group = parent_ref_group_list.get_and_step(); 00411 td_temp = parent_ref_group->get_TD(&TDCAGE::is_cage); 00412 TDCAGE *td_parent = (td_temp ? CAST_TO(td_temp, TDCAGE) : NULL); 00413 if (td_parent == NULL) { 00414 #if defined _WIN32 || defined CUBIT_LINUX 00415 td_parent = new TDCAGE(rand()); 00416 #else 00417 td_parent = new TDCAGE((int)lrand48()); 00418 #endif 00419 parent_ref_group->add_TD(td_parent); 00420 td_parent->initialize_group_sequence_list(parent_ref_group); 00421 } 00422 00423 // append to this CAGroup the id and the unique id of the group; 00424 // also append the group name 00425 owningGroupID.append(parent_ref_group->id()); 00426 owningUniqueID.append(td_parent->unique_id()); 00427 owningGroupNames.append(parent_ref_group->entity_name()); 00428 00429 // get and append the sequence number of the group in the parent 00430 // group 00431 seq_number = td_cagroup->td_sequence_number(parent_ref_group); 00432 assert(seq_number != -1); 00433 owningSequenceNumbers.append(seq_number); 00434 00435 // finally, build a list of distant ancestors, in case there are 00436 // groups more than twice removed from any real entities; make 00437 // it a recursive function, so that it goes all the way up the chain 00438 // of ancestors 00439 build_ancestor_list(parent_ref_group); 00440 00441 } // loop over parent groups 00442 } // loop over groups containing attribOwnerEntity 00443 00444 return CUBIT_SUCCESS; 00445 } 00446 00447 CubitStatus CAGroup::reset() 00448 { 00449 groupID.clean_out(); 00450 //- group ids containing attribOwnerEntity 00451 00452 uniqueID.clean_out(); 00453 //- unique ids of groups containing attribOwnerEntity 00454 00455 groupNames.clean_out(); 00456 //- names of groups containing attribOwnerEntity 00457 00458 sequenceNumbers.clean_out(); 00459 //- sequence numbers of this entity in the groups 00460 00461 numOwningGroups.clean_out(); 00462 //- for each group in groupID, number of groups owning those groups 00463 00464 owningGroupID.clean_out(); 00465 //- group ids containing groups containing attribOwnerEntity 00466 00467 owningUniqueID.clean_out(); 00468 //- unique ids of groups containing groups containing attribOwnerEntity 00469 00470 owningGroupNames.clean_out(); 00471 //- names of groups containing groups containing attribOwnerEntity 00472 00473 owningSequenceNumbers.clean_out(); 00474 //- sequence numbers of groups in owning groups 00475 00476 //- for each ancestor (a group which owns only other groups, with those 00477 //- those groups owning only other groups), we store the group id, uid, 00478 //- name, and the uid of the owned group to which this is an ancestor 00479 ancestorGroupID.clean_out(); 00480 ancestorUniqueID.clean_out(); 00481 ancestorGroupName.clean_out(); 00482 ancestorOwnedGroupUid.clean_out(); 00483 ancestorSequenceNumbers.clean_out(); 00484 00485 return CUBIT_SUCCESS; 00486 } 00487 00488 void CAGroup::build_ancestor_list(RefGroup *parent_ref_group) 00489 { 00490 DLIList<RefGroup*> ancestor_ref_group_list; 00491 RefGroup::get_groups_within(parent_ref_group, ancestor_ref_group_list, CUBIT_FALSE); 00492 00493 // now, recursively work on ancestor list, adding owning group id, 00494 // uid and name, and owned group uid, to lists 00495 ToolData *td_temp = parent_ref_group->get_TD(&TDCAGE::is_cage); 00496 TDCAGE *td_parent = (td_temp ? CAST_TO(td_temp, TDCAGE) : NULL); 00497 00498 for (int j = ancestor_ref_group_list.size(); j > 0; j--) { 00499 RefGroup *ancestor = ancestor_ref_group_list.get_and_step(); 00500 td_temp = ancestor->get_TD(&TDCAGE::is_cage); 00501 TDCAGE *td_cagroup = (td_temp ? CAST_TO(td_temp, TDCAGE) : NULL); 00502 if (td_cagroup == NULL) { 00503 #if defined _WIN32 || defined CUBIT_LINUX 00504 td_cagroup = new TDCAGE(rand()); 00505 #else 00506 td_cagroup = new TDCAGE((int)lrand48()); 00507 #endif 00508 ancestor->add_TD(td_cagroup); 00509 td_cagroup->initialize_group_sequence_list(ancestor); 00510 } 00511 00512 ancestorGroupID.append(ancestor->id()); 00513 ancestorUniqueID.append(td_cagroup->unique_id()); 00514 ancestorGroupName.append(ancestor->entity_name()); 00515 ancestorOwnedGroupUid.append(td_parent->unique_id()); 00516 00517 // get and append the sequence number of the group in the parent 00518 // group 00519 int seq_number = td_parent->td_sequence_number(ancestor); 00520 assert(seq_number != -1); 00521 ancestorSequenceNumbers.append(seq_number); 00522 00523 build_ancestor_list(ancestor); 00524 } 00525 } 00526 00527 CubitSimpleAttrib CAGroup::cubit_simple_attrib() 00528 { 00529 std::vector<CubitString> cs_list; 00530 std::vector<double> d_list; 00531 std::vector<int> i_list; 00532 00533 // first, the ints 00534 // groupID 00535 groupID.reset(); 00536 i_list.push_back(groupID.size()); 00537 int i; 00538 for (i = groupID.size(); i > 0; i--) 00539 i_list.push_back(groupID.get_and_step()); 00540 00541 // uniqueID 00542 uniqueID.reset(); 00543 for (i = uniqueID.size(); i > 0; i--) 00544 i_list.push_back(uniqueID.get_and_step()); 00545 00546 // sequenceNumbers 00547 sequenceNumbers.reset(); 00548 for (i = sequenceNumbers.size(); i > 0; i--) 00549 i_list.push_back(sequenceNumbers.get_and_step()); 00550 00551 // numOwningGroups 00552 numOwningGroups.reset(); 00553 for (i = numOwningGroups.size(); i > 0; i--) 00554 i_list.push_back(numOwningGroups.get_and_step()); 00555 00556 // size of owningGroupID 00557 i_list.push_back(owningGroupID.size()); 00558 00559 // owningGroupID 00560 owningGroupID.reset(); 00561 for (i = owningGroupID.size(); i > 0; i--) 00562 i_list.push_back(owningGroupID.get_and_step()); 00563 00564 // owningUniqueID 00565 owningUniqueID.reset(); 00566 for (i = owningUniqueID.size(); i > 0; i--) 00567 i_list.push_back(owningUniqueID.get_and_step()); 00568 00569 // owningSequenceNumbers 00570 owningSequenceNumbers.reset(); 00571 for (i = owningSequenceNumbers.size(); i > 0; i--) 00572 i_list.push_back(owningSequenceNumbers.get_and_step()); 00573 00574 // size of ancestorGroupID 00575 i_list.push_back(ancestorGroupID.size()); 00576 00577 // ancestorGroupID 00578 ancestorGroupID.reset(); 00579 for (i = ancestorGroupID.size(); i > 0; i--) 00580 i_list.push_back(ancestorGroupID.get_and_step()); 00581 00582 // ancestorUniqueID 00583 ancestorUniqueID.reset(); 00584 for (i = ancestorUniqueID.size(); i > 0; i--) 00585 i_list.push_back(ancestorUniqueID.get_and_step()); 00586 00587 // ancestorOwnedGroupUid 00588 ancestorOwnedGroupUid.reset(); 00589 for (i = ancestorOwnedGroupUid.size(); i > 0; i--) 00590 i_list.push_back(ancestorOwnedGroupUid.get_and_step()); 00591 00592 // ancestorSequenceNumbers 00593 ancestorSequenceNumbers.reset(); 00594 for (i = ancestorSequenceNumbers.size(); i > 0; i--) 00595 i_list.push_back(ancestorSequenceNumbers.get_and_step()); 00596 00597 // now, doubles (none) 00598 00599 // now, strings 00600 // attribute internal name 00601 cs_list.push_back(att_internal_name()); 00602 00603 // groupNames 00604 groupNames.reset(); 00605 for (i = groupID.size(); i > 0; i--) 00606 cs_list.push_back(groupNames.get_and_step()); 00607 00608 // owningGroupNames 00609 owningGroupNames.reset(); 00610 for (i = owningGroupNames.size(); i > 0; i--) 00611 cs_list.push_back(owningGroupNames.get_and_step()); 00612 00613 // ancestorGroupName 00614 ancestorGroupName.reset(); 00615 for (i = ancestorGroupName.size(); i > 0; i--) 00616 cs_list.push_back(ancestorGroupName.get_and_step()); 00617 00618 return CubitSimpleAttrib(&cs_list, &d_list, &i_list); 00619 } 00620 00621 void CAGroup::has_written(CubitBoolean has_written) 00622 { 00623 //- overloaded has_written function, resets td_cage on owner 00624 if (has_written == CUBIT_TRUE && hasWritten == CUBIT_FALSE) 00625 // reset the td_cage on the owner 00626 attribOwnerEntity->delete_TD(&TDCAGE::is_cage); 00627 00628 hasWritten = has_written; 00629 }