Mesh Oriented datABase  (version 5.6.0)
An array-based unstructured mesh library
SkinMesh.cpp File Reference
#include <iostream>
#include <cstdlib>
#include "MBCore.hpp"
#include "MBRange.hpp"
#include "MBTagConventions.hpp"
+ Include dependency graph for SkinMesh.cpp:

Go to the source code of this file.

Classes

struct  edge
 

Functions

int compare_edge (const void *a, const void *b)
 
MBErrorCode skin_tris (MBInterface *mb, MBRange tris, MBRange &skin_edges)
 
int main (int argc, char **argv)
 

Function Documentation

◆ compare_edge()

int compare_edge ( const void *  a,
const void *  b 
)
Examples
SkinMesh.cpp.

Definition at line 23 of file SkinMesh.cpp.

24 {
25  struct edge* ia = (struct edge*)a;
26  struct edge* ib = (struct edge*)b;
27  if( ia->v0 == ib->v0 )
28  {
29  return (int)( 100.f * ia->v1 - 100.f * ib->v1 );
30  }
31  else
32  {
33  return (int)( 100.f * ia->v0 - 100.f * ib->v0 );
34  }
35 }

References edge::v0, and edge::v1.

Referenced by skin_tris().

◆ main()

int main ( int  argc,
char **  argv 
)
Examples
SkinMesh.cpp.

Definition at line 141 of file SkinMesh.cpp.

142 {
143  if( 1 == argc )
144  {
145  std::cout << "Usage: " << argv[0] << " <filename>" << std::endl;
146  return 0;
147  }
148 
149  // get MOAB instance and read the file
150  MBCore* mb = new MBCore();
151  MBErrorCode rval = mb->load_file( argv[1] );
152  if( MB_SUCCESS != rval ) return 0;
153 
154  // this optimized skinner requires removing all MBEdges from the MOAB instance
155  MBRange edges;
156  rval = mb->get_entities_by_type( 0, MBEDGE, edges );
157  if( MB_SUCCESS != rval ) return 0;
158  if( !edges.empty() ) std::cout << "Warning: deleting all MBEdges" << std::endl;
159  rval = mb->delete_entities( edges );
160  if( MB_SUCCESS != rval ) return 0;
161 
162  // get surface sets
163  MBTag geom_tag;
164  rval = mb->tag_get_handle( GEOM_DIMENSION_TAG_NAME, 1, MB_TYPE_INTEGER, geom_tag );
165  if( MB_SUCCESS != rval ) return 0;
166  MBRange surf_sets;
167  int two = 2;
168  void* dim[] = { &two };
169  rval = mb->get_entities_by_type_and_tag( 0, MBENTITYSET, &geom_tag, dim, 1, surf_sets );
170  if( MB_SUCCESS != rval ) return 0;
171 
172  // skin each surface
173  for( MBRange::iterator i = surf_sets.begin(); i != surf_sets.end(); ++i )
174  {
175 
176  // get triangles in the surface set
177  MBRange tris;
178  rval = mb->get_entities_by_type( *i, MBTRI, tris );
179  if( MB_SUCCESS != rval ) return 0;
180 
181  // call the skinning function
182  MBRange skin_edges;
183  rval = skin_tris( mb, tris, skin_edges );
184  if( MB_SUCCESS != rval ) return 0;
185 
186  // do something with the result
187  std::cout << "surface has " << skin_edges.size() << " skin edges" << std::endl;
188 
189  // remove the edges for the optimized skinner
190  rval = mb->delete_entities( skin_edges );
191  if( MB_SUCCESS != rval ) return 0;
192  }
193 }

References GEOM_DIMENSION_TAG_NAME, mb, MB_SUCCESS, MB_TYPE_INTEGER, MBEDGE, MBENTITYSET, MBTRI, and skin_tris().

◆ skin_tris()

MBErrorCode skin_tris ( MBInterface *  mb,
MBRange  tris,
MBRange &  skin_edges 
)
Examples
SkinMesh.cpp.

Definition at line 39 of file SkinMesh.cpp.

40 {
41 
42  // Empty the output range and make sure that the input range is only tris
43  skin_edges.clear();
44  if( tris.empty() ) return MB_ENTITY_NOT_FOUND;
45  if( !tris.all_of_type( MBTRI ) ) return MB_FAILURE;
46 
47  // Remove edges from the instance.
48  int n_edges;
49  MBErrorCode rval = mb->get_number_entities_by_type( 0, MBEDGE, n_edges );
50  if( MB_SUCCESS != rval ) return rval;
51  if( 0 != n_edges )
52  {
53  std::cerr << "skin_tris: failed because " << n_edges << " edges exist in the MOAB instance" << std::endl;
54  return MB_FAILURE;
55  }
56 
57  // Get connectivity. Do not create MBEdges.
58  edge* edges = new edge[3 * tris.size()];
59  int n_verts;
60  int ii = 0;
61  for( MBRange::iterator i = tris.begin(); i != tris.end(); ++i )
62  {
63  const MBEntityHandle* conn;
64  rval = mb->get_connectivity( *i, conn, n_verts );
65  if( MB_SUCCESS != rval ) return rval;
66  if( 3 != n_verts ) return MB_FAILURE;
67  // points should not be degenerate
68  if( conn[0] == conn[1] || conn[1] == conn[2] || conn[2] == conn[0] )
69  {
70  std::cerr << "skin_tris: degenerate triangle" << std::endl;
71  return MB_FAILURE;
72  }
73 
74  // make edges
75  edges[3 * ii + 0].v0 = conn[0];
76  edges[3 * ii + 0].v1 = conn[1];
77  edges[3 * ii + 1].v0 = conn[1];
78  edges[3 * ii + 1].v1 = conn[2];
79  edges[3 * ii + 2].v0 = conn[2];
80  edges[3 * ii + 2].v1 = conn[0];
81  ii++;
82  }
83 
84  // Ensure that the first vertex handle is the lowest
85  for( unsigned int i = 0; i < 3 * tris.size(); ++i )
86  {
87  if( edges[i].v0 > edges[i].v1 )
88  {
89  MBEntityHandle temp = edges[i].v0;
90  edges[i].v0 = edges[i].v1;
91  edges[i].v1 = temp;
92  }
93  }
94 
95  // Sort by first handle, then second handle.
96  qsort( edges, 3 * tris.size(), sizeof( struct edge ), compare_edge );
97 
98  // Go through array, saving edges that are not paired.
99  for( unsigned int i = 0; i < 3 * tris.size(); i++ )
100  {
101  // If the last edge has not been paired, create it. This avoids overrunning
102  // the edges array with i+1.
103  if( 3 * tris.size() - 1 == i )
104  {
105  const MBEntityHandle conn[2] = { edges[i].v0, edges[i].v1 };
106  MBEntityHandle edge;
107  rval = mb->create_element( MBEDGE, conn, 2, edge );
108  if( MB_SUCCESS != rval ) return rval;
109  skin_edges.insert( edge );
110 
111  // If a match exists, skip ahead
112  }
113  else if( edges[i].v0 == edges[i + 1].v0 && edges[i].v1 == edges[i + 1].v1 )
114  {
115  i++;
116  // test to make sure surface is manifold
117  while( edges[i].v0 == edges[i + 1].v0 && edges[i].v1 == edges[i + 1].v1 )
118  {
119  std::cout << "find_skin WARNING: non-manifold edge" << std::endl;
120  mb->list_entity( edges[i].v0 );
121  mb->list_entity( edges[i].v1 );
122  ++i;
123  }
124  // otherwise a skin edge has been found
125  }
126  else
127  {
128  const MBEntityHandle conn[2] = { edges[i].v0, edges[i].v1 };
129  MBEntityHandle edge;
130  rval = mb->create_element( MBEDGE, conn, 2, edge );
131  if( MB_SUCCESS != rval ) return rval;
132  skin_edges.insert( edge );
133  }
134  }
135  delete[] edges;
136  return MB_SUCCESS;
137 }

References compare_edge(), mb, MB_ENTITY_NOT_FOUND, MB_SUCCESS, MBEDGE, MBTRI, edge::v0, and edge::v1.

Referenced by moab::ReadRTT::build_moab(), and main().