29 #ifndef CORE_DATATYPES_TRISURFMESH_H
30 #define CORE_DATATYPES_TRISURFMESH_H 1
59 #include <boost/thread.hpp>
67 using namespace SCIRun::Core::Basis;
68 using namespace SCIRun::Core::Geometry;
83 #if (SCIRUN_TRISURF_SUPPORT > 0)
87 #if (SCIRUN_QUADRATIC_SUPPORT > 0)
90 #if (SCIRUN_CUBIC_SUPPORT > 0)
101 template <
class Basis>
102 class TriSurfMesh :
public Mesh
106 template<
class MESH>
friend class VTriSurfMesh;
158 friend class ElemData;
170 if (basis_type::polynomial_order() > 1) {
171 mesh_.get_edges_from_face(edges_,
index_);
178 return mesh_.faces_[
index_ * 3];
182 return mesh_.faces_[
index_ * 3 + 1];
186 return mesh_.faces_[
index_ * 3 + 2];
210 return mesh_.points_[node0_index()];
214 return mesh_.points_[node1_index()];
218 return mesh_.points_[node2_index()];
231 friend class Synchronize;
237 mesh_(mesh), sync_(sync) {}
245 mesh_->synchronize_lock_.lock();
247 sync_ &= ~(mesh_->synchronized_);
249 sync_ &= ~(mesh_->synchronizing_);
252 mesh_->synchronizing_ |= sync_;
254 mesh_->synchronize_lock_.unlock();
268 while(!(mesh_->synchronized_ & Mesh::BOUNDING_BOX_E))
269 mesh_->synchronize_cond_.wait(lock);
273 mesh_->compute_node_grid();
277 mesh_->compute_elem_grid();
281 mesh_->synchronize_lock_.lock();
283 mesh_->synchronized_ |= sync_;
285 mesh_->synchronizing_ &= ~(sync_);
287 mesh_->synchronize_cond_.conditionBroadcast();
288 mesh_->synchronize_lock_.unlock();
351 virtual bool synchronize(
mask_type mask);
352 virtual bool unsynchronize(
mask_type mask);
353 bool clear_synchronization();
359 void begin(
typename Node::iterator &)
const;
360 void begin(
typename Edge::iterator &)
const;
361 void begin(
typename Face::iterator &)
const;
362 void begin(
typename Cell::iterator &)
const;
364 void end(
typename Node::iterator &)
const;
365 void end(
typename Edge::iterator &)
const;
366 void end(
typename Face::iterator &)
const;
367 void end(
typename Cell::iterator &)
const;
391 { array.resize(1); array[0]= idx; }
393 { get_nodes_from_edge(array,idx); }
395 { get_nodes_from_face(array,idx); }
397 {
ASSERTFAIL(
"TriSurfMesh: get_nodes has not been implemented for cells"); }
400 { get_edges_from_node(array,idx); }
402 { array.resize(1); array[0]= idx; }
404 { get_edges_from_face(array,idx); }
406 {
ASSERTFAIL(
"TriSurfMesh: get_edges has not been implemented for cells"); }
409 { get_faces_from_node(array,idx); }
411 { get_faces_from_edge(array,idx); }
413 { array.resize(1); array[0]= idx; }
415 {
ASSERTFAIL(
"TriSurfMesh: get_faces has not been implemented for cells"); }
418 {
ASSERTFAIL(
"TriSurfMesh: get_cells has not been implemented"); }
420 {
ASSERTFAIL(
"TriSurfMesh: get_cells has not been implemented"); }
422 {
ASSERTFAIL(
"TriSurfMesh: get_cells has not been implemented"); }
424 {
ASSERTFAIL(
"TriSurfMesh: get_cells has not been implemented"); }
427 { get_faces_from_node(array,idx); }
429 { get_faces_from_edge(array,idx); }
431 { array.resize(1); array[0]= idx; }
433 {
ASSERTFAIL(
"TriSurfMesh: get_elems has not been implemented for cells"); }
436 { get_edges_from_node(array,idx); }
438 { array.resize(1); array[0]= idx; }
440 { get_edges_from_face(array,idx); }
442 {
ASSERTFAIL(
"TriSurfMesh: get_delems has not been implemented for cells"); }
446 template<
class VECTOR,
class INDEX>
449 unsigned int which_edge,
450 unsigned int div_per_unit)
const
452 basis_.approx_edge(which_edge, div_per_unit, coords);
457 template<
class VECTOR,
class INDEX>
460 unsigned int which_face,
461 unsigned int div_per_unit)
const
463 basis_.approx_face(which_face, div_per_unit, coords);
468 { get_node_center(result, idx); }
470 { get_edge_center(result, idx); }
472 { get_face_center(result, idx); }
474 {
ASSERTFAIL(
"TriSurfMesh: get_cneter has not been implemented for cells"); }
482 typename Node::array_type arr;
483 get_nodes_from_edge(arr, idx);
484 return (points_[arr[0]] - points_[arr[1]]).length();
489 typename Node::array_type ra;
494 return (
Cross(p0-p1,p2-p0)).length()*0.5;
502 {
return get_size(idx); }
504 {
return get_size(idx); }
515 {
return(get_elem_neighbor(neighbor,elem,delem)); }
520 { get_node_neighbors(array,node); }
524 {
return(get_elem_neighbors(array,elem,delem)); }
527 { get_elem_neighbors(array,elem); }
531 {
return (locate_node(loc,p)); }
533 {
return (locate_edge(loc,p)); }
535 {
return (locate_elem(loc,p)); }
540 std::vector<double>& coords,
542 {
return(locate_elem(elem,coords,p)); }
548 {
ASSERTFAIL(
"TriSurfMesh::get_weights(Edges) not supported."); }
551 {
ASSERTFAIL(
"TriSurfMesh::get_weights(Cells) not supported."); }
555 { result = points_[index]; }
557 { points_[index] = point; }
565 "Must call synchronize NORMALS_E on TriSurfMesh first");
566 result = normals_[index];
570 template<
class VECTOR,
class INDEX1,
class INDEX2>
572 INDEX1 eidx, INDEX2 )
575 ElemData ed(*
this, eidx);
576 std::vector<Core::Geometry::Point> Jv;
577 basis_.derivate(coords, ed, Jv);
585 {
return(add_point(p)); }
588 template <
class ARRAY>
591 ASSERTMSG(a.size() == 3,
"TriSurfMesh: Tried to add non-tri element.");
593 faces_.push_back(static_cast<typename Node::index_type>(a[0]));
594 faces_.push_back(static_cast<typename Node::index_type>(a[1]));
595 faces_.push_back(static_cast<typename Node::index_type>(a[2]));
608 template<
class VECTOR,
class INDEX>
611 ElemData ed(*
this, idx);
612 return basis_.get_coords(coords, p, ed);
617 template<
class VECTOR,
class INDEX>
620 ElemData ed(*
this, idx);
621 pt = basis_.interpolate(coords, ed);
627 template<
class VECTOR1,
class INDEX,
class VECTOR2>
628 void derivate(
const VECTOR1 &coords, INDEX idx, VECTOR2 &J)
const
630 ElemData ed(*
this, idx);
631 basis_.derivate(coords, ed, J);
636 template<
class VECTOR,
class INDEX>
640 jacobian(coords,idx,J);
647 template<
class VECTOR,
class INDEX>
648 void jacobian(
const VECTOR& coords, INDEX idx,
double* J)
const
651 ElemData ed(*
this,idx);
652 basis_.derivate(coords,ed,Jv);
669 template<
class VECTOR,
class INDEX>
673 ElemData ed(*
this,idx);
674 basis_.derivate(coords,ed,Jv);
682 template<
class INDEX>
686 ElemData ed(*
this,idx);
691 typename Node::array_type nodes;
692 get_nodes(nodes,idx);
693 get_center(p0,nodes[0]);
694 get_center(p1,nodes[1]);
695 get_center(p2,nodes[2]);
697 double l1 = (p0-p1).length();
698 double l2 = (p1-p2).length();
699 double l3 = (p2-p0).length();
701 double max_scale = l1*l2;
702 if (l2*l3 > max_scale) max_scale = l2*l3;
703 if (l1*l3 > max_scale) max_scale = l1*l3;
705 basis_.derivate(basis_.unit_center,ed,Jv);
710 size_t num_vertices = basis_.number_of_vertices();
711 for (
size_t j=0;j < num_vertices;j++)
713 basis_.derivate(basis_.unit_vertices[j],ed,Jv);
718 if(temp < min_jacobian) min_jacobian = temp;
721 return (min_jacobian/max_scale);
725 template<
class INDEX>
729 ElemData ed(*
this,idx);
733 basis_.derivate(basis_.unit_center,ed,Jv);
740 size_t num_vertices = basis_.number_of_vertices();
741 for (
size_t j=0;j < num_vertices;j++)
743 basis_.derivate(basis_.unit_vertices[j],ed,Jv);
748 if(temp < min_jacobian) min_jacobian = temp;
751 return (min_jacobian);
755 template <
class INDEX>
759 return(find_closest_node(pdist,result,node,p,-1.0));
762 template <
class INDEX>
766 if (maxdist < 0.0) maxdist = DBL_MAX;
else maxdist = maxdist*maxdist;
770 if (sz == 0)
return (
false);
772 if (node >= 0 && node < sz)
775 double dist = (p-point).length2();
777 if ( dist < epsilon2_ )
786 "TriSurfMesh::find_closest_node requires synchronize(NODE_LOCATE_E).")
789 const size_type ni = node_grid_->get_ni()-1;
790 const size_type nj = node_grid_->get_nj()-1;
791 const size_type nk = node_grid_->get_nk()-1;
795 node_grid_->unsafe_locate(bi, bj, bk, p);
798 if (bi > ni) bi = ni;
if (bi < 0) bi = 0;
799 if (bj > nj) bj = nj;
if (bj < 0) bj = 0;
800 if (bk > nk) bk = nk;
if (bk < 0) bk = 0;
802 ei = bi; ej = bj; ek = bk;
804 double dmin = maxdist;
806 bool found_one =
false;
816 if (i < 0 || i > ni)
continue;
819 if (j < 0 || j > nj)
continue;
822 if (k < 0 || k > nk)
continue;
823 if (i == bi || i == ei || j == bj || j == ej || k == bk || k == ek)
825 if (node_grid_->min_distance_squared(p, i, j, k) < dmin)
829 node_grid_->lookup_ijk(it, eit, i, j, k);
834 const double dist = (p-point).length2();
844 if (dmin < epsilon2_)
863 if (!found_one)
return (
false);
869 template <
class ARRAY>
875 "TriSurfMesh::find_closest_node requires synchronize(NODE_LOCATE_E).")
878 const size_type ni = node_grid_->get_ni()-1;
879 const size_type nj = node_grid_->get_nj()-1;
880 const size_type nk = node_grid_->get_nk()-1;
888 node_grid_->unsafe_locate(bi, bj, bk, min);
889 node_grid_->unsafe_locate(ei, ej, ek, max);
892 if (bi > ni) bi = ni;
if (bi < 0) bi = 0;
893 if (bj > nj) bj = nj;
if (bj < 0) bj = 0;
894 if (bk > nk) bk = nk;
if (bk < 0) bk = 0;
896 if (ei > ni) ei = ni;
if (ei < 0) ei = 0;
897 if (ej > nj) ej = nj;
if (ej < 0) ej = 0;
898 if (ek > nk) ek = nk;
if (ek < 0) ek = 0;
900 double maxdist2 = maxdist*maxdist;
908 if (node_grid_->min_distance_squared(p, i, j, k) < maxdist2)
911 node_grid_->lookup_ijk(it, eit, i, j, k);
916 const double dist = (p-point).length2();
920 nodes.push_back(*it);
929 return(nodes.size() > 0);
933 template <
class ARRAY1,
class ARRAY2>
940 "TriSurfMesh::find_closest_node requires synchronize(NODE_LOCATE_E).")
943 const size_type ni = node_grid_->get_ni()-1;
944 const size_type nj = node_grid_->get_nj()-1;
945 const size_type nk = node_grid_->get_nk()-1;
953 node_grid_->unsafe_locate(bi, bj, bk, min);
954 node_grid_->unsafe_locate(ei, ej, ek, max);
957 if (bi > ni) bi = ni;
if (bi < 0) bi = 0;
958 if (bj > nj) bj = nj;
if (bj < 0) bj = 0;
959 if (bk > nk) bk = nk;
if (bk < 0) bk = 0;
961 if (ei > ni) ei = ni;
if (ei < 0) ei = 0;
962 if (ej > nj) ej = nj;
if (ej < 0) ej = 0;
963 if (ek > nk) ek = nk;
if (ek < 0) ek = 0;
965 double maxdist2 = maxdist*maxdist;
973 if (node_grid_->min_distance_squared(p, i, j, k) < maxdist2)
976 node_grid_->lookup_ijk(it, eit, i, j, k);
981 const double dist = (p-point).length2();
985 nodes.push_back(*it);
986 distances.push_back(dist);
995 return(nodes.size() > 0);
1001 template <
class INDEX,
class ARRAY>
1008 return (find_closest_elem(pdist,result,coords,face,p,-1.0));
1013 template <
class INDEX,
class ARRAY>
1019 double maxdist)
const
1021 if (maxdist < 0.0) maxdist = DBL_MAX;
else maxdist = maxdist*maxdist;
1025 if (sz == 0)
return (
false);
1028 if (face >= 0 && face < sz)
1032 points_[faces_[idx+1]], points_[faces_[idx+2]]);
1033 double dist = (p-result).length2();
1034 if ( dist < epsilon2_ )
1038 ElemData ed(*
this,face);
1039 basis_.get_coords(coords,result,ed);
1045 "TriSurfMesh::find_closest_elem requires synchronize(ELEM_LOCATE_E).")
1048 const size_type ni = elem_grid_->get_ni()-1;
1049 const size_type nj = elem_grid_->get_nj()-1;
1050 const size_type nk = elem_grid_->get_nk()-1;
1054 elem_grid_->unsafe_locate(bi, bj, bk, p);
1057 if (bi > ni) bi = ni;
if (bi < 0) bi = 0;
1058 if (bj > nj) bj = nj;
if (bj < 0) bj = 0;
1059 if (bk > nk) bk = nk;
if (bk < 0) bk = 0;
1061 ei = bi; ej = bj; ek = bk;
1063 double dmin = maxdist;
1065 bool found_one =
false;
1074 if (i < 0 || i > ni)
continue;
1077 if (j < 0 || j > nj)
continue;
1080 if (k < 0 || k > nk)
continue;
1081 if (i == bi || i == ei || j == bj || j == ej || k == bk || k == ek)
1083 if (elem_grid_->min_distance_squared(p, i, j, k) < dmin)
1087 elem_grid_->lookup_ijk(it,eit, i, j, k);
1094 points_[faces_[idx ]],
1095 points_[faces_[idx+1]],
1096 points_[faces_[idx+2]]);
1097 const double dtmp = (p - r).length2();
1105 if (dmin < epsilon2_)
1109 ElemData ed(*
this,face);
1110 basis_.get_coords(coords,result,ed);
1128 ElemData ed(*
this,face);
1129 basis_.get_coords(coords,result,ed);
1131 if (!found_one)
return (
false);
1138 template <
class INDEX>
1145 return(find_closest_elem(pdist,result,coords,elem,p,-1.0));
1150 template <
class INDEX>
1153 typename Node::iterator ni, nie;
1163 double min_dist = (p - points_[*ni]).length2();
1164 loc =
static_cast<INDEX
>(*ni);
1169 const double dist = (p - points_[*ni]).length2();
1170 if (dist < min_dist)
1173 loc =
static_cast<INDEX
>(*ni);
1183 template<
class ARRAY>
1192 if (sz == 0)
return (
false);
1195 "TriSurfMesh::find_closest_elems requires synchronize(ELEM_LOCATE_E).")
1198 const size_type ni = elem_grid_->get_ni()-1;
1199 const size_type nj = elem_grid_->get_nj()-1;
1200 const size_type nk = elem_grid_->get_nk()-1;
1204 elem_grid_->unsafe_locate(bi, bj, bk, p);
1207 if (bi > ni) bi = ni;
if (bi < 0) bi = 0;
1208 if (bj > nj) bj = nj;
if (bj < 0) bj = 0;
1209 if (bk > nk) bk = nk;
if (bk < 0) bk = 0;
1211 ei = bi; ej = bj; ek = bk;
1213 double dmin = DBL_MAX;
1224 if (i < 0|| i > ni)
continue;
1227 if (j < 0 || j > nj)
continue;
1230 if (k < 0 || k > nk)
continue;
1231 if (i == bi || i == ei || j == bj || j == ej || k == bk || k == ek)
1233 if (elem_grid_->min_distance_squared(p, i, j, k) < dmin)
1237 elem_grid_->lookup_ijk(it,eit, i, j, k);
1244 points_[faces_[idx ]],
1245 points_[faces_[idx+1]],
1246 points_[faces_[idx+2]]);
1247 const double dtmp = (p - rtmp).length2();
1249 if (dtmp < dmin - epsilon2_)
1253 elems.push_back(
typename ARRAY::value_type(*it));
1257 else if (dtmp < dmin + epsilon2_)
1259 elems.push_back(
typename ARRAY::value_type(*it));
1272 while ((!found)||(dmin == DBL_MAX)) ;
1280 {
return (epsilon_); }
1290 static const std::string type_name(
int n = -1);
1300 {
return face_type_description(); }
1313 double err = 1.0e-3);
1325 bool remove_orphan_nodes();
1327 void orient_faces();
1339 bool insert_node_in_edge_aux(
typename Face::array_type &tris,
1344 bool insert_node_in_face_aux(
typename Face::array_type &tris,
1349 bool insert_node_in_face(
typename Face::array_type &tris,
1362 void collapse_edges(
const std::vector<index_type> &nodemap);
1366 void remove_obvious_degenerate_triangles();
1382 template<
class ARRAY,
class INDEX>
1386 "TriSurfMesh: Must call synchronize EDGES_E on TriSurfMesh first");
1394 array[0] =
static_cast<typename ARRAY::value_type
>(faces_[faceidx*3]);
1395 array[1] =
static_cast<typename ARRAY::value_type
>(faces_[faceidx*3 + 1]);
1397 else if (offset == 1)
1399 array[0] =
static_cast<typename ARRAY::value_type
>(faces_[faceidx*3 + 1]);
1400 array[1] =
static_cast<typename ARRAY::value_type
>(faces_[faceidx*3 + 2]);
1404 array[0] =
static_cast<typename ARRAY::value_type
>(faces_[faceidx*3 + 2]);
1405 array[1] =
static_cast<typename ARRAY::value_type
>(faces_[faceidx*3 ]);
1410 template<
class ARRAY,
class INDEX>
1414 array[0] =
static_cast<typename ARRAY::value_type
>(faces_[idx * 3 + 0]);
1415 array[1] =
static_cast<typename ARRAY::value_type
>(faces_[idx * 3 + 1]);
1416 array[2] =
static_cast<typename ARRAY::value_type
>(faces_[idx * 3 + 2]);
1420 template<
class ARRAY,
class INDEX>
1423 get_nodes_from_face(array,idx);
1427 template<
class ARRAY,
class INDEX>
1431 "TriSurfMesh: Must call synchronize EDGES_E on TriSurfMesh first");
1435 array[0] =
static_cast<typename ARRAY::value_type
>(halfedge_to_edge_[idx * 3 + 0]);
1436 array[1] =
static_cast<typename ARRAY::value_type
>(halfedge_to_edge_[idx * 3 + 1]);
1437 array[2] =
static_cast<typename ARRAY::value_type
>(halfedge_to_edge_[idx * 3 + 2]);
1440 template<
class ARRAY,
class INDEX>
1443 get_edges_from_face(array,idx);
1447 template<
class ARRAY,
class INDEX>
1451 "TriSurfMesh: Must call synchronize NODE_NEIGHBORS_E on TriSurfMesh first");
1453 array.resize(node_neighbors_[idx].
size());
1454 for (
size_t i = 0; i < node_neighbors_[idx].size(); ++i)
1455 array[i] = static_cast<typename ARRAY::value_type>(node_neighbors_[idx][i]);
1459 template<
class ARRAY,
class INDEX>
1463 "Must call synchronize EDGES_E on TriSurfMesh first");
1465 const std::vector<index_type>& faces = edges_[idx];
1470 array.reserve(faces.size());
1475 array.push_back(faces[i]>>2);
1481 template<
class ARRAY,
class INDEX>
1485 "Must call synchronize NODE_NEIGHBORS_E on TriSurfMesh first");
1488 const std::vector<index_type>& faces = node_neighbors_[idx];
1491 typename ARRAY::value_type edge;
1492 for (
size_t i=0; i<faces.size(); i++)
1496 edge = halfedge_to_edge_[faces[i]*3+j];
1498 for (; k<array.size(); k++)
1499 if (array[k] == edge)
break;
1500 if (k == array.size()) array.push_back(edge);
1505 template<
class ARRAY,
class INDEX>
1509 "Must call synchronize NODE_NEIGHBORS_E on TriSurfMesh first");
1512 int n=edge_on_node_[idx].size();
1513 typename ARRAY::value_type edge;
1514 for(
int i=0; i<
n; i++)
1516 edge = edge_on_node_[idx][i];
1518 for (; k<array.size(); k++)
1519 if (array[k] == edge)
break;
1520 if (k == array.size()) array.push_back(edge);
1524 template <
class ARRAY,
class INDEX>
1528 faces_[idx * 3 +
n] = static_cast<index_type>(array[
n]);
1534 template <
class INDEX1,
class INDEX2>
1538 "Must call synchronize EDGES_E on TriSurfMesh first");
1540 const std::vector<index_type>& faces = edges_[delem];
1555 template <
class ARRAY,
class INDEX1,
class INDEX2>
1559 "Must call synchronize EDGES_E on TriSurfMesh first");
1562 const std::vector<index_type>& faces = edges_[delem];
1573 array.push_back(face);
1577 return (array.size() > 0);
1580 template <
class ARRAY,
class INDEX>
1584 "Must call synchronize EDGES_E on TriSurfMesh first");
1586 typename Edge::array_type edges;
1587 get_edges_from_face(edges, idx);
1590 array.reserve(edges.size());
1597 if (get_elem_neighbors(nbor, idx, edges[i]))
1601 array.push_back(nbor[j]);
1607 template <
class ARRAY,
class INDEX>
1611 "Must call synchronize NODE_NEIGHBORS_E on TriSurfMesh first");
1616 const std::vector<index_type>& faces = node_neighbors_[idx];
1618 array.reserve(2*faces.size());
1620 for (
size_t i=0;i<faces.size();i++)
1625 if (faces_[base+j] == idx)
continue;
1627 for (;k<array.size();k++)
1628 if (static_cast<typename ARRAY::value_type>(faces_[base+j]) == array[k])
break;
1629 if (k==array.size())
1630 array.push_back(static_cast<typename ARRAY::value_type>(faces_[base+j]));
1636 template <
class INDEX>
1642 if (sz == 0)
return (
false);
1645 if (node >= 0 && node < sz)
1647 if ((p - points_[node]).length2() < epsilon2_)
return (
true);
1652 "TriSurfMesh::locate_node requires synchronize(NODE_LOCATE_E).")
1655 const size_type ni = node_grid_->get_ni()-1;
1656 const size_type nj = node_grid_->get_nj()-1;
1657 const size_type nk = node_grid_->get_nk()-1;
1661 node_grid_->unsafe_locate(bi, bj, bk, p);
1664 if (bi > ni) bi =ni;
if (bi < 0) bi = 0;
1665 if (bj > nj) bj =nj;
if (bj < 0) bj = 0;
1666 if (bk > nk) bk =nk;
if (bk < 0) bk = 0;
1672 double dmin = DBL_MAX;
1683 if (i < 0 || i > ni)
continue;
1686 if (j < 0 || j > nj)
continue;
1689 if (k < 0 || k > nk)
continue;
1690 if (i == bi || i == ei || j == bj || j == ej || k == bk || k == ek)
1692 if (node_grid_->min_distance_squared(p, i, j, k) < dmin)
1696 node_grid_->lookup_ijk(it, eit, i, j, k);
1701 const double dist = (p-point).length2();
1708 if (dist < epsilon2_)
return (
true);
1721 while ((!found)||(dmin == DBL_MAX)) ;
1729 template <
class INDEX>
1733 "Must call synchronize EDGES_E on TriSurfMesh first");
1735 typename Edge::iterator bi, ei;
1736 typename Node::array_type nodes;
1741 double mindist = 0.0;
1744 get_nodes(nodes,*bi);
1746 points_[nodes[1]],epsilon_);
1747 if (!found || dist < mindist)
1749 loc =
static_cast<INDEX
>(*bi);
1760 template <
class INDEX>
1763 if (basis_.polynomial_order() > 1)
return elem_locate(elem, *
this, p);
1768 if (sz == 0)
return (
false);
1771 if ((elem > 0)&&(elem < sz))
1773 if (inside3_p(elem*3,p))
return (
true);
1777 "TriSurfMesh::locate_elem requires synchronize(ELEM_LOCATE_E).")
1780 if (elem_grid_->lookup(it, eit, p))
1784 if (inside3_p((*it) * 3, p))
1786 elem =
static_cast<INDEX
>(*it);
1795 template <
class ARRAY>
1800 "TriSurfMesh::locate_elems requires synchronize(ELEM_LOCATE_E).")
1805 elem_grid_->locate_clamp(is,js,ks,b.
min());
1806 elem_grid_->locate_clamp(ie,je,ke,b.
max());
1812 elem_grid_->lookup_ijk(it, eit, i, j, k);
1816 for (;p<array.size();p++)
if (array[p] ==
typename ARRAY::value_type(*it))
break;
1817 if (p == array.size()) array.push_back(
typename ARRAY::value_type(*it));
1822 return (array.size() > 0);
1825 template <
class INDEX,
class ARRAY>
1828 if (basis_.polynomial_order() > 1)
return elem_locate(elem, *
this, p);
1833 if (sz == 0)
return (
false);
1836 if ((elem > 0)&&(elem < sz))
1838 if (inside3_p(elem*3,p))
1840 ElemData ed(*
this, elem);
1841 basis_.get_coords(coords, p, ed);
1847 "TriSurfMesh::locate_node requires synchronize(ELEM_LOCATE_E).")
1850 if (elem_grid_->lookup(it, eit, p))
1854 if (inside3_p((*it) * 3, p))
1856 elem =
static_cast<INDEX
>(*it);
1857 ElemData ed(*
this, elem);
1858 basis_.get_coords(coords, p, ed);
1869 template <
class INDEX>
1876 template <
class INDEX>
1879 typename Node::array_type arr;
1880 get_nodes_from_edge(arr, idx);
1881 result = points_[arr[0]];
1882 result += points_[arr[1]];
1887 template <
class INDEX>
1891 typename Node::array_type arr;
1892 get_nodes_from_face(arr, idx);
1893 result = points_[arr[0]];
1894 result += points_[arr[1]];
1895 result += points_[arr[2]];
1896 result *= (1.0/3.0);
1901 std::vector<bool> &tested, std::vector<bool> &flip);
1904 void compute_normals();
1905 void compute_node_neighbors();
1906 void compute_edges();
1908 void compute_edges_bugfix();
1909 void compute_edge_neighbors();
1911 void compute_node_grid();
1912 void compute_elem_grid();
1913 void compute_bounding_box();
1922 void debug_test_edge_neighbors();
1931 std::vector<std::vector<index_type> >
edges_;
1959 #ifdef HAVE_HASH_MAP
1963 size_t operator()(
const std::pair<index_type, index_type> &a)
const
1965 #if defined(__ECC) || defined(_MSC_VER)
1966 hash_compare<int> hasher;
1970 return hasher(static_cast<int>(hasher(a.first) + a.second));
1972 #if defined(__ECC) || defined(_MSC_VER)
1974 static const size_t bucket_size = 4;
1975 static const size_t min_buckets = 8;
1977 bool operator()(
const std::pair<index_type, index_type> &a,
const std::pair<index_type, index_type> &b)
const
1979 return a.first < b.first || a.first == b.first && a.second < b.second;
1986 bool operator()(
const std::pair<index_type, index_type> &a,
const std::pair<index_type, index_type> &b)
const
1988 return a.first == b.first && a.second == b.second;
1996 bool operator()(
const std::pair<index_type, index_type> &a,
const std::pair<index_type, index_type> &b)
const
1998 return a.first < b.first || a.first == b.first && a.second < b.second;
2004 #ifdef HAVE_HASH_MAP
2006 #if defined(__ECC) || defined(_MSC_VER)
2018 #ifdef HAVE_HASH_MAP
2020 #if defined(__ECC) || defined(_MSC_VER)
2021 typedef hash_map<std::pair<index_type, index_type>, std::vector<index_type>, edgehash>
EdgeMapType2;
2023 typedef hash_map<std::pair<index_type, index_type>, std::vector<index_type>, edgehash,
edgecompare>
EdgeMapType2;
2043 template <
class Basis>
2047 template <
class Basis>
2051 ASSERT((n >= -1) && n <= 1);
2059 static const std::string nm(
"TriSurfMesh");
2069 template <
class Basis>
2075 synchronize_lock_(
"TriSurfMesh lock"),
2076 synchronize_cond_(
"TriSurfMesh condition variable"),
2077 synchronized_(
Mesh::NODES_E |
Mesh::FACES_E |
Mesh::CELLS_E),
2089 template <
class Basis>
2094 halfedge_to_edge_(0),
2099 synchronize_lock_(
"TriSurfMesh lock"),
2100 synchronize_cond_(
"TriSurfMesh condition variable"),
2101 synchronized_(
Mesh::NODES_E |
Mesh::FACES_E |
Mesh::CELLS_E),
2111 copy.synchronize_lock_.lock();
2130 copy.synchronize_lock_.unlock();
2139 template <
class Basis>
2147 template <
class Basis>
2156 if (u + v > 1.0) { u = 1.0 - u; v = 1.0 -
v; }
2162 p = p0+((p1-p0)*u)+((p2-p0)*v);
2167 template <
class Basis>
2177 result.
extend(points_[*ni]);
2183 template <
class Basis>
2193 template <
class Basis>
2197 synchronize_lock_.lock();
2198 std::vector<Core::Geometry::Point>::iterator itr = points_.
begin();
2199 std::vector<Core::Geometry::Point>::iterator eitr = points_.end();
2216 bbox_.extend(point(*ni));
2221 epsilon_ = bbox_.diagonal().length()*1e-8;
2222 epsilon2_ = epsilon_*epsilon_;
2224 synchronized_ |= Mesh::BOUNDING_BOX_E;
2227 if (node_grid_) { node_grid_->transform(t); }
2228 if (elem_grid_) { elem_grid_->transform(t); }
2230 synchronize_lock_.unlock();
2234 template <
class Basis>
2238 ASSERTMSG(synchronized_ & Mesh::NODES_E,
2239 "Must call synchronize NODES_E on TriSurfMesh first");
2244 template <
class Basis>
2248 ASSERTMSG(synchronized_ & Mesh::NODES_E,
2249 "Must call synchronize NODES_E on TriSurfMesh first");
2250 itr =
static_cast<index_type>(points_.size());
2254 template <
class Basis>
2258 ASSERTMSG(synchronized_ & Mesh::EDGES_E,
2259 "Must call synchronize EDGES_E on TriSurfMesh first");
2264 template <
class Basis>
2268 ASSERTMSG(synchronized_ & Mesh::EDGES_E,
2269 "Must call synchronize EDGES_E on TriSurfMesh first");
2270 itr =
static_cast<index_type>(edges_.size());
2274 template <
class Basis>
2278 ASSERTMSG(synchronized_ & Mesh::FACES_E,
2279 "Must call synchronize FACES_E on TriSurfMesh first");
2284 template <
class Basis>
2288 ASSERTMSG(synchronized_ & Mesh::FACES_E,
2289 "Must call synchronize FACES_E on TriSurfMesh first");
2290 itr =
static_cast<index_type>(faces_.size() / 3);
2294 template <
class Basis>
2298 ASSERTMSG(synchronized_ & Mesh::CELLS_E,
2299 "Must call synchronize CELLS_E on TriSurfMesh first");
2304 template <
class Basis>
2308 ASSERTMSG(synchronized_ & Mesh::CELLS_E,
2309 "Must call synchronize CELLS_E on TriSurfMesh first");
2314 template <
class Basis>
2331 template <
class Basis>
2340 std::vector<double> coords(2);
2341 if (get_coords(coords, p, idx))
2343 basis_.get_weights(coords, w);
2344 return basis_.dofs();
2351 template <
class Basis>
2367 const double s = a0+a1+a2;
2372 return fabs(s - a) < epsilon2_ && a > epsilon2_;
2376 template <
class Basis>
2381 if (sync & (Mesh::DELEMS_E))
2382 { sync |= Mesh::EDGES_E; sync &= ~(Mesh::DELEMS_E); }
2384 if (sync & Mesh::FIND_CLOSEST_NODE_E)
2385 { sync |= NODE_LOCATE_E; sync &= ~(Mesh::FIND_CLOSEST_NODE_E); }
2387 if (sync & Mesh::FIND_CLOSEST_ELEM_E)
2388 { sync |= ELEM_LOCATE_E; sync &= ~(Mesh::FIND_CLOSEST_ELEM_E); }
2390 if (sync & (Mesh::NODE_LOCATE_E|Mesh::ELEM_LOCATE_E)) sync |= Mesh::BOUNDING_BOX_E;
2391 if (sync & Mesh::ELEM_NEIGHBORS_E) sync |= Mesh::EDGES_E;
2394 sync &= (Mesh::EDGES_E|Mesh::NORMALS_E|
2395 Mesh::NODE_NEIGHBORS_E|Mesh::BOUNDING_BOX_E|
2396 Mesh::ELEM_NEIGHBORS_E|
2397 Mesh::NODE_LOCATE_E|Mesh::ELEM_LOCATE_E);
2402 sync &= (~synchronized_);
2404 if (sync == Mesh::EDGES_E)
2407 synchronize_lock_.unlock();
2409 synchronize_lock_.lock();
2411 else if (sync & Mesh::EDGES_E)
2415 boost::thread syncthread(syncclass);
2418 if (sync == Mesh::NORMALS_E)
2421 synchronize_lock_.unlock();
2423 synchronize_lock_.lock();
2425 else if (sync & Mesh::NORMALS_E)
2429 boost::thread syncthread(syncclass);
2432 if (sync == Mesh::NODE_NEIGHBORS_E)
2435 synchronize_lock_.unlock();
2437 synchronize_lock_.lock();
2439 else if (sync & Mesh::NODE_NEIGHBORS_E)
2441 mask_type tosync = Mesh::NODE_NEIGHBORS_E;
2443 boost::thread syncthread(syncclass);
2446 if (sync == Mesh::ELEM_NEIGHBORS_E)
2449 synchronize_lock_.unlock();
2451 synchronize_lock_.lock();
2453 else if (sync & Mesh::ELEM_NEIGHBORS_E)
2455 mask_type tosync = Mesh::ELEM_NEIGHBORS_E;
2457 boost::thread syncthread(syncclass);
2460 if (sync == Mesh::BOUNDING_BOX_E)
2463 synchronize_lock_.unlock();
2465 synchronize_lock_.lock();
2467 else if (sync & Mesh::BOUNDING_BOX_E)
2469 mask_type tosync = Mesh::BOUNDING_BOX_E;
2471 boost::thread syncthread(syncclass);
2474 if (sync == Mesh::NODE_LOCATE_E)
2477 synchronize_lock_.unlock();
2479 synchronize_lock_.lock();
2481 else if (sync & Mesh::NODE_LOCATE_E)
2485 boost::thread syncthread(syncclass);
2488 if (sync == Mesh::ELEM_LOCATE_E)
2491 synchronize_lock_.unlock();
2493 synchronize_lock_.lock();
2495 else if (sync & Mesh::ELEM_LOCATE_E)
2499 boost::thread syncthread(syncclass);
2503 while ((synchronized_ & sync) != sync)
2505 synchronize_cond_.wait(lock);
2511 template <
class Basis>
2518 template <
class Basis>
2522 synchronize_lock_.lock();
2524 synchronized_ = Mesh::NODES_E | Mesh::ELEMS_E | Mesh::FACES_E | Mesh::CELLS_E;
2528 halfedge_to_edge_.clear();
2529 edge_neighbors_.clear();
2535 synchronize_lock_.unlock();
2541 template <
class Basis>
2545 normals_.resize(points_.size());
2548 std::vector<std::vector<typename Face::index_type> > node_in_faces(points_.size());
2550 std::vector<Core::Geometry::Vector> face_normals(faces_.size());
2556 while (iter != iter_end)
2558 get_nodes(nodes, *iter);
2561 get_point(p1, nodes[0]);
2562 get_point(p2, nodes[1]);
2563 get_point(p3, nodes[2]);
2565 node_in_faces[nodes[0]].push_back(*iter);
2566 node_in_faces[nodes[1]].push_back(*iter);
2567 node_in_faces[nodes[2]].push_back(*iter);
2572 face_normals[*iter] =
n;
2577 typename std::vector<std::vector<typename Face::index_type> >::iterator nif_iter =
2578 node_in_faces.begin();
2580 while (nif_iter != node_in_faces.end())
2582 const std::vector<typename Face::index_type> &
v = *nif_iter;
2583 typename std::vector<typename Face::index_type>::const_iterator fiter =
2586 while(fiter != v.end())
2588 ave += face_normals[*fiter];
2592 normals_[i] = ave; ++i;
2596 synchronize_lock_.lock();
2597 synchronized_ |= Mesh::NORMALS_E;
2598 synchronize_lock_.unlock();
2602 template <
class Basis>
2606 const bool do_neighbors = synchronized_ & Mesh::ELEM_NEIGHBORS_E;
2607 const bool do_normals =
false;
2614 synchronize_lock_.lock();
2616 faces_.push_back(faces_[f0+1]);
2617 faces_.push_back(faces_[f0+2]);
2618 faces_.push_back(pi);
2620 faces_.push_back(faces_[f0+2]);
2621 faces_.push_back(faces_[f0+0]);
2622 faces_.push_back(pi);
2629 edge_neighbors_.push_back(edge_neighbors_[f0+1]);
2631 edge_neighbors_[edge_neighbors_.back()] = edge_neighbors_.size()-1;
2632 edge_neighbors_.push_back(f2+2);
2633 edge_neighbors_.push_back(f0+1);
2635 edge_neighbors_.push_back(edge_neighbors_[f0+2]);
2637 edge_neighbors_[edge_neighbors_.back()] = edge_neighbors_.size()-1;
2638 edge_neighbors_.push_back(f0+2);
2639 edge_neighbors_.push_back(f1+1);
2641 edge_neighbors_[f0+1] = f1+2;
2642 edge_neighbors_[f0+2] = f2+1;
2648 normals_[faces_[f0]] +
2649 normals_[faces_[f1]] +
2650 normals_[faces_[f2]]);
2652 normals_.push_back(normals_[faces_[f1]]);
2653 normals_.push_back(normals_[faces_[f2]]);
2654 normals_.push_back(normal);
2656 normals_.push_back(normals_[faces_[f2]]);
2657 normals_.push_back(normals_[faces_[f0]]);
2658 normals_.push_back(normal);
2660 normals_[faces_[f0+2]] = normal;
2664 if (!do_neighbors) synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
2665 synchronized_ &= ~(Mesh::EDGES_E);
2666 if (!do_normals) synchronized_ &= ~
Mesh::NORMALS_E;
2668 synchronize_lock_.unlock();
2672 template <
class Basis>
2677 if (!locate(face,p))
return false;
2678 insert_node(face,p);
2683 template <
class Basis>
2687 for (
index_type i = 0; i < static_cast<index_type>(edge_neighbors_.size()); i++)
2690 edge_neighbors_[edge_neighbors_[i]] != i)
2697 template <
class Basis>
2706 synchronize_lock_.lock();
2708 remove_elem_from_grid(halfedge/3);
2712 const index_type nbr = edge_neighbors_[halfedge];
2717 tris.push_back(f1 / 3);
2718 faces_.push_back(ni);
2719 faces_.push_back(faces_[next(halfedge)]);
2720 faces_.push_back(faces_[prev(halfedge)]);
2721 edge_neighbors_.push_back(nbr);
2722 edge_neighbors_.push_back(edge_neighbors_[next(halfedge)]);
2723 edge_neighbors_.push_back(next(halfedge));
2727 edge_neighbors_[edge_neighbors_[next(halfedge)]] = next(f1);
2733 tris.push_back(halfedge / 3);
2734 faces_[next(halfedge)] = ni;
2736 edge_neighbors_[next(halfedge)] = prev(f1);
2737 edge_neighbors_[prev(halfedge)] = edge_neighbors_[prev(halfedge)];
2741 remove_elem_from_grid(nbr / 3);
2744 tris.push_back(f3 / 3);
2745 faces_.push_back(ni);
2746 faces_.push_back(faces_[next(nbr)]);
2747 faces_.push_back(faces_[prev(nbr)]);
2748 edge_neighbors_.push_back(halfedge);
2749 edge_neighbors_.push_back(edge_neighbors_[next(nbr)]);
2750 edge_neighbors_.push_back(next(nbr));
2754 edge_neighbors_[edge_neighbors_[next(nbr)]] = next(f3);
2758 tris.push_back(nbr / 3);
2759 faces_[next(nbr)] = ni;
2760 edge_neighbors_[nbr] = f1;
2761 edge_neighbors_[next(nbr)] = f3+2;
2764 debug_test_edge_neighbors();
2766 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
2767 synchronized_ &= ~(Mesh::EDGES_E);
2768 synchronized_ &= ~
Mesh::NORMALS_E;
2770 for (
size_t i = 0; i < tris.size(); i++)
2772 insert_elem_into_grid(tris[i]);
2775 synchronize_lock_.unlock();
2781 template <
class Basis>
2790 synchronize_lock_.lock();
2792 remove_elem_from_grid(face);
2802 edge_neighbors_[edge_neighbors_[f0+1]] = f1+0;
2806 edge_neighbors_[edge_neighbors_[f0+2]] = f2+0;
2809 tris.push_back(faces_.size() / 3);
2810 faces_.push_back(faces_[f0+1]);
2811 faces_.push_back(faces_[f0+2]);
2812 faces_.push_back(ni);
2813 edge_neighbors_.push_back(edge_neighbors_[f0+1]);
2814 edge_neighbors_.push_back(f2+2);
2815 edge_neighbors_.push_back(f0+1);
2817 tris.push_back(faces_.size() / 3);
2818 faces_.push_back(faces_[f0+2]);
2819 faces_.push_back(faces_[f0+0]);
2820 faces_.push_back(ni);
2821 edge_neighbors_.push_back(edge_neighbors_[f0+2]);
2822 edge_neighbors_.push_back(f0+2);
2823 edge_neighbors_.push_back(f1+1);
2826 tris.push_back(face);
2828 edge_neighbors_[f0+1] = f1+2;
2829 edge_neighbors_[f0+2] = f2+1;
2831 debug_test_edge_neighbors();
2833 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
2834 synchronized_ &= ~(Mesh::EDGES_E);
2835 synchronized_ &= ~
Mesh::NORMALS_E;
2837 for (
size_t i = 0; i < tris.size(); i++)
2839 insert_elem_into_grid(tris[i]);
2842 synchronize_lock_.unlock();
2848 template <
class Basis>
2864 if (a0 >= epsilon2_*epsilon2_) { mask |= 1; }
2865 if (a1 >= epsilon2_*epsilon2_) { mask |= 2; }
2866 if (a2 >= epsilon2_*epsilon2_) { mask |= 4; }
2871 return insert_node_in_face_aux(tris, ni, face, p);
2877 tris.push_back(face);
2878 ni = faces_[face * 3 + 0];
2885 tris.push_back(face);
2886 ni = faces_[face * 3 + 0];
2892 tris.push_back(face);
2893 ni = faces_[face * 3 + 1];
2899 tris.push_back(face);
2900 ni = faces_[face * 3 + 2];
2906 return insert_node_in_edge_aux(tris, ni, face*3+0, p);
2910 return insert_node_in_edge_aux(tris, ni, face*3+2, p);
2914 return insert_node_in_edge_aux(tris, ni, face*3+1, p);
2920 template <
class Basis>
2924 for (
size_t i = 0; i < faces_.size(); i++)
2926 faces_[i] = nodemap[faces_[i]];
2931 template <
class Basis>
2935 std::vector<index_type> oldfaces = faces_;
2937 for (
size_t i = 0; i< oldfaces.size(); i+=3)
2942 if (a != b && a != c && b != c)
2944 faces_.push_back(a);
2945 faces_.push_back(b);
2946 faces_.push_back(c);
2949 synchronized_ = NODES_E | FACES_E | CELLS_E;
2965 #define DEBUGINFO(f) cerr << "Face #" << f/3 << " N1: " << faces_[f+0] << " N2: " << faces_[f+1] << " N3: " << faces_[f+2] << " B1: " << edge_neighbors_[f] << " B2: " << edge_neighbors_[f+1] << " B3: " << edge_neighbors_[f+2] << endl;
2966 template <
class Basis>
2971 const bool do_neighbors = synchronized_ & Mesh::ELEM_NEIGHBORS_E;
2972 const bool do_normals =
false;
2976 get_nodes(nodes,face);
2977 std::vector<Core::Geometry::Vector> normals(3);
2981 points_[faces_[next(f0+edge)]]) / 2.0).asPoint();
2982 nodes[edge] = add_point(p);
2987 normals_[faces_[next(f0+edge)]]);
2988 normals[edge].safe_normalize();
2992 synchronize_lock_.lock();
2995 faces_.push_back(nodes[0]);
2996 faces_.push_back(nodes[3]);
2997 faces_.push_back(nodes[5]);
3000 faces_.push_back(nodes[1]);
3001 faces_.push_back(nodes[4]);
3002 faces_.push_back(nodes[3]);
3005 faces_.push_back(nodes[2]);
3006 faces_.push_back(nodes[5]);
3007 faces_.push_back(nodes[4]);
3009 faces_[f0+0] = nodes[3];
3010 faces_[f0+1] = nodes[4];
3011 faces_[f0+2] = nodes[5];
3016 edge_neighbors_.push_back(edge_neighbors_[f0+0]);
3017 edge_neighbors_.push_back(f0+2);
3020 edge_neighbors_.push_back(edge_neighbors_[f0+1]);
3021 edge_neighbors_.push_back(f0+0);
3024 edge_neighbors_.push_back(edge_neighbors_[f0+2]);
3025 edge_neighbors_.push_back(f0+1);
3029 edge_neighbors_[f0+0] = f2+1;
3030 edge_neighbors_[f0+1] = f3+1;
3031 edge_neighbors_[f0+2] = f1+1;
3036 normals_.push_back(normals_[f0+0]);
3037 normals_.push_back(normals[0]);
3038 normals_.push_back(normals[2]);
3040 normals_.push_back(normals_[f0+1]);
3041 normals_.push_back(normals[1]);
3042 normals_.push_back(normals[0]);
3044 normals_.push_back(normals_[f0+2]);
3045 normals_.push_back(normals[2]);
3046 normals_.push_back(normals[1]);
3048 normals_[f0+0] = normals[0];
3049 normals_[f0+1] = normals[1];
3050 normals_[f0+2] = normals[2];
3058 faces_.push_back(nodes[1]);
3059 faces_.push_back(nodes[3]);
3060 faces_.push_back(faces_[pnbr]);
3061 edge_neighbors_[f2+2] = f4;
3062 edge_neighbors_.push_back(f2+2);
3063 edge_neighbors_.push_back(pnbr);
3064 edge_neighbors_.push_back(edge_neighbors_[pnbr]);
3065 edge_neighbors_[edge_neighbors_.back()] = f4+2;
3066 faces_[nbr] = nodes[3];
3067 edge_neighbors_[pnbr] = f4+1;
3070 normals_[nbr] = normals[0];
3071 normals_.push_back(normals_[f0+1]);
3072 normals_.push_back(normals[0]);
3073 normals_.push_back(normals_[pnbr]);
3082 faces_.push_back(nodes[2]);
3083 faces_.push_back(nodes[4]);
3084 faces_.push_back(faces_[pnbr]);
3085 edge_neighbors_[f3+2] = f5;
3086 edge_neighbors_.push_back(f3+2);
3087 edge_neighbors_.push_back(pnbr);
3088 edge_neighbors_.push_back(edge_neighbors_[pnbr]);
3089 edge_neighbors_[edge_neighbors_.back()] = f5+2;
3090 faces_[nbr] = nodes[4];
3091 edge_neighbors_[pnbr] = f5+1;
3094 normals_[nbr] = normals[1];
3095 normals_.push_back(normals_[f0+2]);
3096 normals_.push_back(normals[1]);
3097 normals_.push_back(normals_[pnbr]);
3106 faces_.push_back(nodes[0]);
3107 faces_.push_back(nodes[5]);
3108 faces_.push_back(faces_[pnbr]);
3109 edge_neighbors_[f1+2] = f6;
3110 edge_neighbors_.push_back(f1+2);
3111 edge_neighbors_.push_back(pnbr);
3112 edge_neighbors_.push_back(edge_neighbors_[pnbr]);
3113 edge_neighbors_[edge_neighbors_.back()] = f6+2;
3114 faces_[nbr] = nodes[5];
3115 edge_neighbors_[pnbr] = f6+1;
3118 normals_[nbr] = normals[2];
3119 normals_.push_back(normals_[f0+0]);
3120 normals_.push_back(normals[2]);
3121 normals_.push_back(normals_[pnbr]);
3125 if (!do_neighbors) synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
3126 synchronized_ &= ~(Mesh::EDGES_E);
3127 if (!do_normals) synchronized_ &= ~
Mesh::NORMALS_E;
3129 synchronize_lock_.unlock();
3133 template <
class Basis>
3137 node_neighbors_.clear();
3138 node_neighbors_.resize(points_.size());
3142 node_neighbors_[faces_[f]].push_back(f/3);
3144 synchronize_lock_.lock();
3145 synchronized_ |= Mesh::NODE_NEIGHBORS_E;
3146 synchronize_lock_.unlock();
3150 template <
class Basis>
3163 if (n0 > n1) edge_map[std::pair<index_type, index_type>(n1,n0)].push_back(i<<2);
3164 else edge_map[std::pair<index_type, index_type>(n0,n1)].push_back(i<<2);
3166 if (n1 > n2) edge_map[std::pair<index_type, index_type>(n2,n1)].push_back((i<<2)+1);
3167 else edge_map[std::pair<index_type, index_type>(n1,n2)].push_back((i<<2)+1);
3169 if (n2 > n0) edge_map[std::pair<index_type, index_type>(n0,n2)].push_back((i<<2)+2);
3170 else edge_map[std::pair<index_type, index_type>(n2,n0)].push_back((i<<2)+2);
3173 typename EdgeMapType2::iterator itr;
3175 edges_.resize(edge_map.size());
3176 halfedge_to_edge_.resize(faces_.size());
3179 for (itr = edge_map.begin(); itr != edge_map.end(); ++itr)
3181 const std::vector<index_type >& hedges = (*itr).second;
3182 for (
size_t j=0; j<hedges.size(); j++)
3185 edges_[k].push_back(h);
3186 halfedge_to_edge_[(h>>2)*3 + (h&0x3)] = k;
3192 synchronize_lock_.lock();
3193 synchronized_ |= (Mesh::EDGES_E);
3194 synchronize_lock_.unlock();
3198 template <
class Basis>
3211 if (n0 > n1) edge_map[std::pair<index_type, index_type>(n1,n0)].push_back(i<<2);
3212 else edge_map[std::pair<index_type, index_type>(n0,n1)].push_back(i<<2);
3214 if (n1 > n2) edge_map[std::pair<index_type, index_type>(n2,n1)].push_back((i<<2)+1);
3215 else edge_map[std::pair<index_type, index_type>(n1,n2)].push_back((i<<2)+1);
3217 if (n2 > n0) edge_map[std::pair<index_type, index_type>(n0,n2)].push_back((i<<2)+2);
3218 else edge_map[std::pair<index_type, index_type>(n2,n0)].push_back((i<<2)+2);
3221 typename EdgeMapType2::iterator itr;
3223 edges_.resize(edge_map.size());
3224 halfedge_to_edge_.resize(faces_.size());
3225 edge_on_node_.clear();
3226 edge_on_node_.resize(points_.size());
3229 for (itr = edge_map.begin(); itr != edge_map.end(); ++itr)
3231 const std::vector<index_type >& hedges = (*itr).second;
3232 for (
size_t j=0; j<hedges.size(); j++)
3235 edges_[k].push_back(h);
3236 halfedge_to_edge_[(h>>2)*3 + (h&0x3)] = k;
3238 edge_on_node_[(*itr).first.first].push_back(k);
3239 edge_on_node_[(*itr).first.second].push_back(k);
3243 synchronize_lock_.lock();
3244 synchronized_ |= (Mesh::EDGES_E);
3245 synchronize_lock_.unlock();
3248 template <
class Basis>
3253 if (search_node(i, p) && (p - points_[i]).length2() < err)
3259 synchronize_lock_.lock();
3260 points_.push_back(p);
3261 node_neighbors_.push_back(std::vector<under_type>());
3262 synchronize_lock_.unlock();
3270 template <
class Basis>
3276 std::set<index_type, less_int> shared;
3277 shared.insert(faces_[face1]);
3278 shared.insert(faces_[face1 + 1]);
3279 shared.insert(faces_[face1 + 2]);
3284 std::pair<std::set<index_type, less_int>::iterator,
bool> p = shared.insert(faces_[face2]);
3285 if (!p.second) { *ns = faces_[face2]; ++ns;}
3286 p = shared.insert(faces_[face2 + 1]);
3287 if (!p.second) { *ns = faces_[face2 + 1]; ++ns;}
3288 p = shared.insert(faces_[face2 + 2]);
3289 if (!p.second) { *ns = faces_[face2 + 2]; }
3292 if (shared.size() > 4)
return false;
3294 std::set<index_type, less_int>::iterator iter = shared.find(not_shar[0]);
3297 iter = shared.find(not_shar[1]);
3300 iter = shared.begin();
3304 synchronize_lock_.lock();
3306 faces_[face1 + 1] = not_shar[0];
3307 faces_[face1 + 2] = s2;
3310 faces_[face2 + 1] = not_shar[1];
3311 faces_[face2 + 2] = s1;
3313 synchronized_ &= ~
Mesh::ELEM_NEIGHBORS_E;
3314 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
3315 synchronized_ &= ~
Mesh::NORMALS_E;
3316 synchronize_lock_.unlock();
3321 template <
class Basis>
3328 std::vector<index_type> onodes;
3330 for (
index_type i = 0; i < static_cast<index_type>(points_.size()); i++) {
3331 if (find(faces_.begin(), faces_.end(), i) == faces_.end()) {
3333 onodes.push_back(i);
3337 if (onodes.size()) rval =
true;
3340 std::vector<index_type>::reverse_iterator orph_iter = onodes.rbegin();
3341 while (orph_iter != onodes.rend())
3344 std::vector<index_type>::iterator iter = faces_.
begin();
3345 while (iter != faces_.end())
3353 std::vector<Core::Geometry::Point>::iterator niter = points_.begin();
3355 points_.erase(niter);
3358 synchronized_ &= ~
Mesh::ELEM_NEIGHBORS_E;
3359 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
3360 synchronized_ &= ~
Mesh::NORMALS_E;
3364 template <
class Basis>
3370 synchronize_lock_.lock();
3371 std::vector<under_type>::iterator fb = faces_.
begin() + f*3;
3372 std::vector<under_type>::iterator fe = fb + 3;
3374 if (fe <= faces_.end())
3375 faces_.erase(fb, fe);
3379 synchronized_ &= ~
Mesh::ELEM_NEIGHBORS_E;
3380 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
3381 synchronized_ &= ~
Mesh::NORMALS_E;
3382 synchronize_lock_.unlock();
3388 template <
class Basis>
3394 synchronize_lock_.lock();
3395 faces_.push_back(a);
3396 faces_.push_back(b);
3397 faces_.push_back(c);
3398 synchronized_ &= ~
Mesh::ELEM_NEIGHBORS_E;
3399 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
3400 synchronized_ &= ~
Mesh::NORMALS_E;
3401 synchronize_lock_.unlock();
3406 template <
class Basis>
3410 synchronize_lock_.lock();
3414 while (fiter != fend)
3419 synchronized_ &= ~(Mesh::EDGES_E);
3420 synchronized_ &= ~
Mesh::ELEM_NEIGHBORS_E;
3421 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
3422 synchronized_ &= ~
Mesh::NORMALS_E;
3423 synchronize_lock_.unlock();
3427 template <
class Basis>
3433 faces_[base + 1] = faces_[base + 2];
3434 faces_[base + 2] = tmp;
3436 synchronized_ &= ~(Mesh::EDGES_E);
3437 synchronized_ &= ~
Mesh::ELEM_NEIGHBORS_E;
3438 synchronized_ &= ~
Mesh::NODE_NEIGHBORS_E;
3439 synchronized_ &= ~
Mesh::NORMALS_E;
3443 template <
class Basis>
3446 std::vector<bool> &tested,
3447 std::vector<bool> &flip)
3449 tested[face] =
true;
3453 const index_type nbr = edge_neighbors_[edge];
3456 if (!flip[face] && faces_[edge] == faces_[nbr] ||
3457 flip[face] && faces_[next(edge)] == faces_[nbr])
3461 walk_face_orient(nbr/3, tested, flip);
3466 template <
class Basis>
3470 synchronize(Mesh::EDGES_E | Mesh::ELEM_NEIGHBORS_E);
3471 synchronize_lock_.lock();
3474 std::vector<bool> tested(nfaces,
false);
3475 std::vector<bool> flip(nfaces,
false);
3480 while (fiter != fend)
3482 if (! tested[*fiter])
3484 walk_face_orient(*fiter, tested, flip);
3490 while (fiter != fend)
3499 synchronized_ &= ~(Mesh::EDGES_E);
3500 synchronized_ &= ~
Mesh::ELEM_NEIGHBORS_E;
3501 synchronized_ &= ~
Mesh::NORMALS_E;
3502 synchronize_lock_.unlock();
3506 template <
class Basis>
3512 edge_neighbors_.resize(faces_.size());
3513 for (
size_t j = 0; j < edge_neighbors_.size(); j++)
3519 for (i=static_cast<index_type>(faces_.size()-1); i >= 0; i--)
3527 if (n0 > n1) { tmp = n0; n0 = n1; n1 = tmp; }
3529 std::pair<index_type, index_type> nodes(n0, n1);
3531 typename EdgeMapType::iterator maploc;
3533 maploc = edge_map.find(nodes);
3534 if (maploc != edge_map.end())
3536 edge_neighbors_[(*maploc).second] = i;
3537 edge_neighbors_[i] = (*maploc).second;
3539 edge_map[nodes] = i;
3542 debug_test_edge_neighbors();
3544 synchronize_lock_.lock();
3545 synchronized_ |= Mesh::ELEM_NEIGHBORS_E;
3546 synchronize_lock_.unlock();
3550 template <
class Basis>
3558 box.
extend(points_[faces_[idx]]);
3559 box.
extend(points_[faces_[idx+1]]);
3560 box.
extend(points_[faces_[idx+2]]);
3562 elem_grid_->insert(ci, box);
3566 template <
class Basis>
3572 box.
extend(points_[faces_[idx]]);
3573 box.
extend(points_[faces_[idx+1]]);
3574 box.
extend(points_[faces_[idx+2]]);
3576 elem_grid_->remove(ci, box);
3580 template <
class Basis>
3586 node_grid_->insert(ni,points_[ni]);
3590 template <
class Basis>
3594 node_grid_->remove(ni,points_[ni]);
3598 template <
class Basis>
3609 3*
static_cast<size_type>((ceil(pow(static_cast<double>(esz) , (1.0/3.0))))/2.0 + 1.0);
3612 double trace = (diag.
x()+diag.
y()+diag.
z());
3621 begin(ci); end(cie);
3624 insert_elem_into_grid(*ci);
3629 synchronize_lock_.lock();
3630 synchronized_ |= Mesh::ELEM_LOCATE_E;
3631 synchronize_lock_.unlock();
3635 template <
class Basis>
3646 ((ceil(pow(static_cast<double>(esz) , (1.0/3.0))))/2.0 + 1.0);
3649 double trace = (diag.
x()+diag.
y()+diag.
z());
3658 begin(ni); end(nie);
3662 insert_node_into_grid(*ni);
3667 synchronize_lock_.lock();
3668 synchronized_ |= Mesh::NODE_LOCATE_E;
3669 synchronize_lock_.unlock();
3673 template <
class Basis>
3685 bbox_.extend(point(*ni));
3690 epsilon_ = bbox_.diagonal().length()*1e-8;
3691 epsilon2_ = epsilon_*epsilon_;
3693 synchronize_lock_.lock();
3694 synchronized_ |= Mesh::BOUNDING_BOX_E;
3695 synchronize_lock_.unlock();
3699 template <
class Basis>
3703 points_.push_back(p);
3709 template <
class Basis>
3715 return add_triangle(add_find_point(p0), add_find_point(p1), add_find_point(p2));
3718 #define TRISURFMESH_VERSION 4
3720 template <
class Basis>
3728 Pio(stream, points_);
3734 std::vector<unsigned int> old;
3745 if (stream.
reading() && edge_neighbors_.size())
3747 synchronized_ |= Mesh::ELEM_NEIGHBORS_E;
3754 template <
class Basis>
3763 template <
class Basis>
3767 ASSERTMSG(synchronized_ & Mesh::EDGES_E,
3768 "Must call synchronize EDGES_E on TriSurfMesh first");
3775 template <
class Basis>
3784 template <
class Basis>
3793 template <
class Basis>
3804 std::string(__FILE__),
3806 TypeDescription::MESH_E);
3812 template <
class Basis>
3813 const TypeDescription*
3820 template <
class Basis>
3830 std::string(__FILE__),
3832 TypeDescription::MESH_E);
3838 template <
class Basis>
3848 std::string(__FILE__),
3850 TypeDescription::MESH_E);
3856 template <
class Basis>
3866 std::string(__FILE__),
3868 TypeDescription::MESH_E);
3874 template <
class Basis>
3884 std::string(__FILE__),
3886 TypeDescription::MESH_E);
3891 template <
class Basis>
3896 ASSERTMSG(synchronized_ & ELEM_NEIGHBORS_E,
3897 "Must call synchronize ELEM_NEIGHBORS_E on TriSurfMesh first");
3898 nbr_half_edge = edge_neighbors_[half_edge];
boost::shared_ptr< TriSurfMesh< Basis > > handle_type
Definition: TriSurfMesh.h:117
virtual TriSurfMesh * clone() const
Definition: TriSurfMesh.h:307
void get_normal(Core::Geometry::Vector &result, VECTOR &coords, INDEX1 eidx, INDEX2)
Get the normals at the outside of the element.
Definition: TriSurfMesh.h:571
SCIRun::index_type under_type
Definition: TriSurfMesh.h:112
boost::shared_ptr< VMesh > vmesh_
Definition: TriSurfMesh.h:1957
Interface to statically allocated std::vector class.
Definition: VUnstructuredMesh.h:41
static PersistentTypeID trisurf_typeid
This ID is created as soon as this class will be instantiated.
Definition: TriSurfMesh.h:1288
std::vector< Core::Geometry::Point > points_
Actual parameters.
Definition: TriSurfMesh.h:1930
bool reading() const
Definition: Persistent.h:164
Distinct type for node FieldIterator.
Definition: FieldIterator.h:89
void get_edges_from_node_bugfix(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1506
bool get_neighbor(typename Elem::index_type &neighbor, typename Elem::index_type elem, typename DElem::index_type delem) const
Get neighbors of an element or a node.
Definition: TriSurfMesh.h:512
Node::index_type add_node(const Core::Geometry::Point &p)
Definition: TriSurfMesh.h:584
bool operator()(const index_type s1, const index_type s2) const
Definition: TriSurfMesh.h:2037
Definition: FieldRNG.h:37
void get_edge_center(Core::Geometry::Point &result, INDEX idx) const
Definition: TriSurfMesh.h:1877
std::string get_name(const std::string &type_sep_start="<", const std::string &type_sep_end="> ") const
Definition: TypeDescription.cc:135
Distinct type for face Iterator.
Definition: FieldIterator.h:121
Basis basis_
Definition: TriSurfMesh.h:1951
CellIndex< under_type > size_type
Definition: TriSurfMesh.h:145
void resize_nodes(size_type s)
Definition: TriSurfMesh.h:602
Definition: ConditionVariable.h:45
SCIRun::index_type index_type
Definition: TriSurfMesh.h:113
bool locate_elem(INDEX &elem, const Core::Geometry::Point &p) const
Locate an element inside the mesh using the lookup table.
Definition: TriSurfMesh.h:1761
std::vector< index_type > array_type
Definition: TriSurfMesh.h:146
Point max() const
Definition: BBox.h:195
#define ASSERTMSG(condition, message)
Definition: Exception.h:113
void get_elems(typename Elem::array_type &array, typename Face::index_type idx) const
Definition: TriSurfMesh.h:430
void get_center(Core::Geometry::Point &, typename Cell::index_type) const
Definition: TriSurfMesh.h:473
double get_size(typename Edge::index_type idx) const
Definition: TriSurfMesh.h:480
static const TypeDescription * elem_type_description()
Definition: TriSurfMesh.h:1299
const Core::Geometry::Point & node2() const
Definition: TriSurfMesh.h:217
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, INDEX &elem, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:1139
void interpolate(Core::Geometry::Point &pt, VECTOR &coords, INDEX idx) const
Definition: TriSurfMesh.h:618
Definition: Persistent.h:89
Basis basis_type
Definition: TriSurfMesh.h:118
double inverse_jacobian(const VECTOR &coords, INDEX idx, double *Ji) const
Definition: TriSurfMesh.h:670
bool locate(typename Elem::index_type &elem, std::vector< double > &coords, const Core::Geometry::Point &p)
Definition: TriSurfMesh.h:539
void get_neighbors(std::vector< typename Node::index_type > &array, typename Node::index_type node) const
These are more general implementations.
Definition: TriSurfMesh.h:518
bool locate_node(INDEX &node, const Core::Geometry::Point &p) const
Locate a node inside the mesh using the lookup table.
Definition: TriSurfMesh.h:1637
index_type edge2_index() const
Definition: TriSurfMesh.h:199
#define TRISURFMESH_VERSION
Definition: TriSurfMesh.h:3718
Definition: TriCubicHmt.h:58
std::vector< std::vector< index_type > > node_neighbors_
Definition: TriSurfMesh.h:1936
void resize_elems(size_type s)
Definition: TriSurfMesh.h:603
bool get_neighbors(std::vector< typename Elem::index_type > &array, typename Elem::index_type elem, typename DElem::index_type delem) const
Definition: TriSurfMesh.h:521
index_type edge0_index() const
Definition: TriSurfMesh.h:191
void get_cells(typename Cell::array_type &, typename Face::index_type) const
Definition: TriSurfMesh.h:421
double InverseMatrix3P(const PointVector &p, double *q)
Inline templated inverse matrix.
Definition: Locate.h:72
void get_cells(typename Cell::array_type &, typename Edge::index_type) const
Definition: TriSurfMesh.h:419
void to_index(typename Edge::index_type &index, index_type i) const
Definition: TriSurfMesh.h:381
void get_faces(typename Face::array_type &array, typename Edge::index_type idx) const
Definition: TriSurfMesh.h:410
void derivate(const VECTOR1 &coords, INDEX idx, VECTOR2 &J) const
Definition: TriSurfMesh.h:628
Definition: Persistent.h:187
bool index_(ArrayMathProgramCode &pc)
Definition: ArrayMathFunctionSourceSink.cc:636
Elem::index_type add_elem(ARRAY a)
Add a new element to the mesh.
Definition: TriSurfMesh.h:589
index_type edge1_index() const
Definition: TriSurfMesh.h:195
BBox & extend(const Point &p)
Expand the bounding box to include point p.
Definition: BBox.h:98
void to_index(typename Face::index_type &index, index_type i) const
Definition: TriSurfMesh.h:383
double get_area(typename Face::index_type idx) const
Definition: TriSurfMesh.h:503
void get_nodes(typename Node::array_type &, typename Cell::index_type) const
Definition: TriSurfMesh.h:396
void get_face_center(Core::Geometry::Point &result, INDEX idx) const
Definition: TriSurfMesh.h:1888
Definition: TypeDescription.h:45
#define SCISHARE
Definition: share.h:39
std::vector< const TypeDescription * > td_vec
Definition: TypeDescription.h:56
void get_edges_from_node(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1482
std::map< std::pair< index_type, index_type >, index_type, edgecompare > EdgeMapType
Definition: QuadSurfMesh.h:2930
ElemData(const TriSurfMesh< Basis > &msh, const index_type ind)
Definition: TriSurfMesh.h:165
VMesh * CreateVTriSurfMesh(MESH *)
Definition: TriSurfMesh.h:81
void run()
Definition: TriSurfMesh.h:239
FaceIterator< under_type > iterator
Definition: TriSurfMesh.h:137
boost::shared_ptr< Mesh > MeshHandle
Definition: DatatypeFwd.h:67
index_type elem_index() const
Definition: TriSurfMesh.h:204
#define MESH_NO_NEIGHBOR
Definition: MeshTraits.h:67
Distinct type for cell Iterator.
Definition: FieldIterator.h:134
void get_faces(typename Face::array_type &array, typename Node::index_type idx) const
Definition: TriSurfMesh.h:408
int get_weights(const Core::Geometry::Point &, typename Edge::array_type &, double *)
Definition: TriSurfMesh.h:547
unsigned int mask_type
Definition: Types.h:45
bool locate(typename Cell::index_type &, const Core::Geometry::Point &) const
Definition: TriSurfMesh.h:536
void get_node_neighbors(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1608
std::map< std::pair< index_type, index_type >, std::vector< index_type >, edgecompare > EdgeMapType2
Definition: QuadSurfMesh.h:2944
bool find_closest_node(double &pdist, Core::Geometry::Point &result, INDEX &node, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:756
Point & asPoint() const
Definition: Vector.h:457
Definition: TriSurfMesh.h:2035
NodeIndex< under_type > index_type
Definition: TriSurfMesh.h:122
#define ASSERT(condition)
Definition: Assert.h:110
virtual bool has_normals() const
Has this mesh normals.
Definition: TriSurfMesh.h:347
Definition: TriSurfMesh.h:75
bool get_elem_neighbor(INDEX1 &neighbor, INDEX1 elem, INDEX2 delem) const
Definition: TriSurfMesh.h:1535
Index and Iterator types required for Mesh Concept.
Definition: TriSurfMesh.h:121
virtual ~TriSurfMesh()
Destructor.
Definition: TriSurfMesh.h:2140
SCIRun::size_type size_type
Definition: TriSurfMesh.h:114
virtual int begin_class(const std::string &name, int current_version)
Definition: Persistent.cc:143
bool locate(typename Edge::index_type &loc, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:532
boost::shared_ptr< SearchGridT< index_type > > node_grid_
Definition: TriSurfMesh.h:1939
bool search_node(INDEX &loc, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:1151
Core::Geometry::BBox bbox_
Definition: TriSurfMesh.h:1953
void get_nodes(typename Node::array_type &array, typename Face::index_type idx) const
Definition: TriSurfMesh.h:394
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, INDEX &face, const Core::Geometry::Point &p, double maxdist) const
Definition: TriSurfMesh.h:1014
static MeshHandle mesh_maker()
This function returns a handle for the virtual interface.
Definition: TriSurfMesh.h:1305
void get_delems(typename DElem::array_type &array, typename Edge::index_type idx) const
Definition: TriSurfMesh.h:437
bool find_closest_nodes(ARRAY1 &distances, ARRAY2 &nodes, const Core::Geometry::Point &p, double maxdist) const
Definition: TriSurfMesh.h:934
std::vector< index_type > array_type
Definition: TriSurfMesh.h:132
double epsilon2_
Definition: TriSurfMesh.h:1955
boost::unique_lock< boost::mutex > UniqueLock
Definition: ConditionVariable.h:43
double DetMatrix3P(const VectorOfPoints &p)
Inline templated determinant of matrix.
Definition: Locate.h:120
std::vector< std::vector< index_type > > edges_
Definition: TriSurfMesh.h:1931
const string find_type_name(float *)
Definition: TypeName.cc:63
void node_reserve(size_type s)
Definition: TriSurfMesh.h:600
std::vector< index_type > halfedge_to_edge_
Definition: TriSurfMesh.h:1932
double length2() const
Definition: Vector.h:248
T DetMatrix3x3(const T *p)
Definition: Locate.h:95
FaceIndex< under_type > index_type
Definition: TriSurfMesh.h:136
bool operator()(const std::pair< index_type, index_type > &a, const std::pair< index_type, index_type > &b) const
Definition: TriSurfMesh.h:1996
static index_type prev(index_type i)
Definition: TriSurfMesh.h:1927
Definition: VMeshShared.h:40
virtual VMesh * vmesh()
Access point to virtual interface.
Definition: TriSurfMesh.h:315
void get_center(Core::Geometry::Point &result, typename Face::index_type idx) const
Definition: TriSurfMesh.h:471
Definition: ParallelLinearAlgebraTests.cc:358
double jacobian_metric(INDEX idx) const
Definition: TriSurfMesh.h:726
double get_size(typename Cell::index_type) const
Definition: TriSurfMesh.h:497
bool locate_edge(INDEX &loc, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:1730
Definition: SearchGridT.h:47
TriSurfMesh< Basis >::index_type index_type
Definition: TriSurfMesh.h:163
const char * name[]
Definition: BoostGraphExampleTests.cc:87
double get_length(typename Edge::index_type idx) const
More specific names for get_size.
Definition: TriSurfMesh.h:501
void get_edges(typename Edge::array_type &array, typename Face::index_type idx) const
Definition: TriSurfMesh.h:403
void Pio_index(Piostream &stream, index_type *data, size_type size)
Definition: Persistent.cc:606
long long size_type
Definition: Types.h:40
TriSurfMesh()
Construct a new mesh;.
Definition: TriSurfMesh.h:2070
Definition: MTextFileToTriSurf_Plugin.cc:51
std::vector< index_type > faces_
Definition: TriSurfMesh.h:1933
Definition: StackVector.h:50
bool find_closest_elems(double &pdist, Core::Geometry::Point &result, ARRAY &elems, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:1184
Vector Cross(const Vector &v1, const Vector &v2)
Definition: Vector.h:378
double det_jacobian(const VECTOR &coords, INDEX idx) const
Definition: TriSurfMesh.h:637
Definition: TriSurfMesh.h:233
bool find_closest_node(double &pdist, Core::Geometry::Point &result, INDEX &node, const Core::Geometry::Point &p, double maxdist) const
Definition: TriSurfMesh.h:763
Vector diagonal() const
Definition: BBox.h:198
void begin(typename Node::iterator &) const
begin/end iterators
Definition: TriSurfMesh.h:2236
static index_type next(index_type i)
Definition: TriSurfMesh.h:1926
std::vector< index_type > array_type
Definition: TriSurfMesh.h:139
Definition: TriQuadraticLgn.h:58
void get_elems(typename Elem::array_type &array, typename Edge::index_type idx) const
Definition: TriSurfMesh.h:428
std::vector< INDEX >::iterator iterator
Definition: SearchGridT.h:53
const Core::Geometry::Point & node0() const
Definition: TriSurfMesh.h:209
mask_type synchronized_
Definition: TriSurfMesh.h:1947
virtual int topology_geometry() const
Definition: TriSurfMesh.h:327
bool get_coords(VECTOR &coords, const Core::Geometry::Point &p, INDEX idx) const
Definition: TriSurfMesh.h:609
Point min() const
Definition: BBox.h:192
Distinct type for face index.
Definition: FieldIndex.h:90
Definition: QuadSurfMesh.h:2910
int get_weights(const Core::Geometry::Point &, typename Cell::array_type &, double *)
Definition: TriSurfMesh.h:550
void get_cells(typename Cell::array_type &, typename Node::index_type) const
Definition: TriSurfMesh.h:417
void x(double)
Definition: Vector.h:175
void set_nodes_by_elem(ARRAY &array, INDEX idx)
Definition: TriSurfMesh.h:1525
index_type node1_index() const
Definition: TriSurfMesh.h:181
void closest_point_on_tri(Point &result, const Point &orig, const Point &p0, const Point &p1, const Point &p2, const double epsilon)
Definition: CompGeom.cc:136
void to_index(typename Cell::index_type &index, index_type i) const
Definition: TriSurfMesh.h:385
void get_nodes_from_elem(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1421
void get_faces(typename Face::array_type &array, typename Face::index_type idx) const
Definition: TriSurfMesh.h:412
void pwl_approx_edge(std::vector< VECTOR > &coords, INDEX ci, unsigned int which_edge, unsigned int div_per_unit) const
Definition: TriSurfMesh.h:447
std::vector< index_type > edge_neighbors_
Definition: TriSurfMesh.h:1934
void get_edges_from_elem(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1441
void get_elem_neighbors(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1581
virtual MeshFacadeHandle getFacade() const
Definition: TriSurfMesh.h:309
static const std::string make_template_id(const std::string &templateName, const std::string &templateParam)
Definition: TypeName.h:62
void get_delems(typename DElem::array_type &, typename Cell::index_type) const
Definition: TriSurfMesh.h:441
index_type node2_index() const
Definition: TriSurfMesh.h:185
boost::shared_ptr< SearchGridT< index_type > > elem_grid_
Definition: TriSurfMesh.h:1940
v
Definition: readAllFields.py:42
double normalize()
Definition: Vector.h:437
void get_center(Core::Geometry::Point &result, typename Edge::index_type idx) const
Definition: TriSurfMesh.h:469
FaceIndex< under_type > size_type
Definition: TriSurfMesh.h:138
Basis & get_basis()
Get the basis class.
Definition: TriSurfMesh.h:356
double get_epsilon() const
Definition: TriSurfMesh.h:1279
EdgeIterator< under_type > iterator
Definition: TriSurfMesh.h:130
void get_cells(typename Cell::array_type &, typename Cell::index_type) const
Definition: TriSurfMesh.h:423
void get_point(Core::Geometry::Point &result, typename Node::index_type index) const
Access the nodes of the mesh.
Definition: TriSurfMesh.h:554
void y(double)
Definition: Vector.h:185
double safe_normalize()
Definition: Vector.h:236
double distance_to_line2(const Point &p, const Point &a, const Point &b, const double epsilon)
Definition: CompGeom.cc:53
double get_volume(typename Cell::index_type) const
Definition: TriSurfMesh.h:505
Distinct type for edge Iterator.
Definition: FieldIterator.h:105
StackVector< index_type, 4 > array_type
Definition: TriSurfMesh.h:125
Definition: TriLinearLgn.h:324
#define ASSERTFAIL(string)
Definition: Assert.h:52
index_type node0_index() const
Definition: TriSurfMesh.h:177
Definition: TriSurfMesh.h:160
virtual bool is_editable() const
Check whether mesh can be altered by adding nodes or elements.
Definition: TriSurfMesh.h:341
virtual std::string dynamic_type_name() const
Definition: TriSurfMesh.h:1291
Some convenient simple iterators for fields.
Definition: TriSurfMesh.h:128
NodeIndex< under_type > size_type
Definition: TriSurfMesh.h:124
double get_size(typename Node::index_type) const
Get the size of an elemnt (length, area, volume)
Definition: TriSurfMesh.h:477
void get_nodes_from_face(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1411
void get_delems(typename DElem::array_type &array, typename Face::index_type idx) const
Definition: TriSurfMesh.h:439
Definition: TriSurfMesh.h:142
virtual int basis_order()
Definition: TriSurfMesh.h:319
void operator()()
Definition: TriSurfMesh.h:243
void get_edges_from_face(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1428
double length() const
Definition: Vector.h:365
virtual void end_class()
Definition: Persistent.cc:178
Face Elem
Definition: TriSurfMesh.h:151
Core::Thread::Mutex synchronize_lock_
Definition: TriSurfMesh.h:1943
void get_delems(typename DElem::array_type &array, typename Node::index_type idx) const
Definition: TriSurfMesh.h:435
long long index_type
Definition: Types.h:39
bool locate_elem(INDEX &elem, ARRAY &coords, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:1826
std::vector< Core::Geometry::Vector > normals_
Definition: TriSurfMesh.h:1935
Definition: TriSurfMesh.h:135
void get_edges(typename Edge::array_type &, typename Cell::index_type) const
Definition: TriSurfMesh.h:405
double epsilon_
Definition: TriSurfMesh.h:1954
void resize(size_t size, const value_type &val=value_type())
Definition: StackVector.h:61
void get_nodes_from_edge(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1383
mask_type synchronizing_
Definition: TriSurfMesh.h:1949
static Persistent * maker()
This function returns a maker for Pio.
Definition: TriSurfMesh.h:1303
static const std::string type_name(int n=-1)
Core functionality for getting the name of a templated mesh class.
const Core::Geometry::Point & node1() const
Definition: TriSurfMesh.h:213
void get_nodes(typename Node::array_type &array, typename Edge::index_type idx) const
Definition: TriSurfMesh.h:392
void reset()
Definition: BBox.h:95
Definition: TriSurfMesh.h:1994
Definition: Persistent.h:64
CellIndex< under_type > index_type
Definition: TriSurfMesh.h:143
std::vector< std::vector< index_type > > edge_on_node_
Definition: TriSurfMesh.h:1937
void get_center(Core::Geometry::Point &result, typename Node::index_type idx) const
get the center point (in object space) of an element
Definition: TriSurfMesh.h:467
Edge DElem
Definition: TriSurfMesh.h:152
void pwl_approx_face(std::vector< std::vector< VECTOR > > &coords, INDEX ci, unsigned int which_face, unsigned int div_per_unit) const
Definition: TriSurfMesh.h:458
void get_faces(typename Face::array_type &, typename Cell::index_type) const
Definition: TriSurfMesh.h:414
double get_size(typename Face::index_type idx) const
Definition: TriSurfMesh.h:487
Distinct type for edge index.
Definition: FieldIndex.h:81
virtual int dimensionality() const
Topological dimension.
Definition: TriSurfMesh.h:322
void get_elems(typename Elem::array_type &array, typename Node::index_type idx) const
Definition: TriSurfMesh.h:426
int n
Definition: eab.py:9
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, INDEX &face, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:1002
double scaled_jacobian_metric(INDEX idx) const
Definition: TriSurfMesh.h:683
void get_edges(typename Edge::array_type &array, typename Node::index_type idx) const
Definition: TriSurfMesh.h:399
void jacobian(const VECTOR &coords, INDEX idx, double *J) const
Definition: TriSurfMesh.h:648
bool get_elem_neighbors(ARRAY &array, INDEX1 elem, INDEX2 delem) const
Definition: TriSurfMesh.h:1556
void get_edges(typename Edge::array_type &array, typename Edge::index_type idx) const
Definition: TriSurfMesh.h:401
SCIRun::mask_type mask_type
Definition: TriSurfMesh.h:115
std::map< std::pair< index_type, index_type >, std::vector< index_type >, edgecompare > EdgeMapType2
Definition: TriSurfMesh.h:2028
EdgeIndex< under_type > index_type
Definition: TriSurfMesh.h:129
void Pio(Piostream &stream, BBox &box)
Definition: BBox.cc:134
EdgeIndex< under_type > size_type
Definition: TriSurfMesh.h:131
#define DEBUG_CONSTRUCTOR(type)
Definition: Debug.h:64
void set_point(const Core::Geometry::Point &point, typename Node::index_type index)
Definition: TriSurfMesh.h:556
void get_elems(typename Face::array_type &, typename Cell::index_type) const
Definition: TriSurfMesh.h:432
std::map< std::pair< index_type, index_type >, index_type, edgecompare > EdgeMapType
Definition: TriSurfMesh.h:2014
Synchronize(TriSurfMesh< Basis > *mesh, mask_type sync)
Definition: TriSurfMesh.h:236
void z(double)
Definition: Vector.h:195
boost::shared_ptr< MeshFacade< VMesh > > MeshFacadeHandle
Definition: MeshTraits.h:61
void elem_reserve(size_type s)
Definition: TriSurfMesh.h:601
const Core::Geometry::Point & point(typename Node::index_type i)
Definition: TriSurfMesh.h:1356
void get_faces_from_node(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1448
CellIterator< under_type > iterator
Definition: TriSurfMesh.h:144
bool find_closest_nodes(ARRAY &nodes, const Core::Geometry::Point &p, double maxdist) const
Definition: TriSurfMesh.h:870
bool locate(typename Face::index_type &loc, const Core::Geometry::Point &p) const
Definition: TriSurfMesh.h:534
NodeIterator< under_type > iterator
Definition: TriSurfMesh.h:123
void get_neighbors(typename Elem::array_type &array, typename Elem::index_type elem) const
Definition: TriSurfMesh.h:525
int size
Definition: eabLatVolData.py:2
bool locate_elems(ARRAY &array, const Core::Geometry::BBox &b) const
Definition: TriSurfMesh.h:1796
void get_node_center(Core::Geometry::Point &p, INDEX idx) const
Definition: TriSurfMesh.h:1870
void get_normal(Core::Geometry::Vector &result, typename Node::index_type index) const
Normals for visualizations.
Definition: TriSurfMesh.h:562
Core::Thread::ConditionVariable synchronize_cond_
Definition: TriSurfMesh.h:1944
#define DEBUG_DESTRUCTOR(type)
Definition: Debug.h:65
const TypeDescription * get_type_description(Core::Basis::ConstantBasis< T > *)
Definition: Constant.h:209
bool locate(typename Node::index_type &loc, const Core::Geometry::Point &p) const
Locate a point in a mesh, find which is the closest node.
Definition: TriSurfMesh.h:530
void get_nodes(typename Node::array_type &array, typename Node::index_type idx) const
Get the child elements of the given index.
Definition: TriSurfMesh.h:390
bool elem_locate(INDEX &elem, MESH &msh, const Core::Geometry::Point &p)
General case locate, search each elem.
Definition: Mesh.h:188
void get_faces_from_edge(ARRAY &array, INDEX idx) const
Definition: TriSurfMesh.h:1460
void to_index(typename Node::index_type &index, index_type i) const
Definition: TriSurfMesh.h:379