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