Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
quads_to_tris.cpp
Go to the documentation of this file.
1 // Brandon Smith
2 // January 20, 2009
3 
4 /*
5  loop over all surface meshsets
6  get all quads of surface meshset
7  loop over all quads
8  make tris from quad
9  add tris to the surface meshset
10  remove quad from surface meshset
11  delete quad
12  end loop
13  end loop
14 */
15 
16 #include "quads_to_tris.hpp"
17 #include "moab/CartVect.hpp"
18 using namespace moab;
19 
20 // Generic function to create two tris from a quad. This can be improved later.
22  EntityHandle quad, /* input */
23  EntityHandle& tri0, /* output */
24  EntityHandle& tri1 /* output */ )
25 {
26 
27  // get connectivity (ordered counterclockwise for 2D elements in MOAB)
28  ErrorCode result;
29  const EntityHandle* quad_conn;
30  int n_verts = 0;
31  result = MBI->get_connectivity( quad, quad_conn, n_verts );
32  assert( 4 == n_verts );
33  assert( MB_SUCCESS == result );
34 
35  // find length of diagonals
36  std::vector< CartVect > coords( n_verts );
37  result = MBI->get_coords( quad_conn, n_verts, coords[0].array() );
38  if( MB_SUCCESS != result ) return result;
39  CartVect diagA = coords[0] - coords[2];
40  double lenA_sqr = diagA.length_squared();
41  CartVect diagB = coords[1] - coords[3];
42  double lenB_sqr = diagB.length_squared();
43 
44  // choose the shortest diagonal
45  EntityHandle tri0_conn[3], tri1_conn[3];
46  if( lenA_sqr < lenB_sqr )
47  {
48  tri0_conn[0] = quad_conn[0];
49  tri0_conn[1] = quad_conn[1];
50  tri0_conn[2] = quad_conn[2];
51  tri1_conn[0] = quad_conn[0];
52  tri1_conn[1] = quad_conn[2];
53  tri1_conn[2] = quad_conn[3];
54  }
55  else
56  {
57  tri0_conn[0] = quad_conn[0];
58  tri0_conn[1] = quad_conn[1];
59  tri0_conn[2] = quad_conn[3];
60  tri1_conn[0] = quad_conn[1];
61  tri1_conn[1] = quad_conn[2];
62  tri1_conn[2] = quad_conn[3];
63  }
64 
65  // make tris from quad
66  result = MBI->create_element( MBTRI, tri0_conn, 3, tri0 );
67  assert( MB_SUCCESS == result );
68  result = MBI->create_element( MBTRI, tri1_conn, 3, tri1 );
69  assert( MB_SUCCESS == result );
70 
71  return MB_SUCCESS;
72 }
73 
75 {
76  tris.clear();
77  for( Range::const_iterator i = quads.begin(); i != quads.end(); ++i )
78  {
79  EntityHandle tri0, tri1;
80  ErrorCode result = make_tris_from_quad( MBI, *i, tri0, tri1 );
81  assert( MB_SUCCESS == result );
82  if( MB_SUCCESS != result ) return result;
83  tris.insert( tri0 );
84  tris.insert( tri1 );
85  }
86  return MB_SUCCESS;
87 }
88 
90 {
91 
92  // create a geometry tag to find the surfaces with
93  ErrorCode result;
94  Tag geom_tag, id_tag;
95  result = MBI->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag, MB_TAG_DENSE | MB_TAG_CREAT );
96  if( MB_SUCCESS != result ) return result;
97 
98  // create an id tag to find the surface id with
99  id_tag = MBI->globalId_tag();
100 
101  // get all surface meshsets
102  Range surface_meshsets;
103  int dim = 2;
104  void* input_dim[] = { &dim };
105  result = MBI->get_entities_by_type_and_tag( input_meshset, MBENTITYSET, &geom_tag, input_dim, 1, surface_meshsets );
106  assert( MB_SUCCESS == result );
107  std::cout << surface_meshsets.size() << " surfaces found." << std::endl;
108 
109  // ******************************************************************
110  // Loop over every surface meshset and grab each surface's quads.
111  // ******************************************************************
112  for( Range::iterator i = surface_meshsets.begin(); i != surface_meshsets.end(); ++i )
113  {
114 
115  // get the surface id of the surface meshset
116  int surf_id = 0;
117  result = MBI->tag_get_data( id_tag, &( *i ), 1, &surf_id );
118  assert( MB_SUCCESS == result );
119  std::cout << " Surface " << surf_id << " has ";
120 
121  // get all quads of the surface
122  Range quads;
123  result = MBI->get_entities_by_type( *i, MBQUAD, quads );
124  assert( MB_SUCCESS == result );
125  std::cout << quads.size() << " quads." << std::endl;
126 
127  // ******************************************************************
128  // For each quad, make two triangles then delete the quad.
129  // ******************************************************************
130  for( Range::iterator j = quads.begin(); j != quads.end(); ++j )
131  {
132 
133  // make the tris
134  EntityHandle tri0 = 0, tri1 = 0;
135  result = make_tris_from_quad( MBI, *j, tri0, tri1 );
136  assert( MB_SUCCESS == result );
137 
138  // add all the tris to the same surface meshset as the quads were inside.
139  result = MBI->add_entities( *i, &tri0, 1 );
140  if( MB_SUCCESS != result ) std::cout << "result=" << result << std::endl;
141  assert( MB_SUCCESS == result );
142  result = MBI->add_entities( *i, &tri1, 1 );
143  assert( MB_SUCCESS == result );
144 
145  // remove the quad from the surface meshset
146  result = MBI->remove_entities( *i, &( *j ), 1 );
147  assert( MB_SUCCESS == result );
148 
149  // delete the quad
150  result = MBI->delete_entities( &( *j ), 1 );
151  assert( MB_SUCCESS == result );
152 
153  } // end quad loop
154  } // end surface meshset loop
155  return MB_SUCCESS;
156 }