cgma
|
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