cgma
|
00001 //-- File: RefGroup.cc 00002 00003 #include <stdio.h> 00004 #include <string.h> 00005 #include <assert.h> 00006 00007 #include "RefGroup.hpp" 00008 #include "CubitObservable.hpp" 00009 #include "CubitBox.hpp" 00010 #include "DLIList.hpp" 00011 #include "CastTo.hpp" 00012 #include "GeometryQueryTool.hpp" 00013 #include "RefEntityFactory.hpp" 00014 #include "AppUtil.hpp" 00015 #include "GeometryEvent.hpp" 00016 00017 RefGroup::RefGroup( const char* name, int id) 00018 { 00019 recursionMark = 0; 00020 00021 if( id == 0 ) 00022 entityId = RefEntityFactory::instance()->next_ref_group_id(); 00023 else 00024 entityId = id; 00025 00026 // assign default names 00027 assign_default_name(); 00028 00029 if (name != NULL) 00030 entity_name( name ); 00031 } 00032 00033 RefGroup::RefGroup (DLIList<RefEntity*>& entity_list) 00034 { 00035 recursionMark = 0; 00036 //entityList = entity_list; 00037 int i; 00038 for ( i = entity_list.size(); i > 0; i-- ) 00039 { 00040 RefEntity *ent_ptr = entity_list.get_and_step(); 00041 if ( !entityList.move_to(ent_ptr) ) 00042 entityList.append(ent_ptr); 00043 } 00044 entityList.reset(); 00045 for (i=entityList.size(); i > 0; i--) 00046 register_observable(entityList.get_and_step()); 00047 00048 entityId = RefEntityFactory::instance()->next_ref_group_id(); 00049 00050 // Notify Model about the creation of this object 00051 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_ENTITY_CONSTRUCTED, this)) ; 00052 00053 // assign default names 00054 assign_default_name(); 00055 00056 } 00057 00058 RefGroup::RefGroup(int /*proe_type*/) 00059 { 00060 // This constructor was created just to get around not doing a notify, 00061 // so we can use it for Pro/E parts and assemblies. 00062 recursionMark = 0; 00063 } 00064 00065 RefGroup::~RefGroup () 00066 { 00067 remove_all_ref_entities(); 00068 } 00069 00070 CubitStatus RefGroup::add_ref_entity(RefEntity *ref_entity, bool emit_event) 00071 { 00072 CubitStatus status = CUBIT_FAILURE; 00073 00074 // Force failure of commands like: group 3 add group 3 00075 if ( ( ref_entity->entity_type_info() == entity_type_info() ) && 00076 ( ref_entity->entity_name() == entity_name() ) ) 00077 return CUBIT_FAILURE; 00078 00079 if (!entityList.move_to(ref_entity)) 00080 { 00081 entityList.append(ref_entity); 00082 register_observable(ref_entity); 00083 status = CUBIT_SUCCESS; 00084 if (emit_event) 00085 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GROUP_MODIFIED, this)); 00086 } 00087 return status; 00088 } 00089 00090 CubitStatus RefGroup::add_ref_entity(DLIList<RefEntity*>& entity_list, 00091 bool emit_event) 00092 { 00093 RefEntity* entity = NULL; 00094 CubitStatus status = CUBIT_FAILURE; 00095 for (int i=entity_list.size(); i > 0; i--) 00096 { 00097 entity = entity_list.get_and_step(); 00098 if ( entityList.move_to(entity) == CUBIT_FALSE ) 00099 { 00100 entityList.append(entity); 00101 register_observable(entity); 00102 status = CUBIT_SUCCESS; 00103 } 00104 } 00105 00106 if (emit_event && status == CUBIT_SUCCESS) 00107 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GROUP_MODIFIED, this)); 00108 00109 return status; 00110 } 00111 00112 CubitStatus RefGroup::remove_ref_entity(RefEntity *entity, 00113 bool emit_event) 00114 { 00115 CubitStatus status = CUBIT_FAILURE; 00116 if (entityList.remove(entity)) { 00117 unregister_observable(entity); 00118 status = CUBIT_SUCCESS; 00119 if (emit_event) 00120 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GROUP_MODIFIED, this)); 00121 } 00122 return status; 00123 } 00124 00125 CubitStatus RefGroup::remove_ref_entity(DLIList<RefEntity*> &entity_list, 00126 bool emit_event) 00127 { 00128 00129 int i; 00130 RefEntity *entity; 00131 CubitStatus status = CUBIT_FAILURE; 00132 for (i = entity_list.size(); i > 0; i--) { 00133 entity = entity_list.get_and_step(); 00134 if (entityList.remove(entity)) { 00135 unregister_observable(entity); 00136 status = CUBIT_SUCCESS; 00137 } 00138 } 00139 00140 if (emit_event && status == CUBIT_SUCCESS) 00141 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::GROUP_MODIFIED, this)); 00142 00143 return status; 00144 } 00145 00146 int RefGroup::remove_all_ref_entities() 00147 { 00148 int num_entities = entityList.size(); 00149 for (int i=entityList.size(); i > 0; i--) { 00150 unregister_observable(entityList.get_and_step()); 00151 } 00152 entityList.clean_out(); 00153 return num_entities; 00154 } 00155 00156 void RefGroup::get_child_ref_entities(DLIList<RefEntity*>& entity_list) 00157 { 00158 entityList.reset(); 00159 entity_list.merge_unique(entityList, CUBIT_TRUE ); 00160 } 00161 00162 int RefGroup::get_num_child_ref_entities_by_type(const std::type_info &entity_type) 00163 { 00164 int count = 0; 00165 int size = entityList.size(); 00166 for(int i=0; i<size; i++) 00167 { 00168 RefEntity *cur_ent = entityList[i]; 00169 if(cur_ent->entity_type_info() == entity_type) 00170 count++; 00171 } 00172 return count; 00173 } 00174 00175 RefEntity* RefGroup::get_child_ref_entity_by_index(const std::type_info& entity_type, int index) 00176 { 00177 RefEntity *entity = NULL; 00178 int size = entityList.size(); 00179 int type_index = 0; 00180 for(int i=0; i<size && !entity; i++) 00181 { 00182 RefEntity *cur_ent = entityList[i]; 00183 if(cur_ent->entity_type_info() == entity_type) 00184 { 00185 if(type_index == index) 00186 entity = cur_ent; 00187 else 00188 type_index++; 00189 } 00190 } 00191 return entity; 00192 } 00193 00194 void RefGroup::get_child_entities(DLIList<CubitEntity*>& cub_entity_list) 00195 { 00196 cub_entity_list.casting_merge_unique(entityList, CUBIT_TRUE); 00197 } 00198 00199 void RefGroup::expand_group( DLIList<RefEntity*> & entity_list ) 00200 { 00201 //This function will get the list of child entities for this group and 00202 //if there are any groups in its child list, it will call this fucntion 00203 //again on those groups. The end result should be that the returned 00204 //list does not contain groups... just basic_topology entities 00205 //(the other ref_entities) 00206 DLIList<RefEntity*> group_list, mixed_list; 00207 RefEntity *ref_entity_ptr; 00208 RefGroup *group; 00209 mixed_list.append( this ); 00210 00211 // don't swap the upper and lower bounds on ii. 00212 for ( int ii = 0; ii < mixed_list.size(); ii++ ) 00213 { 00214 //Note, the list gets added to, so don't do a simple get_and_step 00215 mixed_list.reset(); 00216 mixed_list.step(ii); 00217 ref_entity_ptr = mixed_list.get(); 00218 00219 group = CAST_TO( ref_entity_ptr, RefGroup ); 00220 if (group) 00221 { 00222 // avoid infinite recursion of groups A and B containing each other 00223 if (!group_list.move_to(group)) { 00224 group->get_child_ref_entities(mixed_list); 00225 group_list.append(group); 00226 } 00227 } 00228 // In the future if we have other RefEntities that are grouping 00229 // entities then we should have another statement here... 00230 else 00231 entity_list.append( ref_entity_ptr ); 00232 } 00233 00234 return; 00235 } 00236 00237 void RefGroup::get_parent_ref_entities(DLIList<RefEntity*>&) 00238 { 00239 //- appends all ref entities that own this to entity_list. 00240 //- Goes up just one dimension. 00241 // There is nothing above us. Do nothing 00242 } 00243 00244 int RefGroup::maximum_dimension() 00245 { 00246 recursionMark = 1; 00247 // This routine returns the maximum dimension of its owned subentities. 00248 // The 'only' kludge is that if one of its subentities is a RefGroup, it 00249 // must call 'maximum_dimension' on that entity instead of dimension(). 00250 00251 RefEntity *entity; 00252 int test_dim = 0; 00253 int dimension = 0; 00254 00255 for (int i = entityList.size(); i > 0; i--) 00256 { 00257 entity = entityList.get_and_step(); 00258 RefGroup* group; 00259 if ( (group = CAST_TO(entity,RefGroup) ) != NULL ) 00260 { 00261 if (group->recursionMark == 0) 00262 test_dim = group->maximum_dimension(); 00263 } 00264 else 00265 { 00266 test_dim = entity->dimension(); 00267 } 00268 dimension = CUBIT_MAX(dimension, test_dim); 00269 } 00270 recursionMark = 0; 00271 return dimension; 00272 } 00273 00274 CubitBox RefGroup::bounding_box() 00275 { 00276 recursionMark = 1; 00277 00278 CubitBox super_box = CubitBox(); 00279 int super_box_defined = CUBIT_FALSE; 00280 00281 for (int i = entityList.size(); i > 0; i--) { 00282 00283 RefEntity *entity = entityList.get_and_step(); 00284 RefGroup *group = CAST_TO(entity, RefGroup); 00285 if (!group || group->recursionMark == 0) { 00286 CubitBox entity_box = entity->bounding_box(); 00287 00288 // "Concatenate" this box with the super_box, creating a bounding 00289 // box that bounds the entities (from the list), processed so far. 00290 if (super_box_defined) 00291 super_box |= entity_box; 00292 else { 00293 super_box = entity_box; 00294 super_box_defined = CUBIT_TRUE; 00295 } 00296 } 00297 } 00298 recursionMark = 0; 00299 00300 return super_box; 00301 } 00302 00303 void RefGroup::get_sub_entities(DLIList<RefEntity*> &entity_list) 00304 { 00305 recursionMark = 1; 00306 00307 //- appends all ref entities owned by this entity on entity_list 00308 //- and recurses all the way down to dimension 0 00309 DLIList<RefEntity*> local_entity_list; 00310 get_child_ref_entities(local_entity_list); 00311 00312 // *need* to merge now if a group 00313 // else more efficient to merge later 00314 entity_list.merge_unique(local_entity_list, CUBIT_TRUE); 00315 DLIList<RefEntity*> temp_list, temp_list2; 00316 00317 00318 for (int i=local_entity_list.size(); i > 0; i--) { 00319 // take some care to avoid infinite recursion 00320 RefEntity *child = local_entity_list.get_and_step(); 00321 RefGroup *group = CAST_TO(child, RefGroup); 00322 if (!group || group->recursionMark == 0) { 00323 temp_list2.clean_out(); 00324 child->get_all_child_ref_entities(temp_list2); 00325 temp_list.merge_unique(temp_list2); 00326 } 00327 } 00328 00329 entity_list.merge_unique(temp_list); 00330 recursionMark = 0; 00331 } 00332 00333 void RefGroup::is_mergeable(AutoMergeStatus val) 00334 { 00335 recursionMark = 1; 00336 autoMergeStatus = val; 00337 DLIList<RefEntity*> children; 00338 get_child_ref_entities( children ); 00339 for ( int i = children.size(); i > 0; i-- ) { 00340 RefEntity *child = children.get_and_step(); 00341 RefGroup *group = CAST_TO(child, RefGroup); 00342 if (!group || group->recursionMark == 0) 00343 child->is_mergeable(val); 00344 } 00345 recursionMark = 0; 00346 } 00347 00348 CubitVector RefGroup::center_point() 00349 { return bounding_box().center(); } 00350 00351 00352 int RefGroup::subtract(RefGroup *group_to_subtract, RefGroup *target_group) 00353 { 00354 // Get the list of RefEntities associated with each group 00355 DLIList<RefEntity*> final_list; 00356 DLIList<RefEntity*> entity_list_2; 00357 00358 get_child_ref_entities(final_list); 00359 group_to_subtract->get_child_ref_entities(entity_list_2); 00360 00361 // At this point, we have three groups, all non-null. Note that 00362 // some or all of these may be the same group, so don't destroy 00363 // the target group until all information is generated. 00364 00365 // 1. Final = group 2 00366 // 2. Remove from final all items that are in both final and group 1 00367 for (int i=entity_list_2.size(); i > 0; i--) { 00368 RefEntity *entity = entity_list_2.get_and_step(); 00369 final_list.remove(entity); 00370 } 00371 00372 target_group->remove_all_ref_entities(); 00373 target_group->add_ref_entity(final_list); 00374 00375 return CUBIT_SUCCESS; 00376 } 00377 00378 int RefGroup::intersect(RefGroup *other_group, RefGroup *target_group) 00379 { 00380 // Get the list of RefEntities associated with each group 00381 DLIList<RefEntity*> entity_list_1; 00382 DLIList<RefEntity*> entity_list_2; 00383 00384 get_child_ref_entities(entity_list_1); 00385 other_group->get_child_ref_entities(entity_list_2); 00386 00387 DLIList<RefEntity*> final_list; 00388 00389 // At this point, we have three groups, all non-null. Note that 00390 // some or all of these may be the same group, so don't destroy 00391 // the target group until all information is generated. 00392 00393 // Final = all items in both group 1 and group 2. 00394 for (int i=entity_list_2.size(); i > 0; i--) { 00395 RefEntity *entity = entity_list_2.get_and_step(); 00396 if (entity_list_1.move_to(entity)) { 00397 final_list.append_unique(entity); 00398 } 00399 } 00400 00401 target_group->remove_all_ref_entities(); 00402 target_group->add_ref_entity(final_list); 00403 00404 return CUBIT_SUCCESS; 00405 } 00406 00407 int RefGroup::unite(RefGroup *other_group, RefGroup *target_group) 00408 { 00409 // Get the list of RefEntities associated with each group 00410 DLIList<RefEntity*> final_list; 00411 DLIList<RefEntity*> entity_list_2; 00412 00413 get_child_ref_entities(final_list); 00414 other_group->get_child_ref_entities(entity_list_2); 00415 00416 // At this point, we have three groups, all non-null. Note that 00417 // some or all of these may be the same group, so don't destroy 00418 // the target group until all information is generated. 00419 00420 // 1. Final = group 1 00421 // 2. Add all items that are in group 2, but not already in group 1 00422 for (int i=entity_list_2.size(); i > 0; i--) { 00423 RefEntity *entity = entity_list_2.get_and_step(); 00424 final_list.append_unique(entity); 00425 } 00426 00427 target_group->remove_all_ref_entities(); 00428 target_group->add_ref_entity(final_list); 00429 00430 return CUBIT_SUCCESS; 00431 } 00432 00433 int RefGroup::validate() 00434 { 00435 // NOTE: RefGroup::validate() should not call RefEntity::validate() 00436 // directly since the contained entities will make that 00437 // call in their respective validate() functions. 00438 00439 recursionMark = 1; 00440 int error = 0; 00441 for (int i = entityList.size(); i > 0; i--) { 00442 RefEntity *entity = entityList.get_and_step(); 00443 RefGroup *group = CAST_TO(entity, RefGroup); 00444 if (!group || group->recursionMark == 0) 00445 error += entity->validate(); 00446 } 00447 recursionMark = 0; 00448 return error; 00449 } 00450 00451 CubitStatus RefGroup::delete_group(RefGroup *group_ptr, CubitBoolean propagate) 00452 { 00453 // This function will delete the corresponding group from the Model 00454 // If propagate is CUBIT_TRUE, the contained groups are deleted also. 00455 00456 AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::TOPOLOGY_ENTITY_DESTRUCTED, group_ptr)); 00457 00458 if( propagate ) 00459 { 00460 DLIList<RefGroup*> contained_groups; 00461 get_contained_groups ( group_ptr, contained_groups ); 00462 for( int i=0; i<contained_groups.size(); i++ ) 00463 { 00464 delete_group( contained_groups.get_and_step(), false ); 00465 } 00466 } 00467 00468 group_ptr->remove_all_ref_entities(); 00469 delete group_ptr; 00470 00471 return CUBIT_SUCCESS; 00472 } 00473 00474 void RefGroup::delete_all_groups() 00475 { 00476 DLIList<RefGroup*> ref_groups; 00477 GeometryQueryTool::instance()->ref_groups(ref_groups); 00478 int num_groups = ref_groups.size(); 00479 for( int i=0; i<num_groups; i++ ) 00480 delete_group( ref_groups.get_and_step() ); 00481 00482 } 00483 00484 void RefGroup::get_contained_groups (RefGroup *group_ptr, DLIList<RefGroup*> &contained_groups) 00485 { 00486 DLIList<RefEntity*> group_list, mixed_list; 00487 RefEntity *ref_entity_ptr; 00488 RefGroup *group; 00489 00490 mixed_list.append( group_ptr ); 00491 00492 // Using expand_group algorithm to get sub_groups of group_ptr 00493 // don't swap the upper and lower bounds on ii. 00494 for ( int ii = 0; ii < mixed_list.size(); ii++ ) 00495 { 00496 // Note, the list gets added to, so don't do a simple get_and_step 00497 mixed_list.reset(); 00498 mixed_list.step(ii); 00499 ref_entity_ptr = mixed_list.get(); 00500 00501 group = CAST_TO( ref_entity_ptr, RefGroup ); //which it should be the first time around 00502 if (group) 00503 { 00504 // avoid infinite recursion of groups A and B containing each other 00505 if (!group_list.move_to(group)) { 00506 group->get_child_ref_entities(mixed_list); 00507 group_list.append(group); 00508 } 00509 } 00510 } 00511 CAST_LIST(group_list, contained_groups, RefGroup); 00512 } 00513 00514 void RefGroup::get_groups_within( CubitEntity* cubit_entity_ptr, 00515 DLIList<RefGroup*> &groups_within, 00516 const CubitBoolean recursive) 00517 { 00518 RefEntity* ref_entity_ptr = CAST_TO( cubit_entity_ptr, RefEntity ); 00519 if( ref_entity_ptr != NULL ) 00520 { 00521 get_groups_within( ref_entity_ptr, groups_within, recursive); 00522 return; 00523 } 00524 00525 return; 00526 } 00527 00528 void RefGroup::get_groups_within( RefEntity* ref_entity_ptr, 00529 DLIList<RefGroup*> &groups_within, 00530 const CubitBoolean recursive) 00531 { 00532 RefGroup* ref_group_ptr; 00533 00534 // Get the observer's of this entity 00535 DLIList <CubitObserver*> observer_list; 00536 ref_entity_ptr->get_observer_list( observer_list ); 00537 00538 // Now, loop through the observer list, adding them 00539 for (int i=0; i<observer_list.size(); i++) 00540 { 00541 ref_group_ptr = CAST_TO (observer_list.get(), RefGroup); 00542 00543 if( ref_group_ptr != NULL ) 00544 { 00545 // Add this observer 00546 groups_within.append_unique( ref_group_ptr ); 00547 00548 // Add all the groups the observer is within 00549 if (recursive) get_groups_within( ref_group_ptr, groups_within ); 00550 } 00551 observer_list.step(); 00552 } 00553 } 00554 00555 // Here we need to move through all the model's group's, since observer's 00556 // aren't recursive (i.e., if group 2 contains group 3 which contains 00557 // hex 1, then hex 1's observer is only group 3. Group 2 actually 00558 // contains hex 1 however, but through group 3). 00559 void RefGroup::get_groups_within( RefGroup* ref_group_ptr, 00560 DLIList<RefGroup*> &groups_within, 00561 const CubitBoolean recursive) 00562 { 00563 // Get the model's groups 00564 DLIList<RefGroup*> model_group_list; 00565 GeometryQueryTool::instance()->ref_groups(model_group_list); 00566 int i, j; 00567 RefGroup* model_group; 00568 RefGroup* contained_group; 00569 00570 // Go through all the groups, finding which ones contain 00571 // the entity, at any level below (checks groups within 00572 // groups). 00573 for( i=0; i<model_group_list.size(); i++ ) 00574 { 00575 model_group = model_group_list.get_and_step(); 00576 00577 // See if it exists directly in model_group 00578 DLIList<RefEntity*> contained_ref_entities; 00579 model_group->get_child_ref_entities( contained_ref_entities ); 00580 if( contained_ref_entities.move_to( (RefEntity*)ref_group_ptr ) ) 00581 groups_within.append_unique( model_group ); 00582 00583 if (!recursive) continue; 00584 00585 // Now check all of model group's contained groups 00586 DLIList<RefGroup*> contained_group_list; 00587 model_group->get_contained_groups( model_group, contained_group_list ); 00588 contained_group_list.remove( model_group ); 00589 for( j=0; j<contained_group_list.size(); j++ ) 00590 { 00591 contained_group = contained_group_list.get_and_step(); 00592 00593 contained_ref_entities.clean_out(); 00594 contained_group->get_child_ref_entities( contained_ref_entities ); 00595 00596 if( contained_ref_entities.move_to( (RefEntity*)ref_group_ptr ) ) 00597 groups_within.append_unique( model_group ); 00598 } 00599 } 00600 } 00601 00602 void RefGroup::notify_observer(const CubitEvent *observer_event) 00603 { 00604 const GeometryEvent* geom_event = dynamic_cast<const GeometryEvent*>(observer_event); 00605 if (geom_event != NULL) 00606 { 00607 RefEntity *entity = geom_event->get_entity(); 00608 00609 int event = geom_event->get_type(); 00610 if (event == GeometryEvent::TOPOLOGY_ENTITY_CONSTRUCTED) { 00611 add_ref_entity(entity); 00612 return; 00613 } 00614 else if (event ==GeometryEvent:: TOPOLOGY_ENTITY_DESTRUCTED) { 00615 remove_ref_entity(entity); 00616 return; 00617 } 00618 else if ( event == GeometryEvent::ENTITIES_MERGED ) 00619 { 00620 // Out with the old... 00621 remove_ref_entity(entity); 00622 00623 // ...in with the new. 00624 const MergeEvent *merge_event = static_cast<const MergeEvent*>(geom_event); 00625 RefEntity *kept_entity = 00626 CAST_TO( merge_event->get_kept_entity(), RefEntity ); 00627 add_ref_entity(kept_entity); 00628 } 00629 } 00630 return; 00631 } 00632 00633 /* 00634 void RefGroup::draw (int color) 00635 { 00636 recursionMark = 1; 00637 if (is_visible()) 00638 { 00639 for (int i = entityList.size(); i > 0; i--) 00640 { 00641 RefEntity *entity = entityList.get_and_step(); 00642 RefGroup *group = CAST_TO(entity, RefGroup); 00643 if (!group || group->recursionMark == 0) 00644 entity->draw(color); 00645 } 00646 } 00647 recursionMark = 0; 00648 } 00649 */ 00650