Shapeworks Studio  2.1
Shape analysis software suite
List of all members | Public Member Functions | Protected Member Functions | Protected Attributes
FEMesh Class Reference
+ Inheritance diagram for FEMesh:
+ Collaboration diagram for FEMesh:

Public Member Functions

 FEMesh (FEMesh &m)
 
void Create (int nodes, int elems, int faces=0, int edges=0)
 allocate space for mesh
 
void ShallowCopy (FEMesh *pm)
 
void Clear ()
 — C L E A N U P —
 
void DeleteEdges ()
 
int Elements () const
 return number of elements
 
FEElementElement (int n)
 return element
 
FEElement_ElementRef (int n)
 return reference to element
 
FEElementElementPtr (int n=0)
 return pointer to element
 
int FindFace (FEElement *pe, FEFace &f, FEFace &fe)
 
void FindNodesFromPart (int gid, vector< int > &node)
 
std::vector< FENode > & NodeArray ()
 
std::vector< FEFace > & FaceArray ()
 
std::vector< FEElement > & ElementArray ()
 
double GetElementValue (int n)
 
void SetElementValue (int n, double v)
 
void UpdateValueRange ()
 
void GetValueRange (double &vmin, double &vmax)
 
vec3d ProjectToSurface (vec3d r, vec3d t)
 
vec3d ProjectToFace (vec3d p, FEFace &f, double &r, double &s)
 
vec3d ProjectToEdge (vec3d e1, vec3d e2, vec3d p, double &r)
 
bool FindIntersection (FEFace &f, vec3d x, vec3d n, vec3d &q, double &g)
 
void Update ()
 
void UpdateElementNeighbors ()
 
void UpdateFaces ()
 
void UpdateEdges ()
 
void UpdateNodes ()
 
void AutoSmooth (double w)
 
void UpdateNormals ()
 
void PartitionSelection ()
 
void RemoveIsolatedNodes ()
 
void AddNode (FENode &n)
 
FEMeshDetachSelectedMesh ()
 
void DetachSelectedPart ()
 
FEMeshExtractSelectedFaces ()
 
void DeleteTaggedElements (int tag)
 
void DeleteTaggedFaces (int tag)
 
void DeleteTaggedEdges (int tag)
 
void FindDuplicateFaces (vector< int > &l)
 This function identifies duplicate faces and returns a list with the duplicates.
 
void FindDuplicateEdges (vector< int > &l)
 This function identifies duplicate edges and returns a list with the duplicates.
 
void DeleteSelectedElements ()
 
void DeleteSelectedFaces ()
 
void DeleteSelectedNodes ()
 
void InvertTaggedElements (int ntag)
 
void InvertSelectedElements ()
 
double ShellJacobian (FEElement &el)
 
void RemoveDuplicateElements ()
 
void FixinvertedElements ()
 
void FixReferenceSurface ()
 
void InterpolateShellThickness (double)
 
void RemoveNonManifoldElements ()
 
void FixElementWinding ()
 
void FixElementWinding2 ()
 
void TagAllElements (int ntag)
 
int DataFields ()
 
FEElementDataAddDataField (const char *szname, double v=0.0)
 
FEElementDataGetDataField (int i)
 
double ShortestEdge ()
 
void BuildNodeElementTable (vector< vector< int > > &NET)
 
void BuildNodeFaceTable (vector< vector< int > > &NFT)
 
void BuildNodeEdgeTable (vector< vector< int > > &NET)
 
void BuildEdgeTable (vector< pair< int, int > > &ET)
 
void BuildNodeNodeTable (vector< set< int > > &NNT)
 
void BuildSurfaceNodeNodeTable (vector< set< int > > &NNT)
 
void BuildElementEdgeTable (vector< vector< int > > &EET, vector< pair< int, int > > &ET)
 
void BuildFaceTable (vector< FEFace > &FT)
 
void BuildElementFaceTable (vector< vector< int > > &EFT, vector< FEFace > &FT)
 
void BuildFaceEdgeTable (vector< vector< int > > &FET, vector< pair< int, int > > &ET)
 
void BuildFaceFaceTable (vector< int > &FFT, vector< FEFace > &FT)
 
void BuildEdgeEdgeTable (vector< int > &EET, vector< pair< int, int > > &ET)
 
- Public Member Functions inherited from FECoreMesh
 FECoreMesh ()
 constructor
 
virtual ~FECoreMesh ()
 destructor
 
bool IsType (int ntype)
 check the type of the mesh More...
 
int Nodes () const
 
int Edges () const
 
int Faces () const
 
FENodeNode (int n)
 
FEEdgeEdge (int n)
 
FEFaceFace (int n)
 
FENodeNodePtr (int n=0)
 
FEEdgeEdgePtr (int n=0)
 
FEFaceFacePtr (int n=0)
 

Protected Member Functions

bool IntersectTri (vec3d *y, vec3d x, vec3d n, vec3d &q, double &g)
 
bool IntersectQuad (vec3d *y, vec3d x, vec3d n, vec3d &q, double &g)
 

Protected Attributes

std::vector< FEElementm_Elem
 FE elements.
 
std::vector< double > m_data
 element values
 
double m_min
 
double m_max
 value range of element data
 
vector< FEElementDatam_map
 
- Protected Attributes inherited from FECoreMesh
std::vector< FENodem_Node
 FE nodes.
 
std::vector< FEEdgem_Edge
 FE edges.
 
std::vector< FEFacem_Face
 FE faces.
 

Detailed Description

Definition at line 57 of file FEMesh.h.

Member Function Documentation

FEMesh * FEMesh::DetachSelectedMesh ( )

Update();

Definition at line 272 of file FEMesh.cpp.

273 {
274  int i, j, n;
275 
276  // count selected elements
277  int elems = 0;
278  FEElement* pe = ElementPtr();
279  for (i=0; i<Elements(); ++i, ++pe) if (pe->IsSelected()) ++elems;
280 
281  // make sure there is a selection
282  if (elems == 0) return 0;
283 
284  // tag nodes that will be moved to the new mesh
285  FENode* pn = NodePtr();
286  for (i=0; i<Nodes(); ++i, ++pn) pn->m_ntag = -1;
287 
288  pe = ElementPtr();
289  for (i=0; i<Elements(); ++i, ++pe)
290  {
291  if (pe->IsSelected())
292  {
293  n = pe->Nodes();
294  for (j=0; j<n; ++j) Node(pe->m_node[j]).m_ntag = 1;
295  }
296  }
297 
298  // count nodes
299  int nodes = 0;
300  pn = NodePtr();
301  for (i=0; i<Nodes(); ++i, ++pn) if (pn->m_ntag > 0) ++nodes;
302 
303  // create a new mesh
304  FEMesh* pm = new FEMesh();
305  pm->Create(nodes, elems);
306 
307  // create the new nodes
308  pn = NodePtr();
309  n = 0;
310  for (i=0; i<Nodes(); ++i, ++pn)
311  {
312  if (pn->m_ntag > 0)
313  {
314  FENode& node = pm->Node(n);
315  node.r = pn->r;
316  pn->m_ntag = n++;
317  }
318  }
319  assert(n == nodes);
320 
321  // create the new elements
322  pe = ElementPtr();
323  n = 0;
324  for (i=0; i<Elements(); ++i, ++pe)
325  {
326  if (pe->IsSelected())
327  {
328  FEElement& el = pm->Element(n);
329  el.SetType(pe->GetType());
330  el.m_h[0] = pe->m_h[0];
331  el.m_h[1] = pe->m_h[1];
332  el.m_h[2] = pe->m_h[2];
333  el.m_h[3] = pe->m_h[3];
334 
335  for (j=0; j<pe->Nodes(); ++j)
336  {
337  el.m_node[j] = Node(pe->m_node[j]).m_ntag;
338  assert(el.m_node[j] >= 0);
339  }
340  ++n;
341  }
342  }
343  assert(n==elems);
344 
345  // update the new mesh (is done later)
346 // pm->Update();
347 
348  vector<int> ELT;
349  ELT.assign(Elements(), -1);
350 
351  // the new mesh is created, so let's clean up this mesh
352  // delete selected elements
353  n = 0;
354  for (i=0; i<Elements(); ++i)
355  {
356  FEElement& e0 = Element(i);
357  FEElement& e1 = Element(n);
358 
359  if (!e0.IsSelected())
360  {
361  e1 = e0;
362  ELT[i] = n;
363  ++n;
364  }
365  }
366  m_Elem.resize(n);
367  m_data.resize(n);
368 
369  // tag nodes which will be kept
370  pn = NodePtr();
371  for (i=0; i<Nodes(); ++i, ++pn) pn->m_ntag = -1;
372 
373  pe = ElementPtr();
374  for (i=0; i<Elements(); ++i, ++pe)
375  {
376  n = pe->Nodes();
377  for (j=0; j<n; ++j) Node(pe->m_node[j]).m_ntag = 1;
378  }
379 
380  // reindex the nodes
381  n = 0;
382  pn = NodePtr();
383  for (i=0; i<Nodes(); ++i, ++pn) if (pn->m_ntag > 0) pn->m_ntag = n++;
384 
385  pe = ElementPtr();
386  for (i=0; i<Elements(); ++i, ++pe)
387  {
388  n = pe->Nodes();
389  for (j=0; j<n; ++j) pe->m_node[j] = Node(pe->m_node[j]).m_ntag;
390  }
391 
392  // delete untagged nodes
393  n = 0;
394  for (i=0; i<Nodes(); ++i)
395  {
396  FENode& n0 = Node(i);
397  FENode& n1 = Node(n);
398 
399  if (n0.m_ntag >= 0)
400  {
401  n1 = n0;
402  ++n;
403  }
404  }
405  m_Node.resize(n);
406 
407  // update the mesh (is done later)
409 
410  // Done!
411  return pm;
412 }
void SetType(int ntype)
Set the element type.
Definition: FEElement.cpp:670
void Create(int nodes, int elems, int faces=0, int edges=0)
allocate space for mesh
Definition: FEMesh.cpp:253
FEElement * ElementPtr(int n=0)
return pointer to element
Definition: FEMesh.h:87
Definition: FEMesh.h:57
int Nodes() const
number of nodes
Definition: FEElement.h:199
FEElement & Element(int n)
return element
Definition: FEMesh.h:81
std::vector< FEElement > m_Elem
FE elements.
Definition: FEMesh.h:206
int GetType() const
return the element type
Definition: FEElement.h:193
int * m_node
pointer to node data
Definition: FEElement.h:233
int Elements() const
return number of elements
Definition: FEMesh.h:78
double * m_h
element thickness (only used by shells)
Definition: FEElement.h:236
std::vector< double > m_data
element values
Definition: FEMesh.h:207
std::vector< FENode > m_Node
FE nodes.
Definition: FECoreMesh.h:49
bool FEMesh::IntersectQuad ( vec3d y,
vec3d  r,
vec3d  n,
vec3d q,
double &  g 
)
protected

This function calculates the intersection of a ray with a quad and returns true if the ray intersected.

Definition at line 2729 of file FEMesh.cpp.

2730 {
2731  // first we're going to see if the ray intersects the two subtriangles
2732  vec3d x1[3], x2[3];
2733  x1[0] = y[0]; x2[0] = y[2];
2734  x1[1] = y[1]; x2[1] = y[3];
2735  x1[2] = y[3]; x2[2] = y[1];
2736 
2737  bool b = false;
2738  double rp, sp;
2739 
2740  double eps = 0.01;
2741 
2742  if (IntersectTri(x1, r, n, q, g))
2743  {
2744  // we've intersected the first triangle
2745  b = true;
2746  rp = 0;
2747  sp = 0;
2748  }
2749  else if (IntersectTri(x2, r, n, q, g))
2750  {
2751  // we've intersected the second triangle
2752  b = true;
2753  rp = 0;
2754  sp = 0;
2755  }
2756 
2757  // if one of the triangels was intersected,
2758  // we calculate a more accurate projection
2759  if (b)
2760  {
2761  mat3d A;
2762  vec3d dx;
2763  vec3d F, F1, F2, F3;
2764  double H[4], H1[4], H2[4];
2765 
2766  double l1 = rp;
2767  double l2 = sp;
2768  double l3 = g;
2769 
2770  int nn = 0;
2771  int maxn = 5;
2772  do
2773  {
2774  // shape functions of quad
2775  H[0] = 0.25*(1 - l1)*(1 - l2);
2776  H[1] = 0.25*(1 + l1)*(1 - l2);
2777  H[2] = 0.25*(1 + l1)*(1 + l2);
2778  H[3] = 0.25*(1 - l1)*(1 + l2);
2779  q = y[0]*H[0] + y[1]*H[1] + y[2]*H[2] + y[3]*H[3];
2780 
2781  // shape function derivatives
2782  H1[0] = -0.25*(1 - l2); H2[0] = -0.25*(1 - l1);
2783  H1[1] = 0.25*(1 - l2); H2[1] = -0.25*(1 + l1);
2784  H1[2] = 0.25*(1 + l2); H2[2] = 0.25*(1 + l1);
2785  H1[3] = -0.25*(1 + l2); H2[3] = 0.25*(1 - l1);
2786 
2787  // calculate residual
2788  F = r + n*l3 - q;
2789 
2790  // residual derivatives
2791  F1 = - y[0]*H1[0] - y[1]*H1[1] - y[2]*H1[2] - y[3]*H1[3];
2792  F2 = - y[0]*H2[0] - y[1]*H2[1] - y[2]*H2[2] - y[3]*H2[3];
2793  F3 = n;
2794 
2795  // set up the tangent matrix
2796  A[0][0] = F1.x; A[0][1] = F2.x; A[0][2] = F3.x;
2797  A[1][0] = F1.y; A[1][1] = F2.y; A[1][2] = F3.y;
2798  A[2][0] = F1.z; A[2][1] = F2.z; A[2][2] = F3.z;
2799 
2800  // calculate solution increment
2801  mat3d Ai(A);
2802  Ai.Invert();
2803  dx = -(Ai*F);
2804 
2805  // update solution
2806  l1 += dx.x;
2807  l2 += dx.y;
2808  l3 += dx.z;
2809 
2810  ++nn;
2811  }
2812  while ((dx.Length() > 1e-7) && (nn < maxn));
2813 
2814  // store results
2815  rp = l1;
2816  sp = l2;
2817  g = l3;
2818 
2819  // see if the point is inside the quad
2820  if ((rp >= -1-eps) && (rp <= 1+eps) &&
2821  (sp >= -1-eps) && (sp <= 1+eps)) return true;
2822  }
2823 
2824  return false;
2825 }
Definition: math3d.h:97
Definition: math3d.h:38
std::vector<FENode>& FEMesh::NodeArray ( )
inline

Get the node array

Todo:
Maybe I should delete these

Definition at line 97 of file FEMesh.h.

97 { return m_Node; }
std::vector< FENode > m_Node
FE nodes.
Definition: FECoreMesh.h:49
void FEMesh::UpdateFaces ( )

This function finds the face neighbours. Note that internal faces cannot be neighbours of external faces.

Todo:
The FEAutoMesher::BuildFaces also assign the FEFace.m_elem variables. I should probably change this so that only one of these two functions does this.

Definition at line 1853 of file FEMesh.cpp.

1854 {
1855  int i, j, k, n, m, inode, nval;
1856  int NF = Faces();
1857 
1858  // make sure we have faces
1859  assert(NF);
1860 
1861  // first we need to figure out which face belongs to which element
1862  // first build the node element table
1863  vector< vector<int> > NET;
1864  BuildNodeElementTable(NET);
1865 
1866  // loop over all faces
1867  int f2[9];
1868  for (i=0; i<NF; ++i)
1869  {
1870  FEFace& f = Face(i);
1871  int m1 = f.m_nodes;
1872  f.m_elem[0] = -1;
1873  f.m_elem[1] = -1;
1874 
1875  // pick a node on the face
1876  inode = f.n[0];
1877  nval = NET[inode].size();
1878  m = 0;
1879  for (j=0; j<nval; ++j)
1880  {
1881  int ni = NET[inode][j];
1882  FEElement* pe = ElementPtr(ni);
1883 
1884  // search solid elements
1885  if (pe->IsSolid())
1886  {
1887  n = pe->Faces();
1888  for (k=0; k<n; ++k)
1889  {
1890  int m2 = pe->GetFace(k, f2);
1891  if ((m1 == m2) && cmp_fn(f.n, f2, m1))
1892  {
1893  assert(m<2);
1894  if (m == 0) f.m_elem[m++] = ni;
1895  else
1896  {
1897  int n0 = f.m_elem[0];
1898  if (ni < n0) { f.m_elem[0] = ni; f.m_elem[1] = n0; } else { f.m_elem[0] = n0; f.m_elem[1] = ni; }
1899  }
1900  pe->m_face[k] = i;
1901  }
1902  }
1903  }
1904  else if (pe->IsShell())
1905  {
1906  FEFace f2 = pe->GetShellFace();
1907  if (f == f2)
1908  {
1909  assert(m<2);
1910  if (m<2)
1911  {
1912  f.m_elem[m++] = ni;
1913  pe->m_face[0] = i;
1914  }
1915  }
1916  }
1917  }
1918 
1919  assert(f.m_elem[0] != -1);
1920  }
1921 
1922  // build the node-face table
1923  vector< vector<int> > NFT;
1924  BuildNodeFaceTable(NFT);
1925 
1926  // find all face neighbours
1927  int n1, n2;
1928  for (i=0; i<NF; ++i)
1929  {
1930  FEFace* pf = FacePtr(i);
1931 
1932  int nf = pf->Nodes();
1933  n = pf->Edges();
1934  for (j=0; j<n; ++j)
1935  {
1936  n1 = pf->n[j];
1937  n2 = pf->n[(j+1)%n];
1938  nval = NFT[n1].size();
1939  pf->m_nbr[j] = -1;
1940  for (k=0; k<nval; ++k)
1941  {
1942  FEFace* pfn = FacePtr(NFT[n1][k]);
1943  if (pfn != pf)
1944  {
1945  if (pfn->HasEdge(n1, n2))
1946  {
1947  if (pf->IsExternal())
1948  {
1949  if (pfn->IsExternal()) { pf->m_nbr[j] = NFT[n1][k]; break; }
1950  }
1951  else if (!pfn->IsExternal()) { pf->m_nbr[j] = NFT[n1][k]; break; }
1952  }
1953  }
1954  }
1955  }
1956  }
1957 
1958 #ifdef _DEBUG
1959  // see if all faces belong to at least one element
1960  for (i=0; i<NF; ++i)
1961  {
1962  FEFace& f = Face(i);
1963  assert(f.m_elem[0] >= 0);
1964  }
1965 #endif
1966 
1967 }
int GetFace(int i, int *n)
Get only the nodes of face i (only solids have faces)
FEElement * ElementPtr(int n=0)
return pointer to element
Definition: FEMesh.h:87
int m_elem[2]
the elements to which this face belongs
Definition: FEElement.h:158
int m_nbr[4]
neighbour faces
Definition: FEElement.h:152
FEFace GetShellFace()
Get the face of a shell.
Definition: FEElement.cpp:375
int Faces() const
Number of faces (shells have no faces)
Definition: FEElement.h:202
bool IsExternal()
Is this face internal or external.
Definition: FEElement.h:146
int Edges()
return number of edges
Definition: FEElement.cpp:133
int * m_face
faces (-1 for interior faces)
Definition: FEElement.h:235
int n[MAX_NODES]
nodal ID&#39;s
Definition: FEElement.h:149
int Nodes()
return number of nodes
Definition: FEElement.h:128
int m_nodes
number of nodes
Definition: FEElement.h:150
bool HasEdge(int n1, int n2)
See if this face has an edge.
Definition: FEElement.cpp:151

The documentation for this class was generated from the following files: