MOAB: Mesh Oriented datABase  (version 5.5.0)
AssocPair.cpp
Go to the documentation of this file.
1 #include "AssocPair.hpp"
2 
3 #include <cstdlib>
4 
5 #include "Lasso.hpp"
6 
7 #ifdef ENABLE_IGEOM
8 #include "GeomAssocPairSide.hpp"
9 #endif
10 #ifdef ENABLE_FBIGEOM
11 #include "FBGeomAssocPairSide.hpp"
12 #endif
13 #ifdef ENABLE_IMESH
14 #include "MeshAssocPairSide.hpp"
15 #endif
16 
17 int AssocPair::currId = 0;
18 
20  iBase_Instance iface0,
21  iRel_RelationType ent_or_set0,
22  iRel_IfaceType type0,
23  iRel_RelationStatus p_status0,
24  iBase_Instance iface1,
25  iRel_RelationType ent_or_set1,
26  iRel_IfaceType type1,
27  iRel_RelationStatus p_status1 )
28  : instance( p_instance )
29 {
30  pairId = currId++;
31 
32  iBase_Instance ifaces[] = { iface0, iface1 };
33  iRel_IfaceType types[] = { type0, type1 };
34  for( int i = 0; i < 2; i++ )
35  {
36  switch( types[i] )
37  {
38 #ifdef ENABLE_IGEOM
39  case iRel_IGEOM_IFACE:
40  relSides[i] = new GeomAssocPairSide( instance, ifaces[i], pairId );
41  break;
42 #endif
43 #ifdef ENABLE_FBIGEOM
44  case iRel_FBIGEOM_IFACE:
45  relSides[i] = new FBGeomAssocPairSide( instance, ifaces[i], pairId );
46  break;
47 #endif
48 #ifdef ENABLE_IMESH
49  case iRel_IMESH_IFACE:
50  relSides[i] = new MeshAssocPairSide( instance, ifaces[i], pairId );
51  break;
52 #endif
53  default:
54  relSides[i] = NULL;
55  }
56  }
57 
58  entOrSet[0] = ent_or_set0;
59  entOrSet[1] = ent_or_set1;
60  relStatus[0] = p_status0;
61  relStatus[1] = p_status1;
62 }
63 
65 {
66  for( int i = 0; i < 2; i++ )
67  delete relSides[i];
68 }
69 
70 int AssocPair::get_all_entities( int iface_no,
71  int dimension,
73  int* entities_alloc,
74  int* entities_size )
75 {
76  return relSides[iface_no]->get_all_entities( dimension, entities, entities_alloc, entities_size );
77 }
78 
79 int AssocPair::get_all_sets( int iface_no, iBase_EntitySetHandle** sets, int* sets_alloc, int* sets_size )
80 {
81  return relSides[iface_no]->get_all_sets( sets, sets_alloc, sets_size );
82 }
83 
84 int AssocPair::get_entities( int iface_no,
85  int dimension,
86  iBase_EntitySetHandle set_handle,
88  int* entities_alloc,
89  int* entities_size )
90 {
91  return relSides[iface_no]->get_entities( dimension, set_handle, entities, entities_alloc, entities_size );
92 }
93 
94 int AssocPair::get_ents_dims( int iface_no,
96  int entities_size,
97  int** ent_types,
98  int* ent_types_alloc,
99  int* ent_types_size )
100 {
101  return relSides[iface_no]->get_ents_dims( entities, entities_size, ent_types, ent_types_alloc, ent_types_size );
102 }
103 
105 {
106  if( entOrSet[0] == iRel_SET || entOrSet[1] == iRel_SET ) ERRORR( iBase_FAILURE, "Invalid relation type" );
107 
108  // check that if we're passing in an ent for a 'both'-type
109  // assoc, there's already a set associated to the other ent
110  iBase_EntityHandle tmp_ent;
111  if( entOrSet[0] == iRel_BOTH && relSides[1]->get_relation_side( &ent2, 1, &tmp_ent ) != iBase_SUCCESS )
112  ERRORR( iBase_FAILURE, "Couldn't find associated set on left side" );
113  if( entOrSet[1] == iRel_BOTH && relSides[0]->get_relation_side( &ent1, 1, &tmp_ent ) != iBase_SUCCESS )
114  ERRORR( iBase_FAILURE, "Couldn't find associated set on right side" );
115 
116  // set ent1 => ent2
117  if( relStatus[0] == iRel_ACTIVE ) CHK_ERRORR( relSides[0]->set_relation_side( &ent1, 1, &ent2 ) );
118 
119  // set ent1 <= ent2
120  if( relStatus[1] == iRel_ACTIVE ) CHK_ERRORR( relSides[1]->set_relation_side( &ent2, 1, &ent1 ) );
121 
123 }
124 
126 {
127  if( entOrSet[0] == iRel_SET || entOrSet[1] == iRel_ENTITY ) ERRORR( iBase_FAILURE, "Invalid relation type" );
128 
129  // check that if we're passing in an ent for a 'both'-type
130  // assoc, there's already a set associated to the other ent
131  iBase_EntityHandle tmp_ent;
132  if( entOrSet[0] == iRel_BOTH && relSides[1]->get_relation_side( &set2, 1, &tmp_ent ) != iBase_SUCCESS )
133  ERRORR( iBase_FAILURE, "Couldn't find associated set on left side" );
134 
135  // set ent1 => set2
136  if( relStatus[0] == iRel_ACTIVE ) CHK_ERRORR( relSides[0]->set_relation_side( &ent1, 1, &set2 ) );
137 
138  // set ent1 <= set2
139  if( relStatus[1] == iRel_ACTIVE ) CHK_ERRORR( relSides[1]->set_relation_side( &set2, 1, &ent1 ) );
140 
141  // if the right side is a 'both'-type association, set the contents of set2
142  // to point to ent1 as well
143  if( entOrSet[1] == iRel_BOTH ) CHK_ERRORR( populate_recursive( 1, set2, ent1 ) );
144 
146 }
147 
149 {
150  if( entOrSet[0] == iRel_ENTITY || entOrSet[1] == iRel_SET ) ERRORR( iBase_FAILURE, "Invalid relation type" );
151 
152  // check that if we're passing in an ent for a 'both'-type
153  // assoc, there's already a set associated to the other ent
154  iBase_EntityHandle tmp_ent;
155  if( entOrSet[1] == iRel_BOTH && relSides[0]->get_relation_side( &set1, 1, &tmp_ent ) != iBase_SUCCESS )
156  ERRORR( iBase_FAILURE, "Couldn't find associated set on right side" );
157 
158  // set set1 => ent2
159  if( relStatus[0] == iRel_ACTIVE ) CHK_ERRORR( relSides[0]->set_relation_side( &set1, 1, &ent2 ) );
160 
161  // set ent1 <= set2
162  if( relStatus[1] == iRel_ACTIVE ) CHK_ERRORR( relSides[1]->set_relation_side( &ent2, 1, &set1 ) );
163 
164  // if the left side is a 'both'-type association, set the contents of set1
165  // to point to ent2 as well
166  if( entOrSet[0] == iRel_BOTH ) CHK_ERRORR( populate_recursive( 0, set1, ent2 ) );
167 
169 }
170 
172 {
173  if( entOrSet[0] == iRel_ENTITY || entOrSet[1] == iRel_ENTITY ) ERRORR( iBase_FAILURE, "Invalid relation type" );
174 
175  // set set1 => set2
176  if( relStatus[0] == iRel_ACTIVE ) CHK_ERRORR( relSides[0]->set_relation_side( &set1, 1, &set2 ) );
177 
178  // set set1 <= set2
179  if( relStatus[1] == iRel_ACTIVE ) CHK_ERRORR( relSides[1]->set_relation_side( &set2, 1, &set1 ) );
180 
181  // if either side is a 'both'-type association, set the contents of set1
182  // to point to set2 as well (and/or vice-versa)
183  if( entOrSet[0] == iRel_BOTH ) CHK_ERRORR( populate_recursive( 0, set1, set2 ) );
184  if( entOrSet[1] == iRel_BOTH ) CHK_ERRORR( populate_recursive( 1, set2, set1 ) );
185 
187 }
188 
189 int AssocPair::get_relation( int iface_no,
191  int num_entities,
192  iBase_EntityHandle* tag_values )
193 {
194  if( relStatus[iface_no] == iRel_NOTEXIST ) ERRORR( iBase_FAILURE, "Relation does not exist on this side" );
195  if( entOrSet[!iface_no] != iRel_ENTITY ) // other iface is sets
196  ERRORR( iBase_INVALID_ENTITY_HANDLE, "Expected EntitySet, got Entity" );
197 
198  return relSides[iface_no]->get_relation_side( entities, num_entities, tag_values );
199 }
200 
201 int AssocPair::get_relation( int iface_no, iBase_EntitySetHandle* sets, int num_sets, iBase_EntityHandle* tag_values )
202 {
203  if( relStatus[iface_no] == iRel_NOTEXIST ) ERRORR( iBase_FAILURE, "Relation does not exist on this side" );
204  if( entOrSet[!iface_no] != iRel_ENTITY ) // other iface is sets
205  ERRORR( iBase_INVALID_ENTITY_HANDLE, "Expected EntitySet, got Entity" );
206 
207  return relSides[iface_no]->get_relation_side( sets, num_sets, tag_values );
208 }
209 
210 int AssocPair::get_relation( int iface_no,
212  int num_entities,
213  iBase_EntitySetHandle* tag_values )
214 {
215  if( relStatus[iface_no] == iRel_NOTEXIST ) ERRORR( iBase_FAILURE, "Relation does not exist on this side" );
216  if( entOrSet[!iface_no] == iRel_ENTITY ) // other iface is not sets
217  ERRORR( iBase_INVALID_ENTITY_HANDLE, "Expected Entity, got EntitySet" );
218 
219  return relSides[iface_no]->get_relation_side( entities, num_entities, tag_values );
220 }
221 
222 int AssocPair::get_relation( int iface_no,
223  iBase_EntitySetHandle* sets,
224  int num_sets,
225  iBase_EntitySetHandle* tag_values )
226 {
227  if( relStatus[iface_no] == iRel_NOTEXIST ) ERRORR( iBase_FAILURE, "Relation does not exist on this side" );
228  if( entOrSet[!iface_no] == iRel_ENTITY ) // other iface is not sets
229  ERRORR( iBase_INVALID_ENTITY_HANDLE, "Expected Entity, got EntitySet" );
230 
231  return relSides[iface_no]->get_relation_side( sets, num_sets, tag_values );
232 }
233 
234 int AssocPair::get_relation( int iface_no,
236  int num_entities,
237  iBase_EntityIterator* tag_values )
238 {
239  std::vector< iBase_EntitySetHandle > sets( num_entities );CHK_ERRORR( get_relation( iface_no, entities, num_entities, &sets[0] ) );
240 
241  for( int i = 0; i < num_entities; i++ )
242  CHK_ERRORR( relSides[i]->get_iterator( sets[i], &tag_values[i] ) );
243 
245 }
246 
247 int AssocPair::get_relation( int iface_no, iBase_EntitySetHandle* sets, int num_sets, iBase_EntityIterator* tag_values )
248 {
249  std::vector< iBase_EntitySetHandle > sets2( num_sets );CHK_ERRORR( get_relation( iface_no, sets, num_sets, &sets2[0] ) );
250 
251  for( int i = 0; i < num_sets; i++ )
252  CHK_ERRORR( relSides[iface_no]->get_iterator( sets2[i], &tag_values[i] ) );
253 
255 }
256 
257 int AssocPair::rmv_relation( int iface_no, iBase_EntityHandle* entities, int num_entities )
258 {
259  if( relStatus[iface_no] == iRel_NOTEXIST ) ERRORR( iBase_FAILURE, "Relation does not exist on this side" );
260 
261  // TODO: handle "both" case
262 
263  // Remove the opposite side first
264  if( relStatus[!iface_no] == iRel_ACTIVE )
265  {
266  if( entOrSet[!iface_no] == iRel_ENTITY )
267  {
268  std::vector< iBase_EntityHandle > other_entities( num_entities );CHK_ERRORR( get_relation( iface_no, entities, num_entities, &other_entities[0] ) );CHK_ERRORR( relSides[!iface_no]->rmv_relation_side( &other_entities[0], num_entities ) );
269  }
270  else
271  {
272  std::vector< iBase_EntitySetHandle > other_sets( num_entities );CHK_ERRORR( get_relation( iface_no, entities, num_entities, &other_sets[0] ) );CHK_ERRORR( relSides[!iface_no]->rmv_relation_side( &other_sets[0], num_entities ) );
273  }
274  }
275 
276  return relSides[iface_no]->rmv_relation_side( entities, num_entities );
277 }
278 
279 int AssocPair::rmv_relation( int iface_no, iBase_EntitySetHandle* sets, int num_sets )
280 {
281  if( relStatus[iface_no] == iRel_NOTEXIST ) ERRORR( iBase_FAILURE, "Relation does not exist on this side" );
282 
283  // TODO: handle "both" case
284 
285  // Remove the opposite side first
286  if( relStatus[!iface_no] == iRel_ACTIVE )
287  {
288  if( entOrSet[!iface_no] == iRel_ENTITY )
289  {
290  std::vector< iBase_EntityHandle > other_entities( num_sets );CHK_ERRORR( get_relation( iface_no, sets, num_sets, &other_entities[0] ) );CHK_ERRORR( relSides[!iface_no]->rmv_relation_side( &other_entities[0], num_sets ) );
291  }
292  else
293  {
294  std::vector< iBase_EntitySetHandle > other_sets( num_sets );CHK_ERRORR( get_relation( iface_no, sets, num_sets, &other_sets[0] ) );CHK_ERRORR( relSides[!iface_no]->rmv_relation_side( &other_sets[0], num_sets ) );
295  }
296  }
297 
298  return relSides[iface_no]->rmv_relation_side( sets, num_sets );
299 }
300 
301 int AssocPair::get_gids( int iface_no, iBase_EntityHandle* entities, int num_entities, int* tag_values )
302 {
303  return relSides[iface_no]->get_gids( entities, num_entities, tag_values );
304 }
305 
306 int AssocPair::get_gids( int iface_no, iBase_EntitySetHandle* sets, int num_sets, int* tag_values )
307 {
308  return relSides[iface_no]->get_gids( sets, num_sets, tag_values );
309 }
310 
311 int AssocPair::get_dims( int iface_no, iBase_EntityHandle* entities, int num_entities, int* tag_values )
312 {
313  return relSides[iface_no]->get_dims( entities, num_entities, tag_values );
314 }
315 
316 int AssocPair::get_dims( int iface_no, iBase_EntitySetHandle* sets, int num_sets, int* tag_values )
317 {
318  return relSides[iface_no]->get_dims( sets, num_sets, tag_values );
319 }
320 
321 int AssocPair::change_type( int iface_no, iRel_RelationType type )
322 {
323  if( entOrSet[iface_no] == type ) RETURNR( iBase_SUCCESS );
324  if( entOrSet[iface_no] == iRel_ENTITY || type == iRel_ENTITY )
325  ERRORR( iBase_FAILURE, "Can only change type from \"set\" to \"both\", or "
326  "vice-versa" );
327 
328  entOrSet[iface_no] = type;
329  if( relStatus[iface_no] != iRel_ACTIVE ) RETURNR( iBase_SUCCESS );
330 
331  iBase_EntitySetHandle* sets = NULL;
332  int set_alloc = 0, set_size;CHK_ERRORR( relSides[iface_no]->get_related_sets( &sets, &set_alloc, &set_size ) );
333  if( type == iRel_BOTH )
334  {
335  if( entOrSet[!iface_no] == iRel_ENTITY )
336  {
337  std::vector< iBase_EntityHandle > related_ents( set_size );CHK_ERRORR( relSides[iface_no]->get_relation_side( sets, set_size, &related_ents[0] ) );
338 
339  for( int i = 0; i < set_size; i++ )
340  CHK_ERRORR( populate_recursive( iface_no, sets[i], related_ents[i] ) );
341  }
342  else
343  {
344  std::vector< iBase_EntitySetHandle > related_sets( set_size );CHK_ERRORR( relSides[iface_no]->get_relation_side( sets, set_size, &related_sets[0] ) );
345 
346  for( int i = 0; i < set_size; i++ )
347  CHK_ERRORR( populate_recursive( iface_no, sets[i], related_sets[i] ) );
348  }
349  }
350  else if( type == iRel_SET )
351  {
352  for( int i = 0; i < set_size; i++ )
353  CHK_ERRORR( unpopulate_recursive( iface_no, sets[i] ) );
354  }
355 
356  free( sets );
358 }
359 
361 {
362  if( relStatus[iface_no] == status ) RETURNR( iBase_SUCCESS );
363 
364  relStatus[iface_no] = status;
365 
366  if( status == iRel_NOTEXIST )
367  {
368  // Destroy the assoc tag
369  CHK_ERRORR( relSides[iface_no]->destroy_relation_side() );
370  }
371  else if( status == iRel_INACTIVE )
372  {
373  // Create the assoc tag
374  CHK_ERRORR( relSides[iface_no]->create_relation_side() );
375  }
376  // Update the assoc tag
377  else if( status == iRel_ACTIVE )
378  {
379  CHK_ERRORR( relSides[iface_no]->destroy_relation_side() );CHK_ERRORR( relSides[iface_no]->create_relation_side() );
380 
381  if( entOrSet[!iface_no] == iRel_ENTITY )
382  {
384  int ent_alloc = 0, ent_size;
385 
386  CHK_ERRORR( relSides[!iface_no]->get_related_ents( &entities, &ent_alloc, &ent_size ) );
387  if( entOrSet[iface_no] == iRel_ENTITY )
388  {
389  std::vector< iBase_EntityHandle > related_ents( ent_size );
390  int result = relSides[!iface_no]->get_relation_side( entities, ent_size, &related_ents[0] );
391 
392  if( result == iBase_SUCCESS )
393  {
394  if( iface_no == 0 )
395  for( int i = 0; i < ent_size; i++ )
396  CHK_ERRORR( set_relation( related_ents[i], entities[i] ) );
397  else
398  for( int i = 0; i < ent_size; i++ )
399  CHK_ERRORR( set_relation( entities[i], related_ents[i] ) );
400  }
401  }
402  else
403  {
404  std::vector< iBase_EntitySetHandle > related_sets( ent_size );
405  int result = relSides[!iface_no]->get_relation_side( entities, ent_size, &related_sets[0] );
406 
407  if( result == iBase_SUCCESS )
408  {
409  if( iface_no == 0 )
410  for( int i = 0; i < ent_size; i++ )
411  CHK_ERRORR( set_relation( related_sets[i], entities[i] ) );
412  else
413  for( int i = 0; i < ent_size; i++ )
414  CHK_ERRORR( set_relation( entities[i], related_sets[i] ) );
415  }
416  }
417 
418  free( entities );
419  }
420  else
421  {
422  iBase_EntitySetHandle* sets = NULL;
423  int set_alloc = 0, set_size;
424 
425  CHK_ERRORR( relSides[!iface_no]->get_related_sets( &sets, &set_alloc, &set_size ) );
426  if( entOrSet[iface_no] == iRel_ENTITY )
427  {
428  std::vector< iBase_EntityHandle > related_ents( set_size );
429  int result = relSides[!iface_no]->get_relation_side( sets, set_size, &related_ents[0] );
430 
431  if( result == iBase_SUCCESS )
432  {
433  if( iface_no == 0 )
434  for( int i = 0; i < set_size; i++ )
435  CHK_ERRORR( set_relation( related_ents[i], sets[i] ) );
436  else
437  for( int i = 0; i < set_size; i++ )
438  CHK_ERRORR( set_relation( sets[i], related_ents[i] ) );
439  }
440  }
441  else
442  {
443  std::vector< iBase_EntitySetHandle > related_sets( set_size );
444  int result = relSides[!iface_no]->get_relation_side( sets, set_size, &related_sets[0] );
445 
446  if( result == iBase_SUCCESS )
447  {
448  if( iface_no == 0 )
449  for( int i = 0; i < set_size; i++ )
450  CHK_ERRORR( set_relation( related_sets[i], sets[i] ) );
451  else
452  for( int i = 0; i < set_size; i++ )
453  CHK_ERRORR( set_relation( sets[i], related_sets[i] ) );
454  }
455  }
456 
457  free( sets );
458  }
459  }
460  else
461  {
462  ERRORR( iBase_INVALID_ARGUMENT, "Invalid argument for relation status" );
463  }
464 
466 }
467 
468 bool AssocPair::equivalent( iBase_Instance iface0, iBase_Instance iface1, bool* order_switched )
469 {
470  if( iface0 == relSides[0]->instance() && iface1 == relSides[1]->instance() )
471  {
472  if( order_switched ) *order_switched = false;
473  return true;
474  }
475  else if( iface0 == relSides[1]->instance() && iface1 == relSides[0]->instance() )
476  {
477  if( order_switched ) *order_switched = true;
478  return true;
479  }
480  else
481  return false;
482 }
483 
484 bool AssocPair::equivalent( iRel_IfaceType type0, iRel_IfaceType type1, bool* order_switched )
485 {
486  if( type0 == relSides[0]->type() && type1 == relSides[1]->type() )
487  {
488  if( order_switched ) *order_switched = false;
489  return true;
490  }
491  else if( type0 == relSides[1]->type() && type1 == relSides[0]->type() )
492  {
493  if( order_switched ) *order_switched = true;
494  return true;
495  }
496  else
497  return false;
498 }
499 
501 {
502  return ( iface == relSides[0]->instance() || iface == relSides[1]->instance() );
503 }
504 
506 {
508  int entities_alloc = 0, entities_size;
509 
510  CHK_ERRORR( relSides[iface_no]->get_entities( -1, set, &entities, &entities_alloc, &entities_size ) );
511 
512  for( int i = 0; i < entities_size; i++ )
513  CHK_ERRORR( relSides[iface_no]->set_relation_side( entities + i, 1, &related_ent ) );
514 
515  free( entities );
517 }
518 
520 {
522  int entities_alloc, entities_size;
523 
524  CHK_ERRORR( relSides[iface_no]->get_entities( -1, set, &entities, &entities_alloc, &entities_size ) );
525 
526  for( int i = 0; i < entities_size; i++ )
527  CHK_ERRORR( relSides[iface_no]->set_relation_side( entities + i, 1, &related_set ) );
528 
529  free( entities );
531 }
532 
534 {
536  int entities_alloc = 0, entities_size;
537 
538  CHK_ERRORR( relSides[iface_no]->get_entities( -1, set, &entities, &entities_alloc, &entities_size ) );CHK_ERRORR( relSides[iface_no]->rmv_relation_side( entities, entities_size ) );
539 
540  free( entities );
542 }