Branch data Line data Source code
1 : : //- Class: CAMergePartner
2 : : //- Owner: Greg Nielson
3 : : //- Description: Cubit Attribute for merge partners.
4 : : //- Checked By:
5 : : //- Version:
6 : :
7 : : #include "CAMergePartner.hpp"
8 : : #include "DLIList.hpp"
9 : : #include "SDLCAMergePartnerList.hpp"
10 : : #include "RefEntity.hpp"
11 : : #include "RefFace.hpp"
12 : : #include "RefEdge.hpp"
13 : : #include "RefVertex.hpp"
14 : : #include "TDCompare.hpp"
15 : : #include "TDUniqueId.hpp"
16 : : #include "MergeTool.hpp"
17 : : #include "CastTo.hpp"
18 : : #include "CubitAttribUser.hpp"
19 : : #include "GeometryQueryTool.hpp"
20 : : #include "RefVolume.hpp"
21 : : #include "TopologyBridge.hpp"
22 : :
23 : : #include <stdlib.h>
24 : : #include <time.h>
25 : :
26 : : // factory function
27 : 10150 : CubitAttrib* CAMergePartner_creator(RefEntity* entity, const CubitSimpleAttrib &p_csa)
28 : : {
29 [ + - ]: 10150 : return new CAMergePartner(entity, p_csa);
30 : : }
31 : :
32 : 10150 : CAMergePartner::CAMergePartner(RefEntity* new_attrib_owner,
33 : : const CubitSimpleAttrib &csa_ptr)
34 : 10150 : : CubitAttrib(new_attrib_owner)
35 : : {
36 [ + - ]: 10150 : initialize();
37 : :
38 [ + - ][ + + ]: 10150 : if(!csa_ptr.isEmpty())
39 : : {
40 [ + - ][ + - ]: 558 : int i_temp = csa_ptr.int_data_list()[0];
41 : 558 : mergeID = i_temp;
42 [ + - ][ + - ]: 558 : if( csa_ptr.int_data_list().size() > 1 )
[ + - ]
43 : : {
44 [ + - ][ + - ]: 558 : i_temp = csa_ptr.int_data_list()[1];
45 [ - + - - ]: 558 : switch( i_temp ) {
46 : 0 : case -1: bridge_sense_ = CUBIT_REVERSED; break;
47 : 558 : case 1: bridge_sense_ = CUBIT_FORWARD; break;
48 : 0 : case 0: bridge_sense_ = CUBIT_UNKNOWN; break;
49 : 558 : default: bridge_sense_ = CUBIT_UNKNOWN; assert(0);
50 : : }
51 : : }
52 : : }
53 : 10150 : }
54 : :
55 : 30450 : CAMergePartner::~CAMergePartner()
56 : : {
57 : : //
58 : 10150 : mergeID = 0;
59 [ - + ]: 20300 : }
60 : :
61 : :
62 : 10150 : void CAMergePartner::initialize()
63 : : {
64 : 10150 : mergeID = -1;
65 : 10150 : bridge_sense_ = CUBIT_UNKNOWN;
66 : 10150 : isSurvivor = 0;
67 : 10150 : }
68 : :
69 : :
70 : 558 : CubitStatus CAMergePartner::actuate()
71 : : {
72 : 558 : hasActuated = CUBIT_TRUE;
73 : 558 : return CUBIT_SUCCESS;
74 : : //We don't need to actuate this attribute here since the merging
75 : : //happens in GeometryQueryTool::check_mergeable_refentity.
76 : :
77 : : /*
78 : : if (hasActuated == CUBIT_TRUE) return CUBIT_SUCCESS;
79 : :
80 : : BasicTopologyEntity * bte_ptr = CAST_TO(attribOwnerEntity,BasicTopologyEntity);
81 : : if (bte_ptr == NULL || bte_ptr->deactivated() == CUBIT_TRUE)
82 : : return CUBIT_FAILURE;
83 : :
84 : : DLIList<RefEntity*> merge_list;
85 : : //merge_prepare(merge_list);
86 : : merge_list.append_unique(attribOwnerEntity);
87 : :
88 : : CubitStatus result = CUBIT_SUCCESS;
89 : :
90 : : if (merge_list.size() > 1)
91 : : result = (NULL == MergeTool::instance()->force_merge(merge_list))
92 : : ? CUBIT_FAILURE : CUBIT_SUCCESS;
93 : :
94 : : if( result )
95 : : {
96 : : hasActuated = CUBIT_TRUE;
97 : : }
98 : :
99 : : return result; */
100 : : }
101 : :
102 : 0 : void CAMergePartner::merge_prepare(DLIList<RefEntity*> &merge_list)
103 : : {
104 [ # # ]: 0 : DLIList<CubitAttrib*> my_ca_list;
105 : : CAMergePartner *my_camp_ptr;
106 : : RefEntity* re_ptr;
107 : :
108 : : // get all the merge partner attributes that are on my owner
109 [ # # ]: 0 : attribOwnerEntity->find_cubit_attrib_type(CA_MERGE_PARTNER, my_ca_list);
110 [ # # ]: 0 : merge_list.clean_out();
111 [ # # ][ # # ]: 0 : DLIList<ToolDataUser*> td_list, temp_td_list;
[ # # ][ # # ]
112 : : int i;
113 [ # # ][ # # ]: 0 : for (i = my_ca_list.size(); i > 0; i--)
114 : : {
115 [ # # ][ # # ]: 0 : my_camp_ptr = CAST_TO(my_ca_list.get(),CAMergePartner);
116 [ # # ]: 0 : my_ca_list.step();
117 [ # # ]: 0 : td_list.clean_out();
118 : : // get all the objects with this unique id (which is also the merge id)
119 [ # # ][ # # ]: 0 : TDUniqueId::find_td_unique_id(my_camp_ptr->merge_id(), temp_td_list);
120 [ # # ]: 0 : td_list += temp_td_list;
121 : : }
122 : :
123 : : // now put those entities into the merge_list
124 [ # # ][ # # ]: 0 : for (i = td_list.size(); i > 0; i--)
125 : : {
126 [ # # ][ # # ]: 0 : re_ptr = CAST_TO(td_list.get(), RefEntity);
127 [ # # ]: 0 : if (re_ptr)
128 : : {
129 [ # # ]: 0 : CubitAttrib *tmp_attrib = re_ptr->get_cubit_attrib( CA_MERGE_PARTNER, CUBIT_FALSE );
130 [ # # ]: 0 : if( tmp_attrib )
131 [ # # ]: 0 : merge_list.append(re_ptr);
132 : : }
133 [ # # ]: 0 : td_list.step();
134 : : }
135 : :
136 : : // Now get bridge sense for each entity in list.
137 : : // Add this entity to list, too.
138 [ # # ]: 0 : merge_list.append( attribOwnerEntity );
139 [ # # ][ # # ]: 0 : for( i = merge_list.size(); i--; )
140 : : {
141 [ # # ]: 0 : RefEntity* ent = merge_list.get_and_step();
142 [ # # ]: 0 : TopologyEntity* te = dynamic_cast<TopologyEntity*>(ent);
143 [ # # ][ # # ]: 0 : if( te->bridge_manager()->number_of_bridges() != 1 )
[ # # ]
144 : 0 : continue;
145 : :
146 [ # # ]: 0 : my_ca_list.clean_out();
147 [ # # ]: 0 : ent->find_cubit_attrib_type(CA_MERGE_PARTNER, my_ca_list);
148 [ # # ][ # # ]: 0 : assert( my_ca_list.size() < 2);
149 [ # # ][ # # ]: 0 : if( !my_ca_list.size() )
150 : 0 : continue;
151 : :
152 [ # # ][ # # ]: 0 : my_camp_ptr = dynamic_cast<CAMergePartner*>(my_ca_list.get());
153 [ # # ][ # # ]: 0 : if( my_camp_ptr->bridge_sense() == CUBIT_UNKNOWN )
154 : 0 : continue;
155 : : }
156 [ # # ]: 0 : merge_list.pop(); // take attribOwnerEntity back off list
157 : :
158 [ # # ]: 0 : return;
159 : : }
160 : :
161 : 96 : CubitStatus CAMergePartner::actuate_list(DLIList<RefEntity*> entity_list)
162 : : {
163 : :
164 : : // given a list of ref entities (usually all entities of a given type),
165 : : // actuate the camp's on those entities
166 : : RefEntity *ref_ent, *keeper;
167 [ + - ]: 96 : DLIList<CubitAttrib*> ca_list;
168 [ + - ][ + - ]: 192 : DLIList<TopologyBridge*> bridge_list(entity_list.size());
[ + - ]
169 [ + - ][ + - ]: 192 : SDLCAMergePartnerList sorted_camp_list;
170 : : int i;
171 [ + - ][ + + ]: 1722 : for(i = entity_list.size(); i > 0; i--)
172 : : {
173 [ + - ]: 1626 : ref_ent = entity_list.get_and_step();
174 [ + - ]: 1626 : ca_list.clean_out();
175 [ + - ]: 1626 : ref_ent->find_cubit_attrib_type(CA_MERGE_PARTNER, ca_list);
176 [ + - ][ - + ]: 1626 : assert(ca_list.size() < 2); // There should only be one
177 : : // merge partner per entity
178 [ + - ][ + + ]: 1626 : if(ca_list.size() > 0)
179 : : {
180 [ + - ][ - + ]: 558 : CAMergePartner* attrib = dynamic_cast<CAMergePartner*>(ca_list.get());
181 [ + - ]: 558 : sorted_camp_list.append( attrib );
182 [ - + ]: 558 : TopologyEntity* te = dynamic_cast<TopologyEntity*>(ref_ent);
183 [ + - ][ + - ]: 558 : TopologyBridge* bridge = te->bridge_manager()->topology_bridge();
184 [ + - ]: 558 : bridge_list.append(bridge);
185 : : }
186 : : }
187 [ + - ]: 96 : sorted_camp_list.sort();
188 [ + - ]: 96 : sorted_camp_list.reset();
189 : :
190 [ + - ][ + - ]: 96 : if (DEBUG_FLAG(90)) {
[ - + ]
191 [ # # ][ # # ]: 0 : for (i = sorted_camp_list.size(); i > 0; i--) {
192 [ # # ]: 0 : CAMergePartner *camp_ptr = sorted_camp_list.get_and_step();
193 [ # # ]: 0 : ref_ent = camp_ptr->attrib_owner();
194 [ # # ][ # # ]: 0 : PRINT_DEBUG_90("%s %d, unique id = %d\n", ref_ent->class_name(),
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
195 [ # # ]: 0 : ref_ent->id(), camp_ptr->merge_id());
196 : : }
197 : : }
198 : :
199 : : // now go through all the camp's for the entity list; peel off
200 : : // camp's with the same id, and merge the associated entities together
201 [ + - ][ + + ]: 654 : while (sorted_camp_list.size() > 0)
202 : : {
203 [ + - ]: 558 : DLIList<RefEntity*> refent_list;
204 [ + - ][ + - ]: 1116 : DLIList<CubitAttrib*> camp_list;
[ - + ]
205 : 558 : keeper = NULL;
206 : :
207 : : // get the next list of entities with the same camp id
208 [ + - ]: 558 : sorted_camp_list.last();
209 [ + - ]: 558 : CAMergePartner *camp_ptr = sorted_camp_list.remove();
210 [ + - ]: 558 : sorted_camp_list.back();
211 [ + - ]: 558 : camp_list.append(camp_ptr);
212 [ + - ]: 558 : int current_id = camp_ptr->merge_id();
213 [ + - ][ + + ]: 1020 : while (sorted_camp_list.size() > 0 &&
[ - + ][ - + ]
214 [ + - ][ + - ]: 462 : sorted_camp_list.get()->merge_id() == current_id) {
215 [ # # ][ # # ]: 0 : camp_list.append(sorted_camp_list.remove());
216 [ # # ]: 0 : sorted_camp_list.back();
217 : : }
218 : :
219 [ + - ][ + - ]: 558 : if (camp_list.size() == 1) continue;
220 : :
221 [ # # ][ # # ]: 0 : CubitBoolean has_actuated = camp_list.get()->has_actuated();
222 : :
223 : : // check the has actuated flag; if one is set, they all should be;
224 : : // also, compile list of ref entities while we're at it
225 [ # # ][ # # ]: 0 : for (current_id = camp_list.size(); current_id > 0; current_id--) {
226 [ # # ][ # # ]: 0 : ref_ent = camp_list.get()->attrib_owner();
227 [ # # ]: 0 : refent_list.append(ref_ent);
228 [ # # ][ # # ]: 0 : if (!keeper || ref_ent->id() < keeper->id()) keeper = ref_ent;
[ # # ][ # # ]
[ # # ]
229 [ # # ][ # # ]: 0 : assert(camp_list.get()->has_actuated() == has_actuated);
[ # # ]
230 [ # # ]: 0 : camp_list.step();
231 : : }
232 : :
233 : : // if they have already actuated, go on to next ones
234 [ # # ]: 0 : if (has_actuated == CUBIT_TRUE) continue;
235 : :
236 : : // otherwise merge
237 [ # # ][ # # ]: 0 : if(refent_list.size() > 1)
238 [ # # ][ # # ]: 0 : MergeTool::instance()->force_merge(refent_list);
239 : :
240 : : // remove the cubit attribute from the surviving parent
241 [ # # ][ + - ]: 558 : keeper->remove_cubit_attrib(CA_MERGE_PARTNER);
[ - + ]
242 : :
243 : 558 : } // loop over existing camp's
244 : :
245 [ + - ]: 96 : return CUBIT_SUCCESS;
246 : : }
247 : :
248 : 9592 : CubitStatus CAMergePartner::update()
249 : : {
250 [ - + ]: 9592 : if (hasUpdated) return CUBIT_SUCCESS;
251 : :
252 : : // set the updated flag
253 : 9592 : hasUpdated = CUBIT_TRUE;
254 [ - + ]: 9592 : BasicTopologyEntity* bte_ptr = CAST_TO(attribOwnerEntity, BasicTopologyEntity);
255 : :
256 [ + + ][ + - ]: 9592 : if( (bte_ptr == NULL) || (dynamic_cast<RefVolume*>(bte_ptr) != NULL))
[ + + ][ + + ]
257 : : {
258 : 818 : delete_attrib(CUBIT_TRUE);
259 : : }
260 [ + + + - ]: 16792 : else if( (bte_ptr->bridge_manager()->number_of_bridges() == 1) &&
[ + + ]
261 : 8018 : (bte_ptr->bridge_manager()->topology_bridge()->bridge_sense() != CUBIT_REVERSED) )
262 : : {
263 : 8018 : delete_attrib(CUBIT_TRUE);
264 : : }
265 : : else
266 : : {
267 : : // get the merge id from the TDUniqueId for the owner entity
268 [ + - ]: 756 : mergeID = TDUniqueId::get_unique_id(attribOwnerEntity);
269 : 756 : bridge_sense_ = CUBIT_UNKNOWN;
270 : 756 : isSurvivor = 0;
271 : : }
272 : :
273 : 9592 : return CUBIT_SUCCESS;
274 : : }
275 : :
276 : 11662 : CubitSimpleAttrib CAMergePartner::cubit_simple_attrib()
277 : : {
278 [ + - ]: 11662 : std::vector<CubitString> cs_list;
279 [ + - ][ + - ]: 23324 : std::vector<double> d_list;
280 [ + - ][ + - ]: 23324 : std::vector<int> i_list;
281 : :
282 [ + - ]: 11662 : i_list.push_back(mergeID);
283 [ + - ][ + - ]: 11662 : cs_list.push_back(att_internal_name());
[ + - ][ + - ]
284 : :
285 [ + - ][ + - ]: 23324 : return CubitSimpleAttrib(&cs_list, &d_list, &i_list);
286 : : }
287 : :
288 : 3024 : void CAMergePartner::set_survivor( CubitSimpleAttrib& csa, int is_survivor )
289 : : {
290 : : //get the list we want to modify from the CSA
291 : 3024 : std::vector<int>& data = csa.int_data_list();
292 : :
293 : : //change or append?
294 [ + + ]: 3024 : if( data.size() >= 4 )
295 : : {
296 : 1512 : data[3] = is_survivor;
297 : : }
298 : : else
299 : : {
300 [ - + ]: 1512 : assert( data.size() == 3 );
301 : 1512 : data.push_back(is_survivor);
302 : : }
303 : 3024 : }
304 : :
305 : 3024 : void CAMergePartner::set_bridge_sense( CubitSimpleAttrib& csa, CubitSense sense )
306 : : {
307 : : //encode/decode sense as:
308 : : // CUBIT_FORWARD : 1
309 : : // CUBIT_REVERSE : -1
310 : : // CUBIT_UNKNOWN : 0
311 : 3024 : int i = 0;
312 [ + + - - ]: 3024 : switch( sense ) {
313 : 2892 : case CUBIT_FORWARD : i = 1; break;
314 : 132 : case CUBIT_REVERSED : i = -1; break;
315 : 0 : case CUBIT_UNKNOWN : i = 0; break;
316 : 0 : default: assert(0);
317 : : }
318 : :
319 : : //get the list we want to modify from the CSA
320 [ + - ]: 3024 : std::vector<int>& data = csa.int_data_list();
321 : :
322 : : //change or append?
323 [ + - ][ + + ]: 3024 : if( data.size() >= 2 )
324 : : {
325 [ + - ]: 1512 : data[1] = i;
326 : : }
327 : : else
328 : : {
329 [ + - ][ - + ]: 1512 : assert( data.size() == 1 );
330 [ + - ]: 1512 : data.push_back(i);
331 : : }
332 : 3024 : }
333 : 558 : CubitBoolean CAMergePartner::is_survivor( const CubitSimpleAttrib& csa )
334 : : {
335 : 558 : const std::vector<int>& data = csa.int_data_list();
336 [ + - ]: 558 : if( data.size() >= 4)
337 : : {
338 : 558 : int i = data[3];
339 [ - + ]: 558 : if( i == 1 )
340 : 558 : return true;
341 : : }
342 : 558 : return false;
343 : : }
344 : :
345 : :
346 : 558 : CubitSense CAMergePartner::get_bridge_sense( const CubitSimpleAttrib& csa )
347 : : {
348 : 558 : const std::vector<int>& data = csa.int_data_list();
349 [ + - ]: 558 : if( data.size() >= 2)
350 : : {
351 : 558 : int i = data[1];
352 [ + + - - ]: 558 : switch(i) {
353 : 514 : case 1: return CUBIT_FORWARD;
354 : 44 : case -1: return CUBIT_REVERSED;
355 : 0 : default: assert(0); // if -DNDEBUG, fall through to unknown
356 : 0 : case 0: return CUBIT_UNKNOWN;
357 : : }
358 : : }
359 : :
360 : 0 : return CUBIT_UNKNOWN;
361 : : }
362 : :
363 : 3024 : void CAMergePartner::set_saved_id( CubitSimpleAttrib& csa, int id )
364 : : {
365 : : //get the list we want to modify from the CSA
366 : 3024 : std::vector<int>& data = csa.int_data_list();
367 : :
368 : : // ID goes after bridge sense, so save bridge sense first
369 [ - + ]: 3024 : if (data.size() == 1)
370 : 0 : set_bridge_sense( csa, CUBIT_UNKNOWN );
371 : :
372 : : // change?
373 [ + + ]: 3024 : if (data.size() > 2 )
374 : : {
375 : 1512 : data[2] = id;
376 : : }
377 : : // set?
378 : : else
379 : : {
380 [ - + ]: 1512 : assert(data.size() == 2);
381 : 1512 : data.push_back(id);
382 : : }
383 : 3024 : }
384 : :
385 : 558 : int CAMergePartner::get_saved_id( const CubitSimpleAttrib& csa )
386 : : {
387 : : //get the list we want to modify from the CSA
388 : 558 : const std::vector<int>& data = csa.int_data_list();
389 : :
390 [ - + ]: 558 : if (data.size() < 3)
391 : 0 : return 0;
392 : :
393 : 558 : return data[2];
394 : : }
395 : :
396 : :
397 : :
398 : 0 : void CAMergePartner::print()
399 : : {
400 [ # # ]: 0 : PRINT_INFO("Attribute MERGE_PARTNER, %s %d: mergeId = %d, sense = %d.\n",
401 : : attribOwnerEntity->class_name(), attribOwnerEntity->id(),
402 [ # # ]: 0 : mergeID, bridge_sense_);
403 [ + - ][ + - ]: 6540 : }
|