cgma
|
00001 #include "CADeferredAttrib.hpp" 00002 #include "CubitSimpleAttrib.hpp" 00003 #include "ToolDataUser.hpp" 00004 #include "TDUniqueId.hpp" 00005 #include "CastTo.hpp" 00006 #include "RefEntity.hpp" 00007 #include "DLIList.hpp" 00008 #include "CubitMessage.hpp" 00009 #include <algorithm> 00010 00011 std::vector<CubitAttrib*> CADeferredAttrib::unactuatedCAs; 00012 std::vector<CADeferredAttrib*> CADeferredAttrib::allCADeferredAttribs; 00013 00014 CubitAttrib* CADeferredAttrib_creator(RefEntity* entity, const CubitSimpleAttrib& p_csa) 00015 { 00016 CADeferredAttrib *new_attrib = NULL; 00017 00018 // Deferred attributes are a special case -- they should only get created 00019 // when restoring from a file, in which case p_csa should be non-NULL 00020 if (!p_csa.isEmpty()) 00021 { 00022 new_attrib = new CADeferredAttrib(entity, p_csa); 00023 } 00024 return new_attrib; 00025 } 00026 00027 00028 CADeferredAttrib::~CADeferredAttrib() 00029 { 00030 allCADeferredAttribs.erase( 00031 std::remove(allCADeferredAttribs.begin(), allCADeferredAttribs.end(), this), allCADeferredAttribs.end() 00032 ); 00033 } 00034 00035 CADeferredAttrib::CADeferredAttrib(RefEntity *, const CubitSimpleAttrib &csa_ptr) 00036 : CubitAttrib(NULL) 00037 { 00038 init_csa(csa_ptr); 00039 hasUpdated = CUBIT_TRUE; 00040 } 00041 00042 namespace { 00043 struct find_attrib_id 00044 { 00045 int mId; 00046 find_attrib_id(int id) : mId(id) {} 00047 bool operator()(CADeferredAttrib* attr) 00048 { 00049 return attr->unique_id() == mId; 00050 } 00051 }; 00052 00053 } 00054 00055 00056 CubitStatus CADeferredAttrib::init_csa(const CubitSimpleAttrib &csa_ptr) 00057 { 00058 int csa_type = CGMApp::instance()->attrib_manager()->attrib_type(csa_ptr); 00059 if (CA_DEFERRED_ATTRIB != csa_type) 00060 { 00061 assert(false); 00062 return CUBIT_FAILURE; 00063 } 00064 00065 // initialize this according to csa_ptr 00066 00067 // first get the uniqueId off the csa 00068 uniqueId = csa_ptr.int_data_list()[0]; 00069 assert(uniqueId > 0); 00070 00071 // now check to see if we have this CADA alreedy; if so, set the 00072 // delete flag and exit 00073 std::vector<CADeferredAttrib*>::iterator iter = std::find_if(allCADeferredAttribs.begin(), allCADeferredAttribs.end(), find_attrib_id(uniqueId)); 00074 00075 if (iter != allCADeferredAttribs.end()) { 00076 deleteAttrib = CUBIT_TRUE; 00077 return CUBIT_SUCCESS; 00078 } 00079 00080 // copy the info on the csa; need a new one, since 00081 // we don't own the original 00082 thisCSA = csa_from_dcsa(csa_ptr); 00083 assert(!thisCSA.isEmpty()); 00084 00085 // add this to the global list 00086 allCADeferredAttribs.push_back(this); 00087 00088 return CUBIT_SUCCESS; 00089 } 00090 00091 CubitStatus CADeferredAttrib::actuate() 00092 { 00093 // test to see if we can assign this CADA to a new owner; set 00094 // flag accordingly 00095 if (assign_to_owner()) { 00096 hasActuated = CUBIT_TRUE; 00097 return CUBIT_SUCCESS; 00098 } 00099 else return CUBIT_FAILURE; 00100 } 00101 00102 CubitStatus CADeferredAttrib::update() 00103 { 00104 // the hasUpdated flag should always be true by the time 00105 // we get here, since the function that put this CA on the 00106 // owning entity set the flag 00107 assert(hasUpdated == CUBIT_TRUE); 00108 return CUBIT_SUCCESS; 00109 } 00110 00111 CubitStatus CADeferredAttrib::reset() 00112 { 00113 // do nothing; this CA manages its own duplicates, so no need 00114 // to worry about them in parent code 00115 return CUBIT_SUCCESS; 00116 } 00117 00118 CubitSimpleAttrib CADeferredAttrib::cubit_simple_attrib() 00119 { 00120 return thisCSA; 00121 } 00122 00123 CubitStatus CADeferredAttrib::assign_to_owner(CubitAttribUser *owner) 00124 { 00125 //- looks for an entity with the right uid, assigns itself to 00126 //- that entity if found 00127 00128 if (uniqueId == 0) return CUBIT_FAILURE; 00129 00130 if (owner == NULL) { 00131 ToolDataUser *tdu = TDUniqueId::find_td_unique_id(uniqueId); 00132 owner = CAST_TO(tdu, CubitAttribUser); 00133 } 00134 00135 if (owner == NULL) return CUBIT_FAILURE; 00136 00137 // ok, we have an owner; create a new CA using the csa, assigning 00138 // it to the ref entity 00139 RefEntity *ref_ent = CAST_TO(owner, RefEntity); 00140 assert (ref_ent != 0); 00141 00142 // CubitAttrib *new_cubit_attrib = 00143 // CGMApp::instance()->attrib_manager()->create_cubit_attrib(thisCSA, ref_ent); 00144 int attrib_type = CGMApp::instance()->attrib_manager()->attrib_type(thisCSA); 00145 CubitAttrib *new_cubit_attrib = 00146 CGMApp::instance()->attrib_manager()->create_cubit_attrib(attrib_type, ref_ent, thisCSA); 00147 00148 // now remove this CADA from the global list and add the new CA 00149 // to the unactuated list 00150 allCADeferredAttribs.erase( 00151 std::remove(allCADeferredAttribs.begin(), allCADeferredAttribs.end(), this), allCADeferredAttribs.end() 00152 ); 00153 00154 // new attribute might be NULL, if there was already one there 00155 if (NULL != new_cubit_attrib) 00156 unactuatedCAs.push_back(new_cubit_attrib); 00157 00158 // ok, all done 00159 00160 deleteAttrib = CUBIT_TRUE; 00161 return CUBIT_SUCCESS; 00162 } 00163 00164 CubitStatus CADeferredAttrib::get_deferred_attribs(const int uid, 00165 std::vector<CADeferredAttrib*> &cada_list) 00166 { 00167 // find a deferred attribute for the entity with the uid passed in 00168 cada_list.clear(); 00169 00170 for(std::vector<CADeferredAttrib*>::iterator iter=allCADeferredAttribs.begin(); 00171 iter != allCADeferredAttribs.end(); ++iter) 00172 { 00173 if((*iter)->unique_id() == uid) 00174 { 00175 cada_list.push_back(*iter); 00176 } 00177 } 00178 00179 if (cada_list.size() > 0) return CUBIT_SUCCESS; 00180 else return CUBIT_FAILURE; 00181 } 00182 00183 CubitStatus CADeferredAttrib::cleanup_cadas(const CubitBoolean from_constructor, 00184 const CubitBoolean after_geom_changes) 00185 { 00186 CubitStatus status = CUBIT_FAILURE; 00187 00188 if (CUBIT_TRUE == from_constructor) 00189 status = CADeferredAttrib::cleanup_cadas_private(CUBIT_TRUE, CUBIT_FALSE); 00190 00191 // exit if we're not to actuate for after_geom_changes 00192 if (CUBIT_TRUE == after_geom_changes) 00193 status = CADeferredAttrib::cleanup_cadas_private(CUBIT_FALSE, CUBIT_TRUE); 00194 00195 return status; 00196 } 00197 00198 CubitStatus CADeferredAttrib::cleanup_cadas_private(const CubitBoolean from_constructor, 00199 const CubitBoolean after_geom_changes) 00200 { 00201 // moves between the global CADA list and the unactuated list: 00202 // 00203 // 1. tries to actuate all CADAs on unactuated list 00204 // 2. tries to assign_to_owner all CADAs on global list 00205 // 00206 // after each of these steps, if anything happened, the loop is 00207 // repeated 00208 // this function should be called as part of the auto actuate process 00209 00210 // first call for from_constructor and !after_geom_changes attributes 00211 CubitBoolean done = CUBIT_FALSE; 00212 CubitStatus did_something = CUBIT_FAILURE; 00213 00214 while (done == CUBIT_FALSE) { 00215 done = CUBIT_TRUE; 00216 for(std::vector<CubitAttrib*>::iterator iter = unactuatedCAs.begin(); iter != unactuatedCAs.end();) 00217 { 00218 CubitAttrib *attrib = *iter; 00219 if( attrib == 0 ) 00220 { 00221 ++iter; 00222 continue; 00223 } 00224 00225 // check the auto actuate flag for this CA; since this function 00226 // is only called from the auto actuating process, we don't need 00227 // to check whether the user requested that this attribute be actuated 00228 if (attrib->auto_actuate_flag() == CUBIT_TRUE && 00229 (!from_constructor || attrib->actuate_in_constructor()) && 00230 (after_geom_changes || !attrib->actuate_after_geom_changes())) 00231 { 00232 00233 // if the attribute has already actuated, but is still in our list, 00234 // count it as doing something 00235 if ( /*attrib->has_actuated() || */ 00236 attrib->actuate() == CUBIT_SUCCESS) { 00237 PRINT_DEBUG_90("Actuated a CADA of type %s\n", 00238 attrib->att_internal_name()); 00239 did_something = CUBIT_SUCCESS; 00240 done = CUBIT_FALSE; 00241 iter = unactuatedCAs.erase(iter); 00242 } 00243 else 00244 { 00245 ++iter; 00246 } 00247 } 00248 else 00249 { 00250 ++iter; 00251 } 00252 } 00253 00254 if (done == CUBIT_TRUE) break; 00255 00256 // if we did something in the previous loop, some of our CADAs might 00257 // now have owners; check and see 00258 for (std::vector<CADeferredAttrib*>::iterator iter = allCADeferredAttribs.begin(); 00259 iter != allCADeferredAttribs.end(); ++iter) 00260 { 00261 CADeferredAttrib *cada = *iter; 00262 if (cada->assign_to_owner() == CUBIT_SUCCESS) { 00263 PRINT_DEBUG_90("Assigned a CADA to a new owner in CADA::cleanup_cadas\n"); 00264 did_something = CUBIT_SUCCESS; 00265 done = CUBIT_FALSE; 00266 } 00267 } 00268 } 00269 00270 // if there wasn't anthing to do in the first place, we didn't 00271 // really fail 00272 if (did_something == CUBIT_FAILURE && unactuatedCAs.size() == 0) 00273 did_something = CUBIT_SUCCESS; 00274 00275 return did_something; 00276 } 00277 00278 CubitStatus CADeferredAttrib::owner_created(RefEntity *new_owner, const int uid) 00279 { 00280 // for a newly created ref entity, assigns any CADA with the same uid to the 00281 // new entity 00282 00283 // get any CADAs with the same uid 00284 std::vector<CADeferredAttrib*> attrib_list; 00285 get_deferred_attribs(uid, attrib_list); 00286 00287 // now assign them to the owner 00288 for (std::vector<CADeferredAttrib*>::iterator iter = attrib_list.begin(); 00289 iter != attrib_list.end(); ++iter) 00290 { 00291 (*iter)->assign_to_owner(new_owner); 00292 } 00293 00294 if (attrib_list.size() > 0) return CUBIT_SUCCESS; 00295 else return CUBIT_FAILURE; 00296 } 00297 /* 00298 CubitBoolean CADeferredAttrib::is_match(CubitSimpleAttrib *csa_ptr, 00299 const int uid) 00300 { 00301 //- returns true if the simple attribute is deferred type and matches 00302 //- uid 00303 assert(csa_ptr && uid > 0); 00304 csa_ptr.string_data_list()->reset(); 00305 csa_ptr.string_data_list()->step(); 00306 csa_ptr.int_data_list()->reset(); 00307 if (!strcmp(csa_ptr.string_data_list()->get()->c_str(), 00308 CGMApp::instance()->attrib_manager()->att_internal_name(CA_DEFERRED_ATTRIB)) && 00309 *csa_ptr.int_data_list()->get() == uid) 00310 return CUBIT_TRUE; 00311 else 00312 return CUBIT_FALSE; 00313 } 00314 */ 00315 00316 00317 CubitSimpleAttrib CADeferredAttrib::csa_from_dcsa(const CubitSimpleAttrib &csa_ptr, 00318 const int uid) 00319 { 00320 00321 //- given a deferred csa, convert it to a normal csa by removing 00322 //- first type string and first int; if first int doesn't match 00323 //- uid passed in, NULL is returned 00324 if (csa_ptr.string_data_list()[0] != CGMApp::instance()->attrib_manager()->att_internal_name(CA_DEFERRED_ATTRIB)) 00325 // csa isn't deferred type - return 00326 return CubitSimpleAttrib(); 00327 00328 if (uid != 0 && csa_ptr.int_data_list()[0] != uid) 00329 // csa uid doesn't match - return 00330 return CubitSimpleAttrib(); 00331 00332 CubitSimpleAttrib c = csa_ptr; 00333 c.string_data_list().erase(c.string_data_list().begin()); 00334 c.int_data_list().erase(c.int_data_list().begin()); 00335 00336 // else we have a match - build new csa 00337 return c; 00338 } 00339 00340 bool CADeferredAttrib::add_unactuated_ca(CubitAttrib *ca_ptr) 00341 { 00342 std::vector<CubitAttrib*>::iterator iter = std::find(unactuatedCAs.begin(), unactuatedCAs.end(), ca_ptr); 00343 if(iter == unactuatedCAs.end()) 00344 { 00345 unactuatedCAs.push_back(ca_ptr); 00346 return true; 00347 } 00348 return false; 00349 } 00350 00351 bool CADeferredAttrib::remove_unactuated_ca( CubitAttrib* ca_ptr ) 00352 { 00353 std::vector<CubitAttrib*>::iterator iter = std::find(unactuatedCAs.begin(), unactuatedCAs.end(), ca_ptr); 00354 if(iter != unactuatedCAs.end()) 00355 { 00356 *iter = NULL; 00357 return true; 00358 } 00359 return false; 00360 }