cgma
RefEntity.cpp
Go to the documentation of this file.
00001 // ********** BEGIN STANDARD INCLUDES      **********
00002 
00003 #include <assert.h>
00004 
00005 // ********** END STANDARD INCLUDES        **********
00006 
00007 // ********** BEGIN MOTIF INCLUDES         **********
00008 // ********** END MOTIF INCLUDES           **********
00009 
00010 // ********** BEGIN OPEN INVENTOR INCLUDES **********
00011 // ********** END OPEN INVENTOR INCLUDES   **********
00012 
00013 // ********** BEGIN CUBIT INCLUDES         **********
00014 
00015 #include "RefEntity.hpp"
00016 #include "CubitDefines.h"
00017 #include "CubitMessage.hpp"
00018 #include "CubitString.hpp"
00019 
00020 #include "Body.hpp"
00021 #include "BodySM.hpp"
00022 #include "RefGroup.hpp"
00023 #include "RefVolume.hpp"
00024 #include "RefFace.hpp"
00025 #include "RefEdge.hpp"
00026 #include "RefEntityName.hpp"
00027 #include "RefCollection.hpp"
00028 #include "RefVertex.hpp"
00029 
00030 #include "CollectionEntity.hpp"
00031 
00032 #include "ModelQueryEngine.hpp"
00033 
00034 #include "TDCompare.hpp"
00035 
00036 
00037 #include "GeometryQueryTool.hpp"
00038 #include "RefEntityFactory.hpp"
00039 
00040 #include "DLIList.hpp"
00041 #include "CubitUtil.hpp"
00042 #include "AppUtil.hpp"
00043 
00044 // need to include VGE here for free entity test; since virtual geom
00045 // is so tied into ref entities, I think it's ok (tjt)
00046 //#include "VirtualGeometryEngine.hpp"
00047 // Dependency on virtual classes removed, so the VGE does not need
00048 // to be included. 10-18-01 (wjg)
00049 
00050 // The following include generates the inline functions for casting
00051 // a list of A objects to a list of B objects.
00052 #include "CastTo.hpp"
00053 
00054 #include "MergeTool.hpp"
00055 
00056 // ********** END CUBIT INCLUDES           **********
00057 
00058 // ********** BEGIN STATIC DECLARATIONS    **********
00059 // ********** END STATIC DECLARATIONS      **********
00060 
00061 // ********** BEGIN PUBLIC FUNCTIONS       **********
00062 
00063 RefEntity::RefEntity()
00064 {
00065   autoMergeStatus      = AUTO_MERGE_AUTO | AUTO_MERGE_ON;
00066   markedFlag           = CUBIT_FALSE;
00067   listFlag             = CUBIT_FALSE;
00068   mColor               = CUBIT_DEFAULT_COLOR_INDEX;
00069   localTolerance       = 0.0;
00070 
00071   CGMHistory::Event evt(CGMHistory::ENTITY_CREATED, this);
00072   GeometryQueryTool::instance()->history().add_event(evt);
00073 }
00074 
00075 RefEntity::~RefEntity()
00076 {
00077   CGMHistory::Event evt(CGMHistory::ENTITY_DELETED, this);
00078   GeometryQueryTool::instance()->history().add_event(evt);
00079 
00080   // Remove the name of this entity from the entity name map
00081   RefEntityName::instance()->remove_refentity_name(this, CUBIT_FALSE);
00082   
00083   remove_from_observers();
00084 }
00085 
00086 RefEntity* RefEntity::get_by_name(const CubitString& name)
00087 {
00088   return RefEntityName::instance()->get_refentity(name);
00089 }
00090 
00091 CubitStatus RefEntity::entity_name (CubitString name)
00092 {
00093     // Add the new {RefEntity, Name} tuple to the RefEntityNameMap class.
00094     // Note that if this name already exists for another RefEntity, then
00095     // it will return with an error. 
00096   CubitStatus success = RefEntityName::instance()->
00097     add_refentity_name(this, name);
00098   
00099   if (success == CUBIT_SUCCESS)
00100     AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::ENTITY_NAME_CHANGED, this));
00101 
00102   return success;
00103 }
00104 
00105 CubitString RefEntity::entity_name() const
00106 {
00107   DLIList<CubitString> names;
00108   
00109     // Get the name(s) associated with this RefEntity.
00110   RefEntityName::instance()->get_refentity_name(this, names);
00111   
00112   CubitString name;
00113   
00114     // If there are no names, then create the default name and return it.
00115   if (names.size() == 0) 
00116   {
00117     name = class_name();
00118     name += " ";
00119     name += CubitString::number(entityId);
00120   } 
00121   else 
00122   {
00123     name = names.get();
00124   }
00125   
00126   return name;
00127 }
00128 
00129 int RefEntity::num_names() const
00130 {
00131   DLIList<CubitString> names;
00132   
00133   // Get the name(s) associated with this RefEntity.
00134   RefEntityName::instance()->get_refentity_name(this, names);
00135   return names.size();
00136 }
00137   
00138 void RefEntity::entity_names(DLIList<CubitString>& names) const
00139 {
00140   RefEntityName::instance()->get_refentity_name(this, names);
00141 }
00142 
00143 CubitStatus RefEntity::remove_entity_name(CubitString const & name)
00144 {
00145   RefEntity* entity = RefEntityName::instance()->get_refentity(name);
00146   if (entity != this)
00147     return CUBIT_FAILURE;
00148   
00149   RefEntityName::instance()->remove_refentity_name(this, name);
00150   AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::ENTITY_NAME_CHANGED, this));
00151   return CUBIT_SUCCESS;
00152 }
00153 
00154 CubitStatus RefEntity::remove_entity_names()
00155 {
00156   RefEntityName::instance()->remove_refentity_name(this, CUBIT_TRUE);
00157   AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::ENTITY_NAME_CHANGED, this));
00158   return CUBIT_SUCCESS;
00159 }
00160 
00161 // All this function basically does is assign the default name.
00162 // It will do this as an attribute so they get actuated to the
00163 // solid model.
00164 CubitStatus RefEntity::generate_default_name( CubitString &name )
00165 {
00166   if ( CAST_TO( this, Body ) )
00167      name += CubitString("bod");
00168   else if ( CAST_TO( this, RefVolume ) )
00169      name += CubitString("vol");
00170   else if ( CAST_TO( this, RefFace ) )
00171      name += CubitString("sur");
00172   else if ( CAST_TO( this, RefEdge ) )
00173      name += CubitString("cur");
00174   else if ( CAST_TO( this, RefVertex ) )
00175      name += CubitString("ver");
00176   else if ( CAST_TO( this, RefGroup ) ) {
00177      //PRINT_INFO( "Debug: RefGroup entity name set in RefEntity::generate_default_name\n" );
00178     name += CubitString("gro");
00179   }
00180   else
00181   {
00182     PRINT_ERROR("Invalid entity: %s.\n",
00183                 entity_name().c_str() );
00184     return CUBIT_FAILURE;
00185   }
00186     
00187   name += CubitString::number(entityId);
00188   return CUBIT_SUCCESS;
00189 }
00190 
00191 CubitStatus RefEntity::assign_default_name( CubitBoolean user_setting )
00192 {
00193 
00194   if ( RefEntityName::instance()->get_generate_default_names() 
00195     || user_setting == CUBIT_TRUE )
00196   {
00197       // first generate the default name
00198     CubitString name;
00199     CubitStatus result = generate_default_name( name );
00200     if (result == CUBIT_FAILURE) return result;
00201 
00202       // now assign it to this entity and return
00203     RefEntityName::instance()->add_refentity_name(this, name);
00204     return CUBIT_SUCCESS;
00205   }
00206   return CUBIT_SUCCESS;
00207 }
00208 
00209 
00210 void RefEntity::merge_entity_names(RefEntity* dead_entity)
00211 {
00212   RefEntityName::instance()->merge_refentity_names(this, dead_entity);
00213 }
00214 
00215 void RefEntity::switch_entity_names(RefEntity* other_entity)
00216 {
00217   RefEntityName::instance()->switch_refentity_names(this, other_entity);
00218 }
00219 
00220 
00221 //-------------------------------------------------------------------------
00222 // Purpose       : Target types for parent/child queries
00223 //
00224 // Special Notes : 
00225 //
00226 // Creator       : Jason Kraftcheck
00227 //
00228 // Creation Date : 07/24/03
00229 //-------------------------------------------------------------------------
00230 DagType RefEntity::get_parent_ref_entity_type() const
00231   { return get_parent_ref_entity_type(dag_type()); }
00232 DagType RefEntity::get_parent_ref_entity_type(DagType my_type)
00233 {
00234   int dimension = my_type.dimension();
00235 
00236     // special case for bodies
00237   if (dimension == 3)
00238   {
00239     if (my_type.functional_type() == DagType::BasicTopologyEntity_TYPE)
00240       return DagType::body_type();
00241     else
00242       return DagType::invalid_type();
00243   }
00244   
00245   return DagType( dimension + 1, DagType::BasicTopologyEntity_TYPE);
00246 }
00247 DagType RefEntity::get_child_ref_entity_type() const
00248   { return get_child_ref_entity_type(dag_type()); }
00249 DagType RefEntity::get_child_ref_entity_type( DagType my_type )
00250 {
00251   int dimension = my_type.dimension();
00252   if (my_type.functional_type() == DagType::BasicTopologyEntity_TYPE)
00253     return DagType(dimension - 1, DagType::BasicTopologyEntity_TYPE);
00254   else
00255     return DagType(dimension, DagType::BasicTopologyEntity_TYPE);
00256 }
00257 
00258 DagType RefEntity::dag_type( const std::type_info& type )
00259 {
00260   if (type == typeid(Body))
00261     return DagType::body_type();
00262   else if (type == typeid(RefVolume))
00263     return DagType::ref_volume_type();
00264   else if (type == typeid(RefFace))
00265     return DagType::ref_face_type();
00266   else if (type == typeid(RefEdge))
00267     return DagType::ref_edge_type();
00268   else if (type == typeid(RefVertex))
00269     return DagType::ref_vertex_type();
00270   
00271   assert(0);
00272   return DagType::invalid_type();
00273 }
00274 
00275 void RefEntity::get_child_ref_entities(DLIList<RefEntity*>& entity_list)
00276 {
00277   // First get the type of RefEntity that is a child of "this" one
00278   DagType child_type = get_child_ref_entity_type();
00279   
00280   DLIList<TopologyEntity*> tempList ;
00281   
00282     // Now retrieve the appropriate type of child entities of this one
00283     // if the child_type is a valid type
00284   if (child_type.is_valid())
00285   {
00286     TopologyEntity* TopologyEntityPtr = CAST_TO(this, TopologyEntity) ;
00287     
00288     assert(TopologyEntityPtr != 0);
00289     
00290     CubitStatus result = ModelQueryEngine::instance()->
00291         query_model( *TopologyEntityPtr, child_type, tempList );
00292     if (result == CUBIT_FAILURE)
00293     {
00294       PRINT_ERROR("In RefEntity::get_child_ref_entities\n");
00295       PRINT_ERROR("       Query failed for unknown reason.\n");
00296       return;
00297     }
00298    
00299     CAST_LIST(tempList, entity_list, RefEntity) ;
00300   }
00301 }
00302 
00303 
00304 //-------------------------------------------------------------------------
00305 // Purpose       : Get all types of child RefEntity
00306 //
00307 // Special Notes : 
00308 //
00309 // Creator       : Jason Kraftcheck
00310 //
00311 // Creation Date : 07/29/03
00312 //-------------------------------------------------------------------------
00313 void RefEntity::get_all_child_ref_entities(DLIList<RefEntity*>& entity_list)
00314 {
00315   
00316   ModelQueryEngine *const mqe = ModelQueryEngine::instance();
00317   DagType child_type = get_child_ref_entity_type();
00318   DLIList<TopologyEntity*> query_output;
00319   TopologyEntity* this_me = dynamic_cast<TopologyEntity*>(this);
00320 
00321   // note that RefGroups are kind of shoe-horned into RefEntity
00322   // there are no children of a refgroup
00323   if(!this_me)
00324     return;  // 
00325  
00326     //While there are more child types
00327   while (child_type.is_valid())
00328   {
00329     mqe->query_model(*this_me, child_type, query_output);
00330     query_output.reset();
00331     for (int i = query_output.size(); i--; )
00332     {
00333       RefEntity* ref_ptr = dynamic_cast<RefEntity*>(query_output.get_and_step());
00334       if (ref_ptr)
00335         entity_list.append(ref_ptr);
00336     }
00337     
00338     child_type = get_child_ref_entity_type( child_type );
00339   }
00340 }
00341 
00342 
00343 
00344 //-------------------------------------------------------------------------
00345 // Purpose       : Get all parent RefEntities for each passed entity.
00346 //
00347 // Special Notes : 
00348 //
00349 // Creator       : Jason Kraftcheck
00350 //
00351 // Creation Date : 07/29/03
00352 //-------------------------------------------------------------------------
00353 void RefEntity::get_all_child_ref_entities( DLIList<RefEntity*>& input_list,
00354                                                       DLIList<RefEntity*>& output_list )
00355 {
00356   DLIList<TopologyEntity*> query_output;
00357   ModelQueryEngine *const mqe = ModelQueryEngine::instance();
00358   int i;
00359   
00360     // Find parent-most type from all passed entities
00361   DagType target_type = DagType::ref_vertex_type();
00362   for (i = input_list.size(); i--; )
00363   {
00364     DagType type = input_list.step_and_get()->dag_type();
00365     if (type.is_valid() && type > target_type)
00366       target_type = type;
00367   }
00368   
00369   target_type = get_child_ref_entity_type( target_type );
00370   while (target_type.is_valid())
00371   {
00372     input_list.reset();
00373     for (i = input_list.size(); i--; )
00374     {
00375       RefEntity* input_ptr = input_list.get_and_step();
00376       DagType source_type = input_ptr->dag_type();
00377 
00378       if (source_type.is_valid() && source_type > target_type)
00379       {
00380         TopologyEntity* me_ptr = dynamic_cast<TopologyEntity*>(input_ptr);
00381         assert(!!me_ptr);
00382         mqe->query_model (*me_ptr, target_type, query_output);
00383         
00384         query_output.size();
00385         for ( int j = query_output.size(); j--; )
00386         {
00387           RefEntity* ref_ent = dynamic_cast<RefEntity*>(query_output.get_and_step());
00388           output_list.append( ref_ent );
00389         }
00390       }
00391     }
00392     
00393     target_type = get_child_ref_entity_type( target_type );
00394 
00395   }
00396 }
00397 
00398 //-------------------------------------------------------------------------
00399 // Purpose       : Get all types of parent RefEntity
00400 //
00401 // Special Notes : 
00402 //
00403 // Creator       : Jason Kraftcheck
00404 //
00405 // Creation Date : 07/29/03
00406 //-------------------------------------------------------------------------
00407 void RefEntity::get_all_parent_ref_entities(DLIList<RefEntity*>& entity_list,
00408                                             const int get_bodies)
00409 {
00410   
00411   ModelQueryEngine *const mqe = ModelQueryEngine::instance();
00412   DagType parent_type = get_parent_ref_entity_type();
00413   DLIList<TopologyEntity*> query_output;
00414   TopologyEntity* this_me = dynamic_cast<TopologyEntity*>(this);
00415   assert(!!this_me);
00416  
00417     //While there are more parent types
00418   while ( parent_type.is_valid() && 
00419           (get_bodies || (parent_type != DagType::body_type())) )
00420   {
00421     mqe->query_model(*this_me, parent_type, query_output);
00422     query_output.reset();
00423     for (int i = query_output.size(); i--; )
00424     {
00425       RefEntity* ref_ptr = dynamic_cast<RefEntity*>(query_output.get_and_step());
00426       assert(!!ref_ptr);
00427       entity_list.append(ref_ptr);
00428     }
00429     
00430     parent_type = get_parent_ref_entity_type( parent_type );
00431   }
00432 }
00433 
00434 
00435 void RefEntity::change_to_parent_ref_entities( DLIList<RefEntity*>& ancestors )
00436 {
00437   DLIList<RefEntity*> new_ancestors, temp_list;
00438   if ( ancestors.size() == 0 ) return;
00439   
00440   ancestors.reset();
00441   do 
00442   {
00443     temp_list.clean_out();
00444     ancestors.get_and_step()->get_parent_ref_entities( temp_list );
00445     new_ancestors.merge_unique( temp_list );
00446   } while ( !ancestors.is_at_beginning() );
00447   
00448     // Overwrite the input list
00449   ancestors = new_ancestors;
00450 }
00451 
00452 int RefEntity::dimension() const
00453 {
00454     // Virtual function. This is the default return value. 
00455     // Override in subclass if different return value is needed.
00456   return -1;
00457 }
00458 
00459  
00460 RefEntity *RefEntity::join( DLIList<RefEntity*> &ref_entities, 
00461                             DLIList<RefEntity*> &join_set )
00462 {
00463   join_set.clean_out();
00464 
00465     // Trivial cases 
00466   
00467     // empty set
00468   if ( !ref_entities.size() )
00469     return NULL;
00470   
00471     // All entities are the same, e.g. list is size 1
00472   int i, j;
00473   int all_same = CUBIT_TRUE;
00474   RefEntity *e1, *e2;
00475   for (i = ref_entities.size()-1; all_same && i--; )
00476   {
00477     e1 = ref_entities.get_and_step();
00478     e2 = ref_entities.get();
00479     all_same = ( e1 == e2 );
00480   }
00481   if ( all_same )
00482   {
00483     join_set.append( ref_entities.get() );
00484     return join_set.get();
00485   }  
00486   
00487     // Generic test, build ancestor lists until dimensions are equal
00488   const int size = ref_entities.size();
00489 
00490     // Lists of ancestors
00491   DLIList<RefEntity*> *ancestors = new DLIList<RefEntity*> [ size ];
00492     // current dimension of ancestors of each entity
00493   int *dimension = new int [size];
00494     // Set ancestors and dimension: Start with the entities themselves
00495   int d1, max_dimension = -1;
00496   ref_entities.reset();
00497   for ( i = 0; i < size; i++ )
00498   {
00499     e1 = ref_entities.get_and_step();
00500     ancestors[i].append( e1 );
00501     dimension[i] = d1 = e1->dimension();
00502     if ( d1 > max_dimension )
00503       max_dimension = d1;
00504   }
00505   
00506   do
00507   {
00508 
00509     // Bump dimensions up to max dimension
00510     for ( i = 0; i < size; i++ )
00511     {
00512       while ( dimension[i] < max_dimension ) 
00513       {
00514         change_to_parent_ref_entities( ancestors[i] );
00515           // no ancestor of max dimension -> join is nothing
00516         if ( !ancestors[i].size() )
00517           goto clean_return;
00518         dimension[i] = d1 = ancestors[i].get()->dimension();
00519           // if somehow a dimension was skipped, go through the list again.
00520         if ( d1 > max_dimension )
00521         {
00522           max_dimension = d1;
00523           i = 0; // restart loop
00524         }
00525       }
00526     }
00527 
00528       // dimensions are the same, see if any entities common to *all* lists
00529     for ( j = ancestors[0].size(); j--; )
00530     {
00531       e1 = ancestors[0].get_and_step();
00532       int in_all_lists = CUBIT_TRUE;
00533       for ( i = 1; in_all_lists && i < size; i++ )
00534       {
00535         in_all_lists = ancestors[i].is_in_list( e1 );
00536       }
00537       if ( in_all_lists )
00538         join_set.append( e1 );
00539     } 
00540     
00541       // iterate
00542     max_dimension++;
00543     
00544       // they had common entities in the current dimension - return
00545   } while ( join_set.size() == 0 );
00546   
00547     clean_return:
00548   delete [] dimension;
00549   delete [] ancestors;
00550 
00551   if ( join_set.size() )
00552   {
00553     join_set.reset();
00554     return join_set.get();
00555   }
00556   return NULL;
00557 }
00558 
00559   
00560 RefEntity *RefEntity::join( RefEntity* ref_entity_2, DLIList<RefEntity*> &join_set )
00561 {
00562   join_set.clean_out();
00563   assert( this != 0 );
00564   
00565     // Trivial case :-)
00566     // Both entities are the same, or 
00567     // The join of the empty set and any thing is defined to be the thing.
00568   if (this == ref_entity_2 || ref_entity_2 == NULL ) 
00569   { 
00570     join_set.append( this );
00571     return this;
00572   }
00573   
00574     // call generic function that takes a list
00575   DLIList<RefEntity*> both_entities;
00576   both_entities.append( this );
00577   both_entities.append( ref_entity_2 );
00578   return join( both_entities, join_set );
00579 }
00580 
00581 RefEntity *RefEntity::meet( DLIList<RefEntity*> &ref_entities, 
00582                                   DLIList<RefEntity*> &join_set )
00583 {
00584   join_set.clean_out();
00585 
00586     // Trivial cases 
00587   
00588     // empty set
00589   if ( !ref_entities.size() )
00590     return NULL;
00591   
00592     // All entities are the same, e.g. list is size 1
00593   int i, j;
00594   int all_same = CUBIT_TRUE;
00595   RefEntity *e1, *e2;
00596   for (i = ref_entities.size()-1; all_same && i--; )
00597   {
00598     e1 = ref_entities.get_and_step();
00599     e2 = ref_entities.get();
00600     all_same = ( e1 == e2 );
00601   }
00602   if ( all_same )
00603   {
00604     join_set.append(ref_entities.get());
00605     return ref_entities.get();
00606   }  
00607 
00608     // they aren't all the same; get all the children, intersect the lists,
00609     // and remove any related entities
00610   DLIList<RefEntity*> temp_list;
00611   ref_entities.get()->get_all_child_ref_entities(join_set);
00612   join_set.append(ref_entities.get_and_step());
00613   
00614   for (i = ref_entities.size(); i > 1; i--) {
00615     temp_list.clean_out();
00616     ref_entities.get()->get_all_child_ref_entities(temp_list);
00617     temp_list.append(ref_entities.get_and_step());
00618     join_set.intersect(temp_list);
00619 
00620       // if the join set is null at any time, there's no common entity
00621     if (join_set.size() == 0) return NULL;
00622   }
00623 
00624   temp_list.clean_out();
00625 
00626     // clean out any duplicates before checking for relations
00627   temp_list.merge_unique(join_set);
00628   join_set = temp_list;
00629   temp_list.clean_out();
00630   
00631     // now remove any related entities
00632   join_set.reset();
00633   join_set.step();
00634   for (i = join_set.size()-1; i > 0; i--) {
00635     RefEntity *entity = join_set.get();
00636     if (temp_list.move_to(entity)) continue;
00637     
00638     for (j = join_set.size()-i; j > 0; j--) {
00639       RefEntity *other_entity = join_set.prev(j);
00640       if (temp_list.move_to(other_entity)) continue;
00641       if (entity->is_child(other_entity)) temp_list.append(entity);
00642       else if (entity->is_parent(other_entity)) temp_list.append(other_entity);
00643     }
00644     join_set.step();
00645   }
00646   
00647   if (temp_list.size() > 0) join_set -= temp_list;
00648 
00649   return (join_set.size() ? join_set.get() : NULL);
00650 }
00651 
00652 RefEntity *RefEntity::meet( RefEntity* ref_entity_2, DLIList<RefEntity*> &join_set )
00653 {
00654   join_set.clean_out();
00655   assert( this != 0 );
00656   
00657     // Trivial case :-)
00658     // Both entities are the same, or 
00659     // The join of the empty set and any thing is defined to be the thing.
00660   if (this == ref_entity_2 || ref_entity_2 == NULL ) 
00661   { 
00662     join_set.append( this );
00663     return this;
00664   }
00665   
00666     // call generic function that takes a list
00667   DLIList<RefEntity*> both_entities;
00668   both_entities.append( this );
00669   both_entities.append( ref_entity_2 );
00670   return meet( both_entities, join_set );
00671 }
00672 
00673 int RefEntity::valence(RefEntity *parent) 
00674 {
00675   DLIList<RefEntity*> parents;
00676   get_parent_ref_entities(parents);
00677   if (parent == NULL) return parents.size();
00678   
00679   int val = parents.size();
00680   int i;
00681   BasicTopologyEntity *topo_ent = CAST_TO(this, BasicTopologyEntity);
00682   for (i = val; i > 0; i--) {
00683     RefEntity *other_ent = parents.get_and_step();
00684     if (!topo_ent->is_directly_related(CAST_TO(other_ent, BasicTopologyEntity))) val--; 
00685   }
00686   
00687   return val;
00688 }
00689   
00690 CubitVector RefEntity::center_point()
00691 {
00692   return bounding_box().center();
00693 }
00694 
00695 // autoMergeStatus :
00696 // bit 0:  1 = mergeable, 0 = not mergeable
00697 // bit 1:  1 = auto,  0 = explicit
00698 
00699 void RefEntity::is_mergeable(AutoMergeStatus val)
00700 {
00701   AutoMergeStatus old_status = (AutoMergeStatus)(autoMergeStatus & 1);
00702   autoMergeStatus = (int)val;
00703   
00704     // always want to update children, but update_auto_merge_state
00705     // recursively updates the children, so don't update the
00706     // children twice if we call update_auto_merge_state.
00707   if( val == AUTO_MERGE_AUTO )
00708   {
00709     this->update_auto_merge_state();
00710   }
00711   else if( old_status != val )
00712   {
00713     DLIList<RefEntity*> children;
00714     get_child_ref_entities( children );
00715     for( int i = children.size(); i--; )
00716       children.get_and_step()->update_auto_merge_state();
00717   }
00718 }
00719 
00720 bool RefEntity::is_mergeable()
00721 {
00722     // return 0-bit of autoMergeState
00723   return (bool)(autoMergeStatus & 1);
00724 }
00725 
00726 CubitBoolean RefEntity::is_merged()
00727 {
00728   TopologyEntity* topo = CAST_TO(this, TopologyEntity);
00729   if (!topo)
00730     return CUBIT_FALSE;
00731 
00732   return MergeTool::instance()->entity_merged(topo);
00733 }
00734 
00735 AutoMergeStatus RefEntity::merge_status() const
00736 {
00737   return autoMergeStatus > 1 ? AUTO_MERGE_AUTO : (AutoMergeStatus)autoMergeStatus;
00738 }
00739 
00740 bool RefEntity::children_mergeable()
00741 {
00742    DLIList<RefEntity*> children;
00743    get_all_child_ref_entities( children );
00744    
00745    for( int i = children.size(); i--; )
00746      if( children.get_and_step()->autoMergeStatus == 0 ) 
00747        return false;
00748 
00749    return true;
00750 }
00751 
00752 void RefEntity::update_auto_merge_state()
00753 {
00754   int i;
00755   
00756   if( autoMergeStatus & 2 )
00757   {
00758     int mergeable = 1;
00759     
00760     DLIList<RefEntity*> list;
00761 
00762     get_parent_ref_entities( list );
00763     for( i = list.size(); i--; )
00764       if( ! list.get_and_step()->is_mergeable() )
00765         mergeable = 0;
00766   
00767     int old_value = autoMergeStatus & 1;
00768     if( old_value != mergeable )
00769     {
00770       autoMergeStatus = (autoMergeStatus & 2) | mergeable;
00771   
00772       list.clean_out();
00773       get_child_ref_entities( list );
00774     
00775       for( i = list.size(); i--; )
00776         list.get_and_step()->update_auto_merge_state();
00777     }    
00778   }
00779 }
00780 
00781 int RefEntity::can_modify() { return 1; }
00782 
00783 double RefEntity::measure()
00784 {
00785   return 0.0;
00786 }
00787 
00788 CubitString RefEntity::measure_label()
00789 {
00790   return "N/A";
00791 }
00792 
00793 
00794 void RefEntity::notify_sub_all_observers(const GeometryEvent::Type& event)
00795 {
00796   DLIList<RefEntity*> entity_list;
00797   get_all_child_ref_entities( entity_list );
00798   for ( int i = entity_list.size(); i>0; i-- )
00799   {
00800     RefEntity* ent = entity_list.get_and_step();
00801     AppUtil::instance()->send_event(GeometryEvent(event, ent));
00802   }
00803   AppUtil::instance()->send_event(GeometryEvent(event, this));
00804 }
00805 
00806 
00807 //-------------------------------------------------------------------------
00808 // Purpose       : This function takes actions depending on the type of 
00809 //                 event it is notified of.
00810 //
00811 // Special Notes :
00812 //
00813 // Creator       : Raikanta Sahu
00814 //
00815 // Creation Date : 11/25/96
00816 //-------------------------------------------------------------------------
00817 
00818 void RefEntity::comparison_found(RefEntity* partner)
00819 {
00820   add_compare_data(partner);
00821   MergeTool::instance()->compare_notify(this) ;
00822   MergeTool::instance()->compare_notify(partner) ;
00823 }
00824 
00825 //-------------------------------------------------------------------------
00826 // Purpose       : This function makes the connection between the two 
00827 //                 RefEntities, this and partner. At the end of this 
00828 //                 function the two entities would know who they 
00829 //                 compare with.
00830 //
00831 // Special Notes :
00832 //
00833 // Creator       : Raikanta Sahu
00834 //
00835 // Creation Date : 11/25/96
00836 //-------------------------------------------------------------------------
00837 
00838 void RefEntity::add_compare_data(RefEntity* partner) 
00839 {
00840   TDCompare* compareDataPtr = (TDCompare*)(this->get_TD(&TDCompare::is_compare));
00841   if (compareDataPtr == NULL)
00842   {
00843     compareDataPtr = new TDCompare() ;
00844     this->add_TD(compareDataPtr) ;
00845   }
00846   compareDataPtr->set_compare_partner(partner) ;
00847   
00848   
00849   compareDataPtr = (TDCompare*)(partner->get_TD(&TDCompare::is_compare));
00850   if (compareDataPtr == NULL)
00851   {
00852     compareDataPtr = new TDCompare() ;
00853     partner->add_TD(compareDataPtr) ;
00854   }
00855   compareDataPtr->set_compare_partner(this) ;
00856 }
00857 
00858 //-------------------------------------------------------------------------
00859 // Purpose       : This function clears the compare related temporary data. 
00860 //
00861 // Special Notes :
00862 //
00863 // Creator       : Raikanta Sahu
00864 //
00865 // Creation Date : 11/25/96
00866 //-------------------------------------------------------------------------
00867 
00868 void RefEntity::remove_compare_data()
00869 {
00870   ToolData* tdPtr = this->get_TD(&TDCompare::is_compare) ;
00871   TDCompare* tdComparePtr = CAST_TO(tdPtr, TDCompare) ;
00872   
00873   if (tdComparePtr == NULL)
00874   {
00875     return ;
00876   }
00877   RefEntity* partner = tdComparePtr->get_compare_partner() ;
00878 
00879   if (partner != NULL)
00880     {
00881       PRINT_DEBUG_19(
00882           "RefEntity::remove_compare_data - Removing TDCompare from"
00883           " %s %d, via partner %s %d\n",
00884           partner->class_name(),
00885           partner->id(),
00886           this->class_name(),
00887           this->id());
00888       partner->delete_TD(&TDCompare::is_compare) ;
00889     }
00890   
00891   this->delete_TD(&TDCompare::is_compare) ;
00892 //   partner->delete_TD(&TDCompare::is_compare) ;
00893 }
00894 
00895 RefEntity* RefEntity::get_compare_partner()
00896 {
00897   ToolData* tdPtr = get_TD(&TDCompare::is_compare) ;
00898   TDCompare* tdComparePtr = CAST_TO(tdPtr, TDCompare) ;
00899   return tdComparePtr ? tdComparePtr->get_compare_partner() : 0;
00900 }
00901 
00902 int RefEntity::validate()
00903 {
00904     //- This function determines whether the entity is valid.
00905     //- Several types of checks can be done, 
00906   
00907     // Check that measure is positive
00908   int error = 0;
00909 
00910   Body *tmp_body = CAST_TO( this, Body);
00911   bool is_sheet_body = false;
00912   if( tmp_body )
00913     is_sheet_body = tmp_body->is_sheet_body();
00914   
00915   if( false == is_sheet_body )
00916   {
00917     double this_measure = measure();
00918     if (this_measure <= 0.0) {
00919       PRINT_WARNING("\tWARNING: non-positive %s (%f) for %s, (%s %d)\n",
00920                     measure_label().c_str(), this_measure,
00921                     entity_name().c_str(), class_name(), id());
00922       error++;
00923     }  
00924   }
00925   return error;
00926 }
00927 
00928 
00929 CubitBoolean RefEntity::is_child(RefEntity *entity)
00930 {
00931     // same?
00932   if ( this == entity )
00933     return CUBIT_TRUE;
00934   
00935     // wrong dimensions?
00936   if (!entity || dimension() >= entity->dimension() )
00937     return CUBIT_FALSE;
00938   
00939     // Topological query.
00940     // Usually slightly faster to search up in dimension.
00941   TopologyEntity *topo_this = CAST_TO( this, TopologyEntity );
00942   TopologyEntity *topo_entity = CAST_TO( entity, TopologyEntity );  
00943   return topo_this->is_directly_related( topo_entity );
00944 }
00945 
00946 CubitBoolean RefEntity::is_parent(RefEntity *entity)
00947 {
00948     // same?
00949   if ( this == entity )
00950     return CUBIT_TRUE;
00951   
00952     // wrong dimensions?
00953   if (!entity || dimension() <= entity->dimension() )
00954     return CUBIT_FALSE;
00955 
00956     // Topological query. 
00957     // Usually slightly faster to search up in dimension.
00958   BasicTopologyEntity *topo_this = CAST_TO( this, BasicTopologyEntity );
00959   BasicTopologyEntity *topo_entity = CAST_TO( entity, BasicTopologyEntity );  
00960   return topo_entity->is_directly_related( topo_this );
00961 }
00962 
00963 int RefEntity::num_parent_ref_entities()
00964 {
00965     // First get the type of RefEntity that is a parent of "this" one
00966   DagType parent_type = get_parent_ref_entity_type();
00967   
00968   DLIList<TopologyEntity*> tempList ;
00969   
00970     // Now retrieve the appropriate type of parent entities of this one,
00971     // if the parent_type is a valid type
00972   if (parent_type.is_valid())
00973   {
00974     TopologyEntity* TopologyEntityPtr = CAST_TO(this, TopologyEntity) ;
00975     
00976       //Make sure that we have a valid pointer
00977     assert(TopologyEntityPtr != NULL) ;
00978     
00979     CubitStatus result = ModelQueryEngine::instance()->
00980         query_model( *TopologyEntityPtr,
00981                      parent_type,
00982                      tempList );
00983     if (result == CUBIT_FAILURE)
00984     {
00985       PRINT_ERROR("In RefEntity::num_parent_ref_entities\n");
00986       PRINT_ERROR("       Query failed for unknown reason.\n");
00987       return -1;
00988     }
00989     return tempList.size();
00990   }
00991 
00992   return -1;
00993 }
00994 /*
00995 CubitBoolean RefEntity::is_free_ref_entity() 
00996 {
00997     // return true if this RefEntity has no non-virtual parents
00998     // first look for Body type or # of parents
00999   if (entity_type_info() == typeid(Body) ||
01000       num_parent_ref_entities() == 0) return CUBIT_TRUE;
01001 
01002   
01003     // now look at immediate parents to quickly rule out some entities
01004   DLIList<RefEntity*> parents;
01005   get_parent_ref_entities(parents);
01006   if (!VGE->check_for_virtual(CAST_TO(parents.get(), TopologyEntity)))
01007     return CUBIT_FALSE;
01008   
01009     // now look at all the parents; work back from the list, as this is most
01010     // likely to be non-virtual
01011   parents.clean_out();
01012   get_all_parent_ref_entities(parents);
01013   parents.last();
01014   RefEntity *ref_entity;
01015   int i;
01016   for (i = parents.size(); i > 0; i--) {
01017     ref_entity = parents.get_and_back();
01018     if (!VGE->check_for_virtual(CAST_TO(ref_entity, TopologyEntity)))
01019       return CUBIT_FALSE;
01020   }
01021 
01022     // if we've gotten here, we have no non-virtual parents
01023   return CUBIT_TRUE;
01024 }
01025 */
01026 void RefEntity::gather_bdy_entities( DLIList<RefEntity*> &entity_list, 
01027                                      DLIList<RefEntity*> &bdy_list ) 
01028 {
01029   RefEntity *entity;
01030   DLIList<RefEntity*> tmp_bdy_list;
01031   int i;
01032 
01033   for ( i = entity_list.size(); i--; )
01034   {
01035     entity = entity_list.get_and_step();
01036     entity->list_mark( CUBIT_TRUE );
01037     //entity->get_all_child_ref_entities( tmp_bdy_list );
01038   }
01039     
01040   get_all_child_ref_entities(entity_list, tmp_bdy_list);
01041 
01042 
01043     // copy non-duplicate and non-entity_list entities
01044   for ( i = tmp_bdy_list.size(); i--; ) {
01045     entity = tmp_bdy_list.get_and_step();
01046     if ( !entity->list_mark() ) {
01047       bdy_list.append( entity );
01048       entity->list_mark( CUBIT_TRUE );
01049     }
01050   }
01051     // clean-up
01052   for ( i = bdy_list.size(); i--; ) {
01053     entity = bdy_list.get_and_step();
01054     entity->list_mark( CUBIT_FALSE );
01055   }
01056   for ( i = entity_list.size(); i--; ) {
01057     entity = entity_list.get_and_step();
01058     entity->list_mark( CUBIT_FALSE );
01059   }
01060 }
01061 
01062 //-------------------------------------------------------------------------
01063 // Purpose       : Most RefEntites related_to another RefEntity can be done
01064 //                 through query model as is in CommandHandler, but
01065 //                 group in <ref_entity> crashes when query model is called, instead
01066 //                 this function will be called
01067 //
01068 // Special Notes : 
01069 //
01070 // Creator       : RY (CAT)
01071 //
01072 // Creation Date : 5-99
01073 //-------------------------------------------------------------------------
01074 void RefEntity::get_related_entity_list(const std::type_info& related_entity_type,
01075                             DLIList<RefEntity*>& entity_list)
01076 {
01077   if (related_entity_type == typeid(RefGroup)){
01078     DLIList <CubitObserver*> observer_list;
01079     this->get_observer_list (observer_list);
01080     for (int i = observer_list.size(); i > 0; i--){
01081       entity_list.append_unique (CAST_TO (observer_list.get(), RefEntity));
01082       observer_list.step();
01083     }
01084   }
01085 }
01086 
01087 void RefEntity::set_id(int i )
01088 {
01089   set_id( i, CUBIT_TRUE );
01090 }
01091 
01092 void RefEntity::set_id(int i, CubitBoolean emit_event )
01093 {
01094   if (entityId == i)
01095     return;
01096  
01097   int old_id = entityId;
01098   entityId = i;
01099 
01100   if( emit_event )
01101     AppUtil::instance()->send_event(GeometryIdSetEvent(this, old_id, entityId) );
01102 
01103   int old_max = RefEntityFactory::instance()->maximum_id(this);
01104   
01105   if (old_max < entityId)
01106       // Need to reset the maxId for this entitytype
01107     RefEntityFactory::instance()->incorporate_id(this);
01108   else if (old_max == old_id) 
01109   {
01110       // We just reset the entity with the max id to something less
01111       // than that - should search and find out what the max id
01112       // is now.
01113     DLIList<RefEntity*> ent_list;
01114     if(this->entity_type_info() == typeid(Body))
01115       RefEntityFactory::instance()->ref_entity_list("body", ent_list);
01116     else if(this->entity_type_info() == typeid(RefVolume))
01117       RefEntityFactory::instance()->ref_entity_list("volume", ent_list);
01118     else if(this->entity_type_info() == typeid(RefFace))
01119       RefEntityFactory::instance()->ref_entity_list("surface", ent_list);
01120     else if(this->entity_type_info() == typeid(RefEdge))
01121       RefEntityFactory::instance()->ref_entity_list("curve", ent_list);
01122     else if(this->entity_type_info() == typeid(RefVertex))
01123       RefEntityFactory::instance()->ref_entity_list("vertex", ent_list);
01124 
01125     int max_id = 0;
01126     for(int i=ent_list.size()-1; i>-1; i--)
01127     {
01128       if(ent_list[i]->id() > max_id)
01129         max_id = ent_list[i]->id();
01130     }
01131     RefEntityFactory::instance()->maximum_id(this->entity_type_info(), max_id);
01132   }
01133 }
01134 
01135 const std::type_info& RefEntity::get_entity_type_info(const char* entity_type)
01136 {
01137   CubitString string(entity_type);
01138   string.to_lower();
01139   
01140   if( string == "group" )
01141      return typeid(RefGroup);
01142   else if (string == "body" )
01143      return typeid(Body);
01144   else if( string == "volume" )
01145      return typeid(RefVolume);
01146   else if( string == "surface" )
01147      return typeid(RefFace);
01148   else if( string == "curve" )
01149      return typeid(RefEdge);
01150   else if( string == "vertex" )
01151      return typeid(RefVertex);
01152   else
01153      return typeid(InvalidEntity);
01154 }
01155 
01156 DagType RefEntity::dag_type(const char* name)
01157 {
01158   if (CubitUtil::compare(name,"body"))
01159     return DagType::body_type();
01160   else if (CubitUtil::compare(name,"volume"))
01161     return DagType::ref_volume_type();
01162   else if (CubitUtil::compare(name,"surface"))
01163     return DagType::ref_face_type();
01164   else if (CubitUtil::compare(name,"curve"))
01165     return DagType::ref_edge_type();
01166   else if (CubitUtil::compare(name,"vertex"))
01167     return DagType::ref_vertex_type();
01168   else
01169     return DagType();
01170 }
01171 
01172 #ifdef CAT
01173 const char* RefEntity::get_ref_class_name(const std::type_info& ref_type)
01174 {
01175   if( ref_type == typeid(RefGroup) )
01176      return RefGroup::get_class_name();
01177   else if( ref_type == typeid(Body) )
01178      return Body::get_class_name();
01179   else if( ref_type == typeid(RefVolume) )
01180      return RefVolume::get_class_name();
01181   else if( ref_type == typeid(RefFace) )
01182      return RefFace::get_class_name();
01183   else if( ref_type == typeid(RefEdge) )
01184      return RefEdge::get_class_name();
01185   else if( ref_type == typeid(RefVertex) )
01186      return RefVertex::get_class_name();
01187   else
01188      return NULL;
01189 }
01190 #endif
01191 
01192 
01193 void RefEntity::color(int value)
01194 {
01195   mColor = value;
01196   AppUtil::instance()->send_event(GeometryEvent(GeometryEvent::ENTITY_GEOMETRY_COLOR_CHANGED, this));
01197 }
01198 
01199 int RefEntity::color() const
01200 {
01201   return mColor;
01202 }
01203 
01204 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines