SCIRun  5.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImageMesh.h
Go to the documentation of this file.
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2009 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9 
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27 */
28 
29 #ifndef CORE_DATATYPES_IMAGEMESH_H
30 #define CORE_DATATYPES_IMAGEMESH_H 1
31 
32 /// Include what kind of support we want to have
33 /// Need to fix this and couple it to sci-defs
35 
37 
38 #include <Core/Basis/Locate.h>
40 
43 
49 
51 
52 namespace SCIRun {
53 
54 /////////////////////////////////////////////////////
55 // Declarations for virtual interface
56 
57 
58 /// Functions for creating the virtual interface
59 /// Declare the functions that instantiate the virtual interface
60 template <class Basis>
61 class ImageMesh;
62 
63 /// make sure any other mesh other than the preinstantiate ones
64 /// returns no virtual interface. Altering this behavior will allow
65 /// for dynamically compiling the interface if needed.
66 template<class MESH>
67 VMesh* CreateVImageMesh(MESH*) { return (0); }
68 
69 /// These declarations are needed for a combined dynamic compilation as
70 /// as well as virtual functions solution.
71 /// Declare that these can be found in a library that is already
72 /// precompiled. So dynamic compilation will not instantiate them again.
73 
74 #if (SCIRUN_IMAGE_SUPPORT > 0)
75 
76 SCISHARE VMesh* CreateVImageMesh(ImageMesh<Core::Basis::QuadBilinearLgn<Core::Geometry::Point> >* mesh);
77 
78 #endif
79 /////////////////////////////////////////////////////
80 
81 
82 template <class Basis>
83 class ImageMesh : public Mesh {
84 
85 /// Make sure the virtual interface has access
86 template <class MESH> friend class VImageMesh;
87 
88 public:
89 
90  // Types that change depending on 32 or 64bits
95 
96  typedef boost::shared_ptr<ImageMesh<Basis> > handle_type;
97  typedef Basis basis_type;
98  struct ImageIndex;
99  friend struct ImageIndex;
100 
101  struct ImageIndex
102  {
103  public:
104  ImageIndex() : i_(0), j_(0), mesh_(0) {}
105 
107  : i_(i), j_(j), mesh_(m) {}
108 
109  operator size_type() const {
110  ASSERT(mesh_);
111  return i_ + j_*mesh_->ni_;
112  }
113 
114  std::ostream& str_render(std::ostream& os) const {
115  os << "[" << i_ << "," << j_ << "]";
116  return os;
117  }
118 
120 
121  const ImageMesh *mesh_;
122  };
123 
124  struct IFaceIndex : public ImageIndex
125  {
128  : ImageIndex(m, i, j) {}
129 
130  operator index_type() const {
131  ASSERT(this->mesh_);
132  return this->i_ + this->j_ * (this->mesh_->ni_-1);
133  }
134  };
135 
136  struct INodeIndex : public ImageIndex
137  {
140  : ImageIndex(m, i, j) {}
141  };
142 
143  struct ImageIter : public ImageIndex
144  {
147  : ImageIndex(m, i, j) {}
148 
149  const ImageIndex &operator *() { return *this; }
150 
151  bool operator ==(const ImageIter &a) const
152  {
153  return this->i_ == a.i_ && this->j_ == a.j_ && this->mesh_ == a.mesh_;
154  }
155 
156  bool operator !=(const ImageIter &a) const
157  {
158  return !(*this == a);
159  }
160  };
161 
162  struct INodeIter : public ImageIter
163  {
166  : ImageIter(m, i, j) {}
167 
168  const INodeIndex &operator *() const { return (const INodeIndex&)(*this); }
169 
171  {
172  this->i_++;
173  if (this->i_ >= this->mesh_->min_i_ + this->mesh_->ni_) {
174  this->i_ = this->mesh_->min_i_;
175  this->j_++;
176  }
177  return *this;
178  }
179 
180  private:
181 
182  INodeIter operator++(int)
183  {
184  INodeIter result(*this);
185  operator++();
186  return result;
187  }
188  };
189 
190 
191  struct IFaceIter : public ImageIter
192  {
195  : ImageIter(m, i, j) {}
196 
197  const IFaceIndex &operator *() const { return (const IFaceIndex&)(*this); }
198 
200  {
201  this->i_++;
202  if (this->i_ >= this->mesh_->min_i_+this->mesh_->ni_-1)
203  {
204  this->i_ = this->mesh_->min_i_;
205  this->j_++;
206  }
207  return *this;
208  }
209 
210  private:
211 
212  IFaceIter operator++(int)
213  {
214  IFaceIter result(*this);
215  operator++();
216  return result;
217  }
218  };
219 
220  struct ImageSize
221  {
222  public:
223  ImageSize() : i_(0), j_(0) {}
224  ImageSize(index_type i, index_type j) : i_(i), j_(j) {}
225 
226  operator index_type() const { return i_*j_; }
227 
228  std::ostream& str_render(std::ostream& os) const
229  {
230  os << i_*j_ << " (" << i_ << " x " << j_ << ")";
231  return os;
232  }
233 
234 
236  };
237 
238  struct INodeSize : public ImageSize
239  {
242  };
243 
244 
245  struct IFaceSize : public ImageSize
246  {
249  };
250 
251 
252  /// Index and Iterator types required for Mesh Concept.
253  struct Node {
258  };
259 
260  struct Edge {
264  typedef std::vector<index_type> array_type;
265  };
266 
267  struct Face {
271  typedef std::vector<index_type> array_type;
272  };
273 
274  struct Cell {
278  typedef std::vector<index_type> array_type;
279  };
280 
281  typedef Face Elem;
282  typedef Edge DElem;
283 
284  friend struct INodeIter;
285  friend struct IFaceIter;
286  friend struct IFaceIndex;
287 
288  friend class ElemData;
289 
290  class ElemData
291  {
292  public:
294  const typename Elem::index_type ind) :
295  mesh_(msh),
296  index_(ind)
297  {}
298 
299  // the following designed to coordinate with ::get_nodes
300  inline
302  {
303  return (index_.i_ + mesh_.get_ni()*index_.j_);
304  }
305  inline
307  {
308  return (index_.i_+ 1 + mesh_.get_ni()*index_.j_);
309  }
310  inline
312  {
313  return (index_.i_ + 1 + mesh_.get_ni()*(index_.j_ + 1));
314 
315  }
316  inline
318  {
319  return (index_.i_ + mesh_.get_ni()*(index_.j_ + 1));
320  }
321 
322  // the following designed to coordinate with ::get_edges
323  inline
325  {
326  return index_.i_ + index_.j_ * (mesh_.ni_- 1);
327  }
328  inline
330  {
331  return index_.i_ + (index_.j_ + 1) * (mesh_.ni_ - 1);
332  }
333  inline
335  {
336  return index_.i_ *(mesh_.nj_ - 1) + index_.j_ +
337  ((mesh_.ni_ - 1) * mesh_.nj_);
338  }
339  inline
341  {
342  return (index_.i_ + 1) * (mesh_.nj_ - 1) + index_.j_ +
343  ((mesh_.ni_ - 1) * mesh_.nj_);
344  }
345 
346 
347  inline
349  {
350  Core::Geometry::Point p(index_.i_, index_.j_, 0.0);
351  return mesh_.transform_.project(p);
352  }
353  inline
355  {
356  Core::Geometry::Point p(index_.i_ + 1, index_.j_, 0.0);
357  return mesh_.transform_.project(p);
358  }
359  inline
361  {
362  Core::Geometry::Point p(index_.i_ + 1, index_.j_ + 1, 0.0);
363  return mesh_.transform_.project(p);
364  }
365  inline
367  {
368  Core::Geometry::Point p(index_.i_, index_.j_ + 1, 0.0);
369  return mesh_.transform_.project(p);
370  }
371 
372 
373  private:
374  const ImageMesh<Basis> &mesh_;
375  const typename Elem::index_type index_;
376  };
377 
378 
380  : min_i_(0), min_j_(0),
381  ni_(1), nj_(1)
382  {
383  DEBUG_CONSTRUCTOR("ImageMesh")
384  /// Create a new virtual interface for this copy
385  /// all pointers have changed hence create a new
386  /// virtual interface class
387  vmesh_.reset(CreateVImageMesh(this));
388  }
389 
392  size_type x, size_type y)
393  : min_i_(mx), min_j_(my), ni_(x), nj_(y), transform_(mh->transform_)
394  {
395  DEBUG_CONSTRUCTOR("ImageMesh")
397  compute_jacobian();
398 
399  /// Create a new virtual interface for this copy
400  /// all pointers have changed hence create a new
401  /// virtual interface class
402  vmesh_.reset(CreateVImageMesh(this));
403  }
404 
405  ImageMesh(const ImageMesh &copy)
406  : Mesh(copy),
407  min_i_(copy.min_i_), min_j_(copy.min_j_),
408  ni_(copy.get_ni()), nj_(copy.get_nj()), transform_(copy.transform_)
409  {
410  DEBUG_CONSTRUCTOR("ImageMesh")
412  compute_jacobian();
413 
414  /// Create a new virtual interface for this copy
415  /// all pointers have changed hence create a new
416  /// virtual interface class
417  vmesh_.reset(CreateVImageMesh(this));
418  }
419 
420  virtual ImageMesh *clone() const { return new ImageMesh(*this); }
421  virtual ~ImageMesh()
422  {
423  DEBUG_DESTRUCTOR("ImageMesh")
424  }
425 
427  {
428  return boost::make_shared<Core::Datatypes::VirtualMeshFacade<VMesh>>(vmesh_);
429  }
430 
431  /// Access point to virtual interface
432  virtual VMesh* vmesh() { return vmesh_.get(); }
433 
434  virtual int basis_order() { return (basis_.polynomial_order()); }
435 
436  virtual bool has_normals() const { return false; }
437  virtual bool has_face_normals() const { return false; }
438  virtual bool is_editable() const { return false; }
439 
440  Basis& get_basis() { return basis_; }
441 
442  /// Generate the list of points that make up a sufficiently accurate
443  /// piecewise linear approximation of an edge.
444  void pwl_approx_edge(std::vector<std::vector<double> > &coords,
445  typename Elem::index_type /*ci*/,
446  unsigned int which_edge,
447  unsigned int div_per_unit) const
448  {
449  // Needs to match unit_edges in Basis/QuadBilinearLgn.cc
450  // compare get_nodes order to the basis order
451  int basis_emap[] = {0, 2, 3, 1};
452  basis_.approx_edge(basis_emap[which_edge], div_per_unit, coords);
453  }
454 
455  /// Generate the list of points that make up a sufficiently accurate
456  /// piecewise linear approximation of an face.
457  void pwl_approx_face(std::vector<std::vector<std::vector<double> > > &coords,
458  typename Elem::index_type,
459  unsigned int,
460  unsigned int div_per_unit) const
461  {
462  basis_.approx_face(0, div_per_unit, coords);
463  }
464 
465 
466  /// Get the local coordinates for a certain point within an element
467  /// This function uses a couple of newton iterations to find the local
468  /// coordinate of a point
469  template<class VECTOR>
470  bool get_coords(VECTOR &coords, const Core::Geometry::Point &p, typename Elem::index_type idx) const
471  {
472  // If polynomial order is larger, use the complicated HO basis implementation
473  // Since this is a latvol and most probably linear, this function is to expensive
474  if (basis_.polynomial_order() > 1)
475  {
476  ElemData ed(*this, idx);
477  return basis_.get_coords(coords, p, ed);
478  }
479 
480  // Cheap implementation that assumes it is a regular grid
481  // This implementation should be faster then the interpolate of the linear
482  // basis which needs to work as well for the unstructured hexvol :(
484 
485  coords.resize(2);
486  coords[0] = static_cast<typename VECTOR::value_type>(r.x()-static_cast<double>(idx.i_));
487  coords[1] = static_cast<typename VECTOR::value_type>(r.y()-static_cast<double>(idx.j_));
488 
489  const double epsilon = 1e-8;
490 
491  if (static_cast<double>(coords[0]) < 0.0) if (static_cast<double>(coords[0]) > -(epsilon))
492  coords[0] = static_cast<typename VECTOR::value_type>(0.0); else return (false);
493  if (static_cast<double>(coords[0]) > 1.0) if (static_cast<double>(coords[0]) < 1.0+(epsilon))
494  coords[0] = static_cast<typename VECTOR::value_type>(1.0); else return (false);
495  if (static_cast<double>(coords[1]) < 0.0) if (static_cast<double>(coords[1]) > -(epsilon))
496  coords[1] = static_cast<typename VECTOR::value_type>(0.0); else return (false);
497  if (static_cast<double>(coords[1]) > 1.0) if (static_cast<double>(coords[1]) < 1.0+(epsilon))
498  coords[1] = static_cast<typename VECTOR::value_type>(1.0); else return (false);
499 
500  return (true);
501  }
502 
503  /// Find the location in the global coordinate system for a local coordinate
504  /// This function is the opposite of get_coords.
505  template<class VECTOR>
506  void interpolate(Core::Geometry::Point &pt, const VECTOR &coords, typename Elem::index_type idx) const
507  {
508  // only makes sense for higher order
509  if (basis_.polynomial_order() > 1)
510  {
511  ElemData ed(*this, idx);
512  pt = basis_.interpolate(coords, ed);
513  return;
514  }
515  // Cheaper implementation
516 
517  Core::Geometry::Point p(static_cast<double>(idx.i_)+static_cast<double>(coords[0]),
518  static_cast<double>(idx.j_)+static_cast<double>(coords[1]),
519  0.0);
520  pt = transform_.project(p);
521  }
522 
523  /// Interpolate the derivate of the function, This infact will return the
524  /// jacobian of the local to global coordinate transformation. This function
525  /// is mainly intended for the non linear elements
526  template<class VECTOR1, class VECTOR2>
527  void derivate(const VECTOR1 &coords, typename Elem::index_type idx, VECTOR2 &J) const
528  {
529  // only makes sense for higher order
530  if (basis_.polynomial_order() > 1)
531  {
532  ElemData ed(*this, idx);
533  basis_.derivate(coords, ed, J);
534  return;
535  }
536 
537  // Cheaper implementation
538  J.resize(2);
539  J[0] = (transform_.project(Core::Geometry::Point(1.0,0.0,0.0)));
540  J[1] = (transform_.project(Core::Geometry::Point(0.0,1.0,0.0)));
541  }
542 
543  /// Get the determinant of the jacobian, which is the local volume of an element
544  /// and is intended to help with the integration of functions over an element.
545  template<class VECTOR>
546  double det_jacobian(const VECTOR& coords, typename Elem::index_type idx) const
547  {
548  if (basis_.polynomial_order() > 1)
549  {
550  double J[9];
551  jacobian(coords,idx,J);
552  return (DetMatrix3x3(J));
553  }
554 
555  return (det_jacobian_);
556  }
557 
558  /// Get the jacobian of the transformation. In case one wants the non inverted
559  /// version of this matrix. This is currentl here for completeness of the
560  /// interface
561  template<class VECTOR>
562  void jacobian(const VECTOR& coords, typename Elem::index_type idx, double* J) const
563  {
564  if (basis_.polynomial_order() > 1)
565  {
567  ElemData ed(*this,idx);
568  basis_.derivate(coords,ed,Jv);
570  Jv2.normalize();
571  J[0] = Jv[0].x();
572  J[1] = Jv[0].y();
573  J[2] = Jv[0].z();
574  J[3] = Jv[1].x();
575  J[4] = Jv[1].y();
576  J[5] = Jv[1].z();
577  J[6] = Jv2.x();
578  J[7] = Jv2.y();
579  J[8] = Jv2.z();
580 
581  return;
582  }
583 
584  J[0] = jacobian_[0];
585  J[1] = jacobian_[1];
586  J[2] = jacobian_[2];
587  J[3] = jacobian_[3];
588  J[4] = jacobian_[4];
589  J[5] = jacobian_[5];
590  J[6] = jacobian_[6];
591  J[7] = jacobian_[7];
592  J[8] = jacobian_[8];
593  }
594 
595  /// Get the inverse jacobian of the transformation. This one is needed to
596  /// translate local gradients into global gradients. Hence it is crucial for
597  /// calculating gradients of fields, or constructing finite elements.
598  template<class VECTOR>
599  double inverse_jacobian(const VECTOR& coords, typename Elem::index_type idx, double* Ji) const
600  {
601  if (basis_.polynomial_order() > 1)
602  {
604  ElemData ed(*this,idx);
605  basis_.derivate(coords,ed,Jv);
606  double J[9];
608  Jv2.normalize();
609  J[0] = Jv[0].x();
610  J[1] = Jv[0].y();
611  J[2] = Jv[0].z();
612  J[3] = Jv[1].x();
613  J[4] = Jv[1].y();
614  J[5] = Jv[1].z();
615  J[6] = Jv2.x();
616  J[7] = Jv2.y();
617  J[8] = Jv2.z();
618 
619  return (InverseMatrix3x3(J,Ji));
620  }
621 
622  Ji[0] = inverse_jacobian_[0];
623  Ji[1] = inverse_jacobian_[1];
624  Ji[2] = inverse_jacobian_[2];
625  Ji[3] = inverse_jacobian_[3];
626  Ji[4] = inverse_jacobian_[4];
627  Ji[5] = inverse_jacobian_[5];
628  Ji[6] = inverse_jacobian_[6];
629  Ji[7] = inverse_jacobian_[7];
630  Ji[8] = inverse_jacobian_[8];
631 
632  return (det_inverse_jacobian_);
633  }
634 
635 
636  double scaled_jacobian_metric(typename Elem::index_type /*idx*/) const
637  { return (scaled_jacobian_); }
638 
639  double jacobian_metric(typename Elem::index_type /*idx*/) const
640  { return (det_jacobian_); }
641 
642 
643 
644  /// get the mesh statistics
645  size_type get_min_i() const { return min_i_; }
646  size_type get_min_j() const { return min_j_; }
647  bool get_min(std::vector<index_type>&) const;
648  size_type get_ni() const { return ni_; }
649  size_type get_nj() const { return nj_; }
650  virtual bool get_dim(std::vector<size_type>&) const;
652  virtual Core::Geometry::BBox get_bounding_box() const;
653  virtual void transform(const Core::Geometry::Transform &t);
655  virtual bool synchronize(mask_type sync);
656  virtual bool unsynchronize(mask_type sync);
657  bool clear_synchronization();
658 
659  /// set the mesh statistics
660  void set_min_i(index_type i) {min_i_ = i; }
661  void set_min_j(index_type j) {min_j_ = j; }
662  void set_min(std::vector<index_type> mins);
664  {
665  ni_ = i;
666 
667  /// Create a new virtual interface for this copy
668  /// all pointers have changed hence create a new
669  /// virtual interface class
670  vmesh_.reset(CreateVImageMesh(this));
671  }
673  {
674  nj_ = j;
675 
676  /// Create a new virtual interface for this copy
677  /// all pointers have changed hence create a new
678  /// virtual interface class
679  vmesh_.reset(CreateVImageMesh(this));
680  }
681 
682  virtual void set_dim(std::vector<size_type> dims);
683 
684  void begin(typename Node::iterator &) const;
685  void begin(typename Edge::iterator &) const;
686  void begin(typename Face::iterator &) const;
687  void begin(typename Cell::iterator &) const;
688 
689  void end(typename Node::iterator &) const;
690  void end(typename Edge::iterator &) const;
691  void end(typename Face::iterator &) const;
692  void end(typename Cell::iterator &) const;
693 
694  void size(typename Node::size_type &) const;
695  void size(typename Edge::size_type &) const;
696  void size(typename Face::size_type &) const;
697  void size(typename Cell::size_type &) const;
698 
699  void to_index(typename Node::index_type &index, index_type i) const;
700  void to_index(typename Edge::index_type &index, index_type i) const { index= i; }
701  void to_index(typename Face::index_type &index, index_type i) const;
702  void to_index(typename Cell::index_type &, index_type) const
703  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
704 
705 
706  /// get the child elements of the given index
707  void get_nodes(typename Node::array_type &, typename Edge::index_type) const;
708  void get_nodes(typename Node::array_type &, typename Face::index_type) const;
709  void get_nodes(typename Node::array_type &, typename Cell::index_type) const
710  { ASSERTFAIL("This mesh type does not have cells use \"elem\".");}
711  void get_edges(typename Edge::array_type &, typename Face::index_type) const;
712  void get_edges(typename Edge::array_type &, typename Cell::index_type) const
713  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
714  void get_faces(typename Face::array_type &, typename Cell::index_type) const
715  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
716  void get_faces(typename Face::array_type &a,typename Face::index_type f) const
717  { a.push_back(f); }
718 
719  /// get the parent element(s) of the given index
720  void get_elems(typename Elem::array_type &result,
721  typename Node::index_type idx) const;
722  void get_elems(typename Elem::array_type &result,
723  typename Edge::index_type idx) const;
724  void get_elems(typename Elem::array_type&,
725  typename Face::index_type) const {}
726 
727 
728  /// Wrapper to get the derivative elements from this element.
729  void get_delems(typename DElem::array_type &result,
730  const typename Elem::index_type &idx) const
731  {
732  get_edges(result, idx);
733  }
734 
735  /// return all face_indecies that overlap the BBox in arr.
736  void get_faces(typename Face::array_type &arr, const Core::Geometry::BBox &box);
737 
738  /// Get the size of an element (length, area, volume)
739  double get_size(const typename Node::index_type &/*i*/) const { return 0.0; }
740  double get_size(typename Edge::index_type idx) const
741  {
742  typename Node::array_type arr;
743  get_nodes(arr, idx);
744  Core::Geometry::Point p0, p1;
745  get_center(p0, arr[0]);
746  get_center(p1, arr[1]);
747  return (p1 - p0).length();
748  }
749  double get_size(const typename Face::index_type &idx) const
750  {
751  typename Node::array_type ra;
752  get_nodes(ra,idx);
753  Core::Geometry::Point p0,p1,p2;
754  get_point(p0,ra[0]);
755  get_point(p1,ra[1]);
756  get_point(p2,ra[2]);
757  return (Cross(p0-p1,p2-p0)).length();
758  }
759  double get_size(typename Cell::index_type /*idx*/) const
760  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
761 
762  double get_length(typename Edge::index_type idx) const { return get_size(idx); };
763  double get_area(typename Face::index_type idx) const { return get_size(idx); };
764  double get_volume(typename Cell::index_type /*idx*/) const
765  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); };
766 
767 
768  bool get_neighbor(typename Face::index_type &neighbor,
769  typename Face::index_type from,
770  typename Edge::index_type idx) const;
771 
772  void get_neighbors(typename Face::array_type &array, typename Face::index_type idx) const;
773 
774  void get_normal(Core::Geometry::Vector&, const typename Node::index_type&) const
775  { ASSERTFAIL("This mesh type does not have node normals."); }
776  void get_normal(Core::Geometry::Vector &result, std::vector<double> &coords,
777  typename Elem::index_type eidx, index_type)
778  {
779  ElemData ed(*this, eidx);
780  std::vector<Core::Geometry::Point> Jv;
781  basis_.derivate(coords, ed, Jv);
782  result = Cross(Core::Geometry::Vector(Jv[0]), Core::Geometry::Vector(Jv[1]));
783  result.normalize();
784  }
785 
786  /// get the center point (in object space) of an element
787  void get_center(Core::Geometry::Point &, const typename Node::index_type &) const;
788  void get_center(Core::Geometry::Point &, typename Edge::index_type) const;
789  void get_center(Core::Geometry::Point &, const typename Face::index_type &) const;
791  ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
792 
793  bool locate(typename Node::index_type &, const Core::Geometry::Point &) const;
794  bool locate(typename Edge::index_type &, const Core::Geometry::Point &) const {return false;}
795  bool locate(typename Face::index_type &, const Core::Geometry::Point &) const;
796  bool locate(typename Cell::index_type &, const Core::Geometry::Point &) const {
797  ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
798 
799  int get_weights(const Core::Geometry::Point &p, typename Node::array_type &l, double *w);
800  int get_weights(const Core::Geometry::Point & , typename Edge::array_type & , double * )
801  { ASSERTFAIL("ImageMesh::get_weights for edges isn't supported"); }
802  int get_weights(const Core::Geometry::Point &p, typename Face::array_type &l, double *w);
803  int get_weights(const Core::Geometry::Point & , typename Cell::array_type & , double * )
804  { ASSERTFAIL("This mesh type does not have cells use \"elem\"."); }
805 
806  void get_point(Core::Geometry::Point &p, const typename Node::index_type &i) const
807  { get_center(p, i); }
808 
809  void get_random_point(Core::Geometry::Point &, const typename Elem::index_type &, FieldRNG &rng) const;
810 
811 
812  /// Export this class using the old Pio system
813  virtual void io(Piostream&);
814  /// These IDs are created as soon as this class will be instantiated
815  /// The first one is for Pio and the second for the virtual interface
816  /// These are currently different as they serve different needs. static PersistentTypeID type_idts;
818  /// Core functionality for getting the name of a templated mesh class
819  static const std::string type_name(int n = -1);
820  virtual std::string dynamic_type_name() const { return imagemesh_typeid.type; }
821 
822  // Unsafe due to non-constness of unproject.
826 
827  virtual int dimensionality() const { return 2; }
828  virtual int topology_geometry() const { return (STRUCTURED | REGULAR); }
829 
830  /// Type description, used for finding names of the mesh class for
831  /// dynamic compilation purposes. Some of this should be obsolete
832  virtual const TypeDescription *get_type_description() const;
833  static const TypeDescription* node_type_description();
834  static const TypeDescription* edge_type_description();
835  static const TypeDescription* face_type_description();
836  static const TypeDescription* cell_type_description();
838  { return face_type_description(); }
841 
842  /// This function returns a maker for Pio.
843  static Persistent *maker() { return new ImageMesh<Basis>(); }
844  /// This function returns a handle for the virtual interface.
845  static MeshHandle mesh_maker() { return boost::make_shared<ImageMesh<Basis>>();}
846  /// This function returns a handle for the virtual interface.
848  { return boost::make_shared<ImageMesh<Basis>>(x,y,min,max); }
849 
850  /// This function will find the closest element and the location on that
851  /// element that is the closest
852  bool find_closest_node(double& pdist,Core::Geometry::Point &result,
853  typename Node::index_type &elem,
854  const Core::Geometry::Point &p) const;
855 
856  bool find_closest_node(double& pdist,Core::Geometry::Point &result,
857  typename Node::index_type &elem,
858  const Core::Geometry::Point &p, double maxdist) const;
859 
860  /// This function will find the closest element and the location on that
861  /// element that is the closest
862  template <class ARRAY>
863  bool find_closest_elem(double& pdist,
864  Core::Geometry::Point &result,
865  ARRAY& coords,
866  typename Elem::index_type &elem,
867  const Core::Geometry::Point &p,
868  double maxdist) const
869  {
870  bool ret = find_closest_elem(pdist,result,coords,elem,p);
871  if(!ret) return (false);
872  if (maxdist < 0.0 || pdist < maxdist) return (true);
873  return (false);
874  }
875 
876  /// This function will find the closest element and the location on that
877  /// element that is the closest
878  bool find_closest_elem(double& pdist,
879  Core::Geometry::Point &result,
880  typename Elem::index_type &elem,
881  const Core::Geometry::Point &p) const
882  {
883  StackVector<double,2> coords;
884  return(find_closest_elem(pdist,result,coords,elem,p));
885  }
886 
887  template<class ARRAY>
888  bool find_closest_elem(double& pdist,
889  Core::Geometry::Point& result,
890  ARRAY& coords,
891  typename Elem::index_type &elem,
892  const Core::Geometry::Point &p) const
893  {
894  if (ni_ == 0 || nj_ == 0) return (false);
895 
897 
898  double ii = r.x();
899  double jj = r.y();
900  const double nii = static_cast<double>(ni_-2);
901  const double njj = static_cast<double>(nj_-2);
902 
903  if (ii < 0.0) ii = 0.0; if (ii > nii) ii = nii;
904  if (jj < 0.0) jj = 0.0; if (jj > njj) jj = njj;
905 
906  const double fi = floor(ii);
907  const double fj = floor(jj);
908 
909  elem.i_ = static_cast<index_type>(fi);
910  elem.j_ = static_cast<index_type>(fj);
911  elem.mesh_ = this;
912 
913  result = transform_.project(Core::Geometry::Point(ii,jj,0));
914  pdist = (p-result).length();
915 
916  coords.resize(2);
917  coords[0] = ii-fi;
918  coords[1] = jj-fj;
919 
920  return (true);
921  }
922 
923 
924  /// This function will return multiple elements if the closest point is
925  /// located on a node or edge. All bordering elements are returned in that
926  /// case.
927  bool find_closest_elems(double& pdist, Core::Geometry::Point &result,
928  std::vector<typename Elem::index_type> &elem,
929  const Core::Geometry::Point &p) const;
930 
931  double get_epsilon() const;
932 
933 protected:
934 
935  void compute_jacobian();
936 
937  /// the min_typename Node::index_type ( incase this is a subLattice )
940  /// the typename Node::index_type space extents of a ImageMesh
941  /// (min=min_typename Node::index_type, max=min+extents-1)
944 
945  /// the object space extents of a ImageMesh
947 
949 
950  /// The basis class
951  Basis basis_;
952 
953  /// Virtual mesh
954  boost::shared_ptr<VMesh> vmesh_;
955  // The jacobian is the same for every element
956  // hence store them as soon as we know the transfrom_
957  // This should speed up FE computations on these regular grids.
958  double jacobian_[9];
959  double inverse_jacobian_[9];
963 };
964 
965 
966 template <class Basis>
968 ImageMesh<Basis>::imagemesh_typeid(type_name(-1),"Mesh", maker);
969 
970 
971 template<class Basis>
973  const Core::Geometry::Point &min, const Core::Geometry::Point &max) :
974  min_i_(0), min_j_(0), ni_(i), nj_(j)
975 {
976  DEBUG_CONSTRUCTOR("ImageMesh")
977  transform_.pre_scale(Core::Geometry::Vector(1.0 / (i-1.0), 1.0 / (j-1.0), 1.0));
978 
979  Core::Geometry::Vector scale = max - min;
980  scale[2] = 1.0;
981 
982  transform_.pre_scale(scale);
985 
986  normal_ = Core::Geometry::Vector(0.0, 0.0, 0.0);
989 
991 
992  /// Create a new virtual interface for this copy
993  /// all pointers have changed hence create a new
994  /// virtual interface class
995  vmesh_.reset(CreateVImageMesh(this));
996 }
997 
998 
999 template<class Basis>
1000 double
1002 {
1003  Core::Geometry::Point p0(static_cast<double>(ni_-1),static_cast<double>(nj_-1),0.0);
1004  Core::Geometry::Point p1(0.0,0.0,0.0);
1005  Core::Geometry::Point q0 = transform_.project(p0);
1006  Core::Geometry::Point q1 = transform_.project(p1);
1007  return ((q0-q1).length()*1e-8);
1008 }
1009 
1010 template<class Basis>
1013 {
1014  Core::Geometry::Point p0(0.0, 0.0, 0.0);
1015  Core::Geometry::Point p1(ni_-1, 0.0, 0.0);
1016  Core::Geometry::Point p2(ni_-1, nj_-1, 0.0);
1017  Core::Geometry::Point p3(0.0, nj_-1, 0.0);
1018 
1019  Core::Geometry::BBox result;
1020  result.extend(transform_.project(p0));
1021  result.extend(transform_.project(p1));
1022  result.extend(transform_.project(p2));
1023  result.extend(transform_.project(p3));
1024  return result;
1025 }
1026 
1027 
1028 template<class Basis>
1031 {
1032  return get_bounding_box().diagonal();
1033 }
1034 
1035 
1036 template<class Basis>
1037 void
1039 {
1040  t = transform_;
1041  t.post_scale(Core::Geometry::Vector(ni_ - 1.0, nj_ - 1.0, 1.0));
1042 }
1043 
1044 
1045 template<class Basis>
1046 bool
1048 {
1049  if (sync & Mesh::NORMALS_E)
1050  {
1051  normal_ = Core::Geometry::Vector(0.0, 0.0, 0.0);
1052  transform_.project_normal(normal_);
1053  normal_.safe_normalize();
1054  return true;
1055  }
1056  return false;
1057 }
1058 
1059 template<class Basis>
1060 bool
1062 {
1063  return (true);
1064 }
1065 
1066 template<class Basis>
1067 bool
1069 {
1070  return (true);
1071 }
1072 
1073 template<class Basis>
1074 void
1076 {
1077  transform_.pre_trans(t);
1078  transform_.compute_imat();
1079  compute_jacobian();
1080 }
1081 
1082 
1083 template<class Basis>
1084 bool
1085 ImageMesh<Basis>::get_min(std::vector<index_type> &array) const
1086 {
1087  array.resize(2);
1088  array.clear();
1089 
1090  array.push_back(min_i_);
1091  array.push_back(min_j_);
1092 
1093  return true;
1094 }
1095 
1096 
1097 template<class Basis>
1098 bool
1099 ImageMesh<Basis>::get_dim(std::vector<size_type> &array) const
1100 {
1101  array.resize(2);
1102  array.clear();
1103 
1104  array.push_back(ni_);
1105  array.push_back(nj_);
1106 
1107  return true;
1108 }
1109 
1110 
1111 template<class Basis>
1112 void
1113 ImageMesh<Basis>::set_min(std::vector<index_type> min)
1114 {
1115  min_i_ = min[0];
1116  min_j_ = min[1];
1117 }
1118 
1119 
1120 template<class Basis>
1121 void
1122 ImageMesh<Basis>::set_dim(std::vector<size_type> dim)
1123 {
1124  ni_ = dim[0];
1125  nj_ = dim[1];
1126 
1127  /// Create a new virtual interface for this copy
1128  /// all pointers have changed hence create a new
1129  /// virtual interface class
1130  vmesh_.reset(CreateVImageMesh(this));
1131 }
1132 
1133 
1134 template<class Basis>
1135 void
1137  typename Face::index_type idx) const
1138 {
1139  array.resize(4);
1140 
1141  array[0].i_ = idx.i_; array[0].j_ = idx.j_;
1142  array[1].i_ = idx.i_+1; array[1].j_ = idx.j_;
1143  array[2].i_ = idx.i_+1; array[2].j_ = idx.j_+1;
1144  array[3].i_ = idx.i_; array[3].j_ = idx.j_+1;
1145 
1146  array[0].mesh_ = idx.mesh_;
1147  array[1].mesh_ = idx.mesh_;
1148  array[2].mesh_ = idx.mesh_;
1149  array[3].mesh_ = idx.mesh_;
1150 }
1151 
1152 
1153 template<class Basis>
1154 void
1156  typename Edge::index_type idx) const
1157 {
1158  array.resize(2);
1159 
1160  const index_type j_idx = idx - (ni_-1) * nj_;
1161  if (j_idx >= 0)
1162  {
1163  const index_type i = j_idx / (nj_ - 1);
1164  const index_type j = j_idx % (nj_ - 1);
1165  array[0] = typename Node::index_type(this, i, j);
1166  array[1] = typename Node::index_type(this, i, j+1);
1167  }
1168  else
1169  {
1170  const index_type i = idx % (ni_ - 1);
1171  const index_type j = idx / (ni_ - 1);
1172  array[0] = typename Node::index_type(this, i, j);
1173  array[1] = typename Node::index_type(this, i+1, j);
1174  }
1175 }
1176 
1177 
1178 template<class Basis>
1179 void
1181  typename Face::index_type idx) const
1182 {
1183  array.resize(4);
1184 
1185  const index_type j_idx = (ni_-1) * nj_;
1186 
1187  array[0] = idx.i_ + idx.j_ *(ni_-1);
1188  array[1] = idx.i_ + (idx.j_+1)*(ni_-1);
1189  array[2] = idx.i_ *(nj_-1) + idx.j_+ j_idx;
1190  array[3] = (idx.i_+1)*(nj_-1) + idx.j_+ j_idx;
1191 }
1192 
1193 template<class Basis>
1194 void
1196  typename Edge::index_type idx) const
1197 {
1198  array.reserve(2);
1199  array.clear();
1200 
1201  const index_type offset = (ni_-1)*nj_;
1202 
1203  if (idx < offset)
1204  {
1205  const index_type j = idx/(ni_-1);
1206  const index_type i = idx - j*(ni_-1);
1207  if (j < (nj_-1)) array.push_back(IFaceIndex(this,i,j));
1208  if (j > 0) array.push_back(IFaceIndex(this,i,j-1));
1209  }
1210  else
1211  {
1212  idx = idx - offset;
1213  const index_type i = idx/(nj_-1);
1214  const index_type j = idx - i*(nj_-1);
1215  if (i < (ni_-1)) array.push_back(IFaceIndex(this,i,j));
1216  if (i > 0) array.push_back(IFaceIndex(this,i-1,j));
1217  }
1218 }
1219 
1220 
1221 
1222 
1223 template<class Basis>
1224 bool
1226  typename Face::index_type from,
1227  typename Edge::index_type edge) const
1228 {
1229  neighbor.mesh_ = this;
1230  const index_type j_idx = edge - (ni_-1) * nj_;
1231  if (j_idx >= 0)
1232  {
1233  const index_type i = j_idx / (nj_ - 1);
1234  if (i == 0 || i == ni_-1)
1235  return false;
1236  neighbor.j_ = from.j_;
1237  if (i == from.i_)
1238  neighbor.i_ = from.i_ - 1;
1239  else
1240  neighbor.i_ = from.i_ + 1;
1241  }
1242  else
1243  {
1244  const index_type j = edge / (ni_ - 1);;
1245  if (j == 0 || j == nj_-1)
1246  return false;
1247  neighbor.i_ = from.i_;
1248  if (j == from.j_)
1249  neighbor.j_ = from.j_ - 1;
1250  else
1251  neighbor.j_ = from.j_ + 1;
1252  }
1253  return true;
1254 }
1255 
1256 
1257 template<class Basis>
1258 void
1260  typename Face::index_type idx) const
1261 {
1262  typename Edge::array_type edges;
1263  get_edges(edges, idx);
1264  array.clear();
1265  typename Edge::array_type::iterator iter = edges.begin();
1266  while(iter != edges.end()) {
1267  typename Face::index_type nbor;
1268  if (get_neighbor(nbor, idx, *iter)) {
1269  array.push_back(nbor);
1270  }
1271  ++iter;
1272  }
1273 }
1274 
1275 
1276 template<class Basis>
1277 void
1279  const typename Node::index_type idx) const
1280 {
1281  result.reserve(4);
1282  result.clear();
1283 
1284  const index_type i0 = idx.i_ ? idx.i_ - 1 : 0;
1285  const index_type j0 = idx.j_ ? idx.j_ - 1 : 0;
1286 
1287  const index_type i1 = idx.i_ < ni_-1 ? idx.i_+1 : ni_-1;
1288  const index_type j1 = idx.j_ < nj_-1 ? idx.j_+1 : nj_-1;
1289 
1290  index_type i, j;
1291  for (j = j0; j < j1; j++)
1292  for (i = i0; i < i1; i++)
1293  result.push_back(typename Face::index_type(this, i, j));
1294 }
1295 
1296 
1297 /// return all face_indecies that overlap the Core::Geometry::BBox in arr.
1298 template<class Basis>
1299 void
1301 {
1302  arr.clear();
1303  typename Face::index_type min;
1304  locate(min, bbox.min());
1305  typename Face::index_type max;
1306  locate(max, bbox.max());
1307 
1308  if (max.i_ >= ni_ - 1) max.i_ = ni_ - 2;
1309  if (max.j_ >= nj_ - 1) max.j_ = nj_ - 2;
1310 
1311  for (index_type i = min.i_; i <= max.i_; i++)
1312  {
1313  for (index_type j = min.j_; j <= max.j_; j++)
1314  {
1315  arr.push_back(typename Face::index_type(this, i,j));
1316  }
1317  }
1318 }
1319 
1320 
1321 template<class Basis>
1322 void
1324  const typename Node::index_type &idx) const
1325 {
1326  Core::Geometry::Point p(idx.i_, idx.j_, 0.0);
1327  result = transform_.project(p);
1328 }
1329 
1330 
1331 template<class Basis>
1332 void
1334  typename Edge::index_type idx) const
1335 {
1336  typename Node::array_type arr;
1337  get_nodes(arr, idx);
1339  get_center(result, arr[0]);
1340  get_center(p1, arr[1]);
1341 
1342  result += p1;
1343  result *= 0.5;
1344 }
1345 
1346 
1347 template<class Basis>
1348 void
1350  const typename Face::index_type &idx) const
1351 {
1352  Core::Geometry::Point p(idx.i_ + 0.5, idx.j_ + 0.5, 0.0);
1353  result = transform_.project(p);
1354 }
1355 
1356 template <class Basis>
1357 int
1359  double *w)
1360 {
1361  typename Face::index_type idx;
1362  if (locate(idx, p))
1363  {
1364  get_nodes(l,idx);
1365  std::vector<double> coords(2);
1366  if (get_coords(coords, p, idx))
1367  {
1368  basis_.get_weights(coords, w);
1369  return basis_.dofs();
1370  }
1371  }
1372  return 0;
1373 }
1374 
1375 
1376 template <class Basis>
1377 int
1378 ImageMesh<Basis>::get_weights(const Core::Geometry::Point &p, typename Face::array_type &l,
1379  double *w)
1380 {
1381  typename Face::index_type idx;
1382  if (locate(idx, p))
1383  {
1384  l.resize(1);
1385  l[0] = idx;
1386  w[0] = 1.0;
1387  return 1;
1388  }
1389  return 0;
1390 }
1391 
1392 
1393 /* To generate a random point inside of a triangle, we generate random
1394  barrycentric coordinates (independent random variables between 0 and
1395  1 that sum to 1) for the point. */
1396 
1397 template<class Basis>
1398 void
1400  const typename Elem::index_type &ci,
1401  FieldRNG &rng) const
1402 {
1403  // Get the positions of the vertices.
1404  typename Node::array_type ra;
1405  get_nodes(ra,ci);
1406  Core::Geometry::Point p00, p10, p11, p01;
1407  get_center(p00,ra[0]);
1408  get_center(p10,ra[1]);
1409  get_center(p11,ra[2]);
1410  get_center(p01,ra[3]);
1411  Core::Geometry::Vector dx=p10-p00;
1412  Core::Geometry::Vector dy=p01-p00;
1413 
1414  // Generate the barycentric coordinates.
1415  const double u = rng();
1416  const double v = rng();
1417 
1418  // Compute the position of the random point.
1419  p = p00 + dx*u + dy*v;
1420 }
1421 
1422 
1423 template<class Basis>
1424 const TypeDescription*
1426 {
1427  static TypeDescription* td = 0;
1428  if(!td){
1430  std::string("::INodeIndex"),
1431  std::string(__FILE__),
1432  "SCIRun");
1433  }
1434  return td;
1435 }
1436 
1437 
1438 template<class Basis>
1439 const TypeDescription*
1441 {
1442  static TypeDescription* td = 0;
1443  if(!td){
1445  std::string("::IFaceIndex"),
1446  std::string(__FILE__),
1447  "SCIRun");
1448  }
1449  return td;
1450 }
1451 
1452 
1453 template<class Basis>
1454 void
1456 {
1457  stream.begin_cheap_delim();
1458  Pio(stream, n.i_);
1459  Pio(stream, n.j_);
1460  stream.end_cheap_delim();
1461 }
1462 
1463 
1464 template<class Basis>
1465 void
1467 {
1468  stream.begin_cheap_delim();
1469  Pio(stream, n.i_);
1470  Pio(stream, n.j_);
1471  stream.end_cheap_delim();
1472 }
1473 
1474 
1475 #define IMAGEMESH_VERSION 4
1476 
1477 template<class Basis>
1478 void
1480 {
1481  int version = stream.begin_class(type_name(-1), IMAGEMESH_VERSION);
1482 
1483  Mesh::io(stream);
1484 
1485  // IO data members, in order
1486  if (version < 4)
1487  {
1488  unsigned int ni = static_cast<unsigned int>(ni_);
1489  unsigned int nj = static_cast<unsigned int>(nj_);
1490  Pio(stream, ni);
1491  Pio(stream, nj);
1492  ni_ = static_cast<size_type>(ni);
1493  nj_ = static_cast<size_type>(nj);
1494  }
1495  else
1496  {
1497  Pio_size(stream, ni_);
1498  Pio_size(stream, nj_);
1499  }
1500 
1501  if (version >= 2) {
1502  basis_.io(stream);
1503  }
1504 
1505  if (version >= 3) {
1506  Pio(stream, transform_);
1507  }
1508 
1509  stream.end_class();
1510 
1511  if (stream.reading())
1512  {
1513  compute_jacobian();
1514  vmesh_.reset(CreateVImageMesh(this));
1515  }
1516 }
1517 
1518 
1519 template<class Basis>
1520 const std::string
1522 {
1523  ASSERT((n >= -1) && n <= 1);
1524  if (n == -1)
1525  {
1526  static const std::string name = TypeNameGenerator::make_template_id(type_name(0), type_name(1));
1527  return name;
1528  }
1529  else if (n == 0)
1530  {
1531  static const std::string nm("ImageMesh");
1532  return nm;
1533  }
1534  else
1535  {
1536  return find_type_name((Basis *)0);
1537  }
1538 }
1539 
1540 
1541 template<class Basis>
1542 void
1544 {
1545  itr = typename Node::iterator(this, min_i_, min_j_);
1546 }
1547 
1548 
1549 template<class Basis>
1550 void
1552 {
1553  itr = typename Node::iterator(this, min_i_, min_j_ + nj_);
1554 }
1555 
1556 
1557 template<class Basis>
1558 void
1560 {
1561  s = typename Node::size_type(ni_, nj_);
1562 }
1563 
1564 
1565 template<class Basis>
1566 void
1568 {
1569  const index_type i = a % ni_;
1570  const index_type j = a / ni_;
1571  idx = typename Node::index_type(this, i, j);
1572 
1573 }
1574 
1575 
1576 template<class Basis>
1577 void
1579 {
1580  itr = 0;
1581 }
1582 
1583 
1584 template<class Basis>
1585 void
1587 {
1588  itr = (ni_-1) * (nj_) + (ni_) * (nj_ -1);
1589 }
1590 
1591 
1592 template<class Basis>
1593 void
1595 {
1596  s = (ni_-1) * (nj_) + (ni_) * (nj_ -1);
1597 }
1598 
1599 
1600 template<class Basis>
1601 void
1603 {
1604  itr = typename Face::iterator(this, min_i_, min_j_);
1605 }
1606 
1607 
1608 template<class Basis>
1609 void
1611 {
1612  itr = typename Face::iterator(this, min_i_, min_j_ + nj_ - 1);
1613 }
1614 
1615 
1616 template<class Basis>
1617 void
1619 {
1620  s = typename Face::size_type(ni_-1, nj_-1);
1621 }
1622 
1623 
1624 template<class Basis>
1625 void
1627  index_type a) const
1628 {
1629  const index_type i = a % (ni_-1);
1630  const index_type j = a / (ni_-1);
1631  idx = typename Face::index_type(this, i, j);
1632 
1633 }
1634 
1635 
1636 template<class Basis>
1637 void
1639 {
1640  ASSERTFAIL("This mesh type does not have cells use \"elem\".");
1641 }
1642 
1643 
1644 template<class Basis>
1645 void
1647 {
1648  ASSERTFAIL("This mesh type does not have cells use \"elem\".");
1649 }
1650 
1651 
1652 template<class Basis>
1653 void
1655 {
1656  ASSERTFAIL("This mesh type does not have cells use \"elem\".");
1657 }
1658 
1659 
1660 template<class Basis>
1661 const TypeDescription*
1663 {
1664  static TypeDescription *td = 0;
1665  if (!td)
1666  {
1667  const TypeDescription *sub = get_type_description((Basis*)0);
1669  (*subs)[0] = sub;
1670  td = new TypeDescription("ImageMesh", subs,
1671  std::string(__FILE__),
1672  "SCIRun",
1674  }
1675  return td;
1676 }
1677 
1678 
1679 template<class Basis>
1680 const TypeDescription*
1682 {
1684 }
1685 
1686 
1687 template<class Basis>
1688 const TypeDescription*
1690 {
1691  static TypeDescription *td = 0;
1692  if (!td)
1693  {
1694  const TypeDescription *me =
1696  td = new TypeDescription(me->get_name() + "::Node",
1697  std::string(__FILE__),
1698  "SCIRun",
1700  }
1701  return td;
1702 }
1703 
1704 
1705 template<class Basis>
1706 const TypeDescription*
1708 {
1709  static TypeDescription *td = 0;
1710  if (!td)
1711  {
1712  const TypeDescription *me =
1714  td = new TypeDescription(me->get_name() + "::Edge",
1715  std::string(__FILE__),
1716  "SCIRun",
1718  }
1719  return td;
1720 }
1721 
1722 
1723 template<class Basis>
1724 const TypeDescription*
1726 {
1727  static TypeDescription *td = 0;
1728  if (!td)
1729  {
1730  const TypeDescription *me =
1732  td = new TypeDescription(me->get_name() + "::Face",
1733  std::string(__FILE__),
1734  "SCIRun",
1736  }
1737  return td;
1738 }
1739 
1740 
1741 template<class Basis>
1742 const TypeDescription*
1744 {
1745  static TypeDescription *td = 0;
1746  if (!td)
1747  {
1748  const TypeDescription *me =
1750  td = new TypeDescription(me->get_name() + "::Cell",
1751  std::string(__FILE__),
1752  "SCIRun",
1754  }
1755  return td;
1756 }
1757 
1758 
1759 template<class Basis>
1760 bool
1762 {
1763  if (basis_.polynomial_order() > 1) return elem_locate(elem, *this, p);
1764 
1765  if (ni_ == 0 || nj_ == 0) return (false);
1766 
1767  const double epsilon = 1e-7;
1768 
1769  const Core::Geometry::Point r = transform_.unproject(p);
1770 
1771  double ii = r.x();
1772  double jj = r.y();
1773 
1774  const double nii = static_cast<double>(ni_-1);
1775  const double njj = static_cast<double>(nj_-1);
1776 
1777  if (ii>=nii && (ii-epsilon)<nii) ii=nii-epsilon;
1778  if (jj>=njj && (jj-epsilon)<njj) jj=njj-epsilon;
1779 
1780  if (ii<0 && ii>(-epsilon)) ii=0.0;
1781  if (jj<0 && jj>(-epsilon)) jj=0.0;
1782 
1783  const index_type i = static_cast<index_type>(floor(ii));
1784  const index_type j = static_cast<index_type>(floor(jj));
1785 
1786  if (i < (ni_-1) && i >= 0 &&
1787  j < (nj_-1) && j >= 0 &&
1788  ii >= 0.0 && jj >= 0.0)
1789  {
1790  elem.i_ = i;
1791  elem.j_ = j;
1792  elem.mesh_ = this;
1793  return (true);
1794  }
1795 
1796  return (false);
1797 }
1798 
1799 
1800 template<class Basis>
1801 bool
1803 {
1804  if (ni_ == 0 || nj_ == 0) return (false);
1805 
1806  const Core::Geometry::Point r = transform_.unproject(p);
1807 
1808  double rx = floor(r.x() + 0.5);
1809  double ry = floor(r.y() + 0.5);
1810  const double nii = static_cast<double>(ni_-1);
1811  const double njj = static_cast<double>(nj_-1);
1812 
1813  if (rx < 0.0) rx = 0.0; if (rx > nii) rx = nii;
1814  if (ry < 0.0) ry = 0.0; if (ry > njj) ry = njj;
1815 
1816  node.i_ = static_cast<index_type>(rx);
1817  node.j_ = static_cast<index_type>(ry);
1818  node.mesh_ = this;
1819 
1820  return (true);
1821 }
1822 
1823 
1824 template <class Basis>
1825 bool
1827  Core::Geometry::Point &result,
1828  typename Node::index_type &node,
1829  const Core::Geometry::Point &p) const
1830 {
1831  if (ni_ == 0 || nj_ == 0) return (false);
1832 
1833  const Core::Geometry::Point r = transform_.unproject(p);
1834 
1835  double rx = floor(r.x() + 0.5);
1836  double ry = floor(r.y() + 0.5);
1837 
1838  const double nii = static_cast<double>(ni_-1);
1839  const double njj = static_cast<double>(nj_-1);
1840 
1841  if (rx < 0.0) rx = 0.0; if (rx > nii) rx = nii;
1842  if (ry < 0.0) ry = 0.0; if (ry > njj) ry = njj;
1843 
1844  result = transform_.project(Core::Geometry::Point(rx,ry,0.0));
1845  node.i_ = static_cast<index_type>(rx);
1846  node.j_ = static_cast<index_type>(ry);
1847  node.mesh_ = this;
1848 
1849  pdist = (p-result).length();
1850  return (true);
1851 }
1852 
1853 
1854 template <class Basis>
1855 bool
1857  Core::Geometry::Point &result,
1858  typename Node::index_type &node,
1859  const Core::Geometry::Point &p, double maxdist) const
1860 {
1861  bool ret = find_closest_node(pdist,result,node,p);
1862  if (!ret) return (false);
1863  if (maxdist < 0.0 || pdist < maxdist) return (true);
1864  return (false);
1865 }
1866 
1867 template <class Basis>
1868 bool
1870  Core::Geometry::Point &result,
1871  std::vector<typename Elem::index_type> &elems,
1872  const Core::Geometry::Point &p) const
1873 {
1874  if (ni_ == 0 || nj_ == 0) return (false);
1875 
1876  elems.clear();
1877 
1878  const double epsilon = 1e-8;
1879 
1880  const Core::Geometry::Point r = transform_.unproject(p);
1881 
1882  double ii = r.x();
1883  double jj = r.y();
1884  const double nii = static_cast<double>(ni_-2);
1885  const double njj = static_cast<double>(nj_-2);
1886 
1887  if (ii < 0.0) ii = 0.0; if (ii > nii) ii = nii;
1888  if (jj < 0.0) jj = 0.0; if (jj > njj) jj = njj;
1889 
1890  const double fii = floor(ii);
1891  const double fjj = floor(jj);
1892 
1893  index_type i = static_cast<index_type>(fii);
1894  index_type j = static_cast<index_type>(fjj);
1895 
1896  typename Elem::index_type elem;
1897 
1898  elem.i_ = i;
1899  elem.j_ = j;
1900  elem.mesh_ = this;
1901  elems.push_back(elem);
1902 
1903  if ((fabs(fii-ii) < epsilon) && ((i-1)>0))
1904  {
1905  elem.i_ = i-1;
1906  elem.j_ = j;
1907  elems.push_back(elem);
1908  }
1909 
1910  if ((fabs(fii-(ii+1.0)) < epsilon) && (i<(ni_-1)))
1911  {
1912  elem.i_ = i+1;
1913  elem.j_ = j;
1914  elems.push_back(elem);
1915  }
1916 
1917  if ((fabs(fjj-jj) < epsilon) && ((j-1)>0))
1918  {
1919  elem.i_ = i;
1920  elem.j_ = j-1;
1921  elems.push_back(elem);
1922  }
1923 
1924  if ((fabs(fjj-(jj+1.0)) < epsilon) && (j<(nj_-1)))
1925  {
1926  elem.i_ = i;
1927  elem.j_ = j+1;
1928  elems.push_back(elem);
1929  }
1930 
1931  result = transform_.project(Core::Geometry::Point(ii,jj,0));
1932 
1933  pdist = (p-result).length();
1934  return (true);
1935 }
1936 
1937 template <class Basis>
1938 void
1940 {
1941  if (basis_.polynomial_order() < 2)
1942  {
1943 
1944  Core::Geometry::Vector J1 = transform_.project(Core::Geometry::Vector(1.0,0.0,0.0));
1945  Core::Geometry::Vector J2 = transform_.project(Core::Geometry::Vector(0.0,1.0,0.0));
1946  Core::Geometry::Vector J3 = Cross(J1,J2);
1947  J3.normalize();
1948 
1949  jacobian_[0] = J1.x();
1950  jacobian_[1] = J1.y();
1951  jacobian_[2] = J1.z();
1952  jacobian_[3] = J2.x();
1953  jacobian_[4] = J2.y();
1954  jacobian_[5] = J2.z();
1955  jacobian_[6] = J3.x();
1956  jacobian_[7] = J3.y();
1957  jacobian_[8] = J3.z();
1958 
1959  det_jacobian_ = DetMatrix3x3(jacobian_);
1960  scaled_jacobian_ = ScaledDetMatrix3x3(jacobian_);
1961  det_inverse_jacobian_ = InverseMatrix3x3(jacobian_,inverse_jacobian_);
1962  }
1963 }
1964 
1965 } // namespace SCIRun
1966 
1967 #endif
std::vector< index_type > array_type
Definition: ImageMesh.h:278
double jacobian_[9]
Definition: ImageMesh.h:958
void begin(typename Node::iterator &) const
Definition: ImageMesh.h:1543
Interface to statically allocated std::vector class.
void set_ni(size_type i)
Definition: ImageMesh.h:663
bool operator!=(const ImageIter &a) const
Definition: ImageMesh.h:156
bool reading() const
Definition: Persistent.h:164
static PersistentTypeID imagemesh_typeid
Definition: ImageMesh.h:817
index_type i_
Definition: ImageMesh.h:235
INodeSize()
Definition: ImageMesh.h:240
Core::Geometry::Vector diagonal() const
Definition: ImageMesh.h:1030
CellIndex< under_type > size_type
Definition: ImageMesh.h:277
double get_size(typename Cell::index_type) const
Definition: ImageMesh.h:759
Definition: FieldRNG.h:37
std::string get_name(const std::string &type_sep_start="<", const std::string &type_sep_end="> ") const
Definition: TypeDescription.cc:135
index_type min_j_
Definition: ImageMesh.h:939
index_type edge3_index() const
Definition: ImageMesh.h:340
EdgeIndex< under_type > size_type
Definition: ImageMesh.h:263
Vector project(const Vector &p) const
Definition: Transform.cc:425
void end(typename Node::iterator &) const
Definition: ImageMesh.h:1551
virtual std::string dynamic_type_name() const
Definition: ImageMesh.h:820
#define IMAGEMESH_VERSION
Definition: ImageMesh.h:1475
friend class VImageMesh
Make sure the virtual interface has access.
Definition: ImageMesh.h:86
ImageMesh()
Definition: ImageMesh.h:379
Point max() const
Definition: BBox.h:195
double inverse_jacobian(const VECTOR &coords, typename Elem::index_type idx, double *Ji) const
Definition: ImageMesh.h:599
void get_edges(typename Edge::array_type &, typename Cell::index_type) const
Definition: ImageMesh.h:712
size_type ni_
Definition: ImageMesh.h:942
double get_length(typename Edge::index_type idx) const
Definition: ImageMesh.h:762
INodeIndex(const ImageMesh *m, index_type i, index_type j)
Definition: ImageMesh.h:139
const Core::Geometry::Point node3() const
Definition: ImageMesh.h:366
void get_faces(typename Face::array_type &, typename Cell::index_type) const
Definition: ImageMesh.h:714
Definition: ImageMesh.h:61
INodeIter(const ImageMesh *m, index_type i, index_type j)
Definition: ImageMesh.h:165
void get_point(Core::Geometry::Point &p, const typename Node::index_type &i) const
Definition: ImageMesh.h:806
Definition: Persistent.h:89
void pre_scale(const Vector &)
Definition: Transform.cc:193
void get_center(Core::Geometry::Point &, typename Cell::index_type) const
Definition: ImageMesh.h:790
const Core::Geometry::Point node0() const
Definition: ImageMesh.h:348
Definition: ImageMesh.h:220
void pwl_approx_face(std::vector< std::vector< std::vector< double > > > &coords, typename Elem::index_type, unsigned int, unsigned int div_per_unit) const
Definition: ImageMesh.h:457
void get_delems(typename DElem::array_type &result, const typename Elem::index_type &idx) const
Wrapper to get the derivative elements from this element.
Definition: ImageMesh.h:729
virtual ~ImageMesh()
Definition: ImageMesh.h:421
Point unproject(const Point &p) const
Definition: Transform.cc:483
IFaceIndex index_type
Definition: ImageMesh.h:268
Definition: ImageMesh.h:191
void get_nodes(typename Node::array_type &, typename Edge::index_type) const
get the child elements of the given index
Definition: ImageMesh.h:1155
void set_min_j(index_type j)
Definition: ImageMesh.h:661
double get_size(typename Edge::index_type idx) const
Definition: ImageMesh.h:740
void y(const double)
Definition: Point.h:135
index_type edge2_index() const
Definition: ImageMesh.h:334
VMesh * CreateVImageMesh(MESH *)
Definition: ImageMesh.h:67
size_type j_
Definition: ImageMesh.h:119
Definition: Persistent.h:187
bool get_min(std::vector< index_type > &) const
Definition: ImageMesh.h:1085
std::ostream & str_render(std::ostream &os) const
Definition: ImageMesh.h:228
BBox & extend(const Point &p)
Expand the bounding box to include point p.
Definition: BBox.h:98
void get_nodes(typename Node::array_type &, typename Cell::index_type) const
Definition: ImageMesh.h:709
virtual int dimensionality() const
Definition: ImageMesh.h:827
bool find_closest_elems(double &pdist, Core::Geometry::Point &result, std::vector< typename Elem::index_type > &elem, const Core::Geometry::Point &p) const
Definition: ImageMesh.h:1869
void to_index(typename Edge::index_type &index, index_type i) const
Definition: ImageMesh.h:700
virtual void set_dim(std::vector< size_type > dims)
Definition: ImageMesh.h:1122
static const std::string type_name(int n=-1)
Core functionality for getting the name of a templated mesh class.
Definition: ImageMesh.h:1521
Definition: TypeDescription.h:50
static const TypeDescription * elem_type_description()
Definition: ImageMesh.h:837
FieldHandle mesh()
Definition: BuildTDCSMatrixTests.cc:56
size_type get_min_i() const
get the mesh statistics
Definition: ImageMesh.h:645
Definition: Point.h:49
Definition: TypeDescription.h:45
#define SCISHARE
Definition: share.h:39
std::vector< const TypeDescription * > td_vec
Definition: TypeDescription.h:56
Definition: Mesh.h:45
size_type get_nj() const
Definition: ImageMesh.h:649
void derivate(const VECTOR1 &coords, typename Elem::index_type idx, VECTOR2 &J) const
Definition: ImageMesh.h:527
Definition: BBox.h:46
Basis basis_
The basis class.
Definition: ImageMesh.h:951
boost::shared_ptr< Mesh > MeshHandle
Definition: DatatypeFwd.h:67
Distinct type for cell Iterator.
Definition: FieldIterator.h:134
void compute_imat() const
Definition: Transform.cc:687
virtual void begin_cheap_delim()
Definition: Persistent.cc:183
Definition: Mesh.h:61
unsigned int mask_type
Definition: Types.h:45
static MeshHandle image_maker(size_type x, size_type y, const Core::Geometry::Point &min, const Core::Geometry::Point &max)
This function returns a handle for the virtual interface.
Definition: ImageMesh.h:847
EdgeIndex< under_type > index_type
Definition: ImageMesh.h:261
static Persistent * maker()
This function returns a maker for Pio.
Definition: ImageMesh.h:843
#define ASSERT(condition)
Definition: Assert.h:110
size_type get_ni() const
Definition: ImageMesh.h:648
void get_faces(typename Face::array_type &a, typename Face::index_type f) const
Definition: ImageMesh.h:716
bool locate(typename Node::index_type &, const Core::Geometry::Point &) const
Definition: ImageMesh.h:1802
virtual int begin_class(const std::string &name, int current_version)
Definition: Persistent.cc:143
boost::shared_ptr< VMesh > vmesh_
Virtual mesh.
Definition: ImageMesh.h:954
ImageIndex(const ImageMesh *m, size_type i, size_type j)
Definition: ImageMesh.h:106
Definition: ImageMesh.h:124
Definition: Vector.h:63
virtual VMesh * vmesh()
Access point to virtual interface.
Definition: ImageMesh.h:432
INodeIndex index_type
Definition: ImageMesh.h:254
virtual void get_canonical_transform(Core::Geometry::Transform &t)
Definition: ImageMesh.h:1038
IFaceIndex(const ImageMesh *m, index_type i, index_type j)
Definition: ImageMesh.h:127
IFaceIter iterator
Definition: ImageMesh.h:269
static const TypeDescription * cell_type_description()
Definition: ImageMesh.h:1743
const string find_type_name(float *)
Definition: TypeName.cc:63
Definition: ImageMesh.h:101
CellIndex< under_type > index_type
Definition: ImageMesh.h:275
IFaceIndex()
Definition: ImageMesh.h:126
T DetMatrix3x3(const T *p)
Definition: Locate.h:95
Definition: ImageMesh.h:274
CellIterator< under_type > iterator
Definition: ImageMesh.h:276
IFaceSize size_type
Definition: ImageMesh.h:270
double inverse_jacobian_[9]
Definition: ImageMesh.h:959
Definition: ParallelLinearAlgebraTests.cc:358
void get_neighbors(typename Face::array_type &array, typename Face::index_type idx) const
Definition: ImageMesh.h:1259
virtual ImageMesh * clone() const
Definition: ImageMesh.h:420
virtual Core::Geometry::BBox get_bounding_box() const
Definition: ImageMesh.h:1012
const char * name[]
Definition: BoostGraphExampleTests.cc:87
void x(const double)
Definition: Point.h:125
double jacobian_metric(typename Elem::index_type) const
Definition: ImageMesh.h:639
long long size_type
Definition: Types.h:40
MeshFacadeHandle getFacade() const
Definition: ImageMesh.h:426
Definition: StackVector.h:50
double get_epsilon() const
Definition: ImageMesh.h:1001
void get_edges(typename Edge::array_type &, typename Face::index_type) const
Definition: ImageMesh.h:1180
static const TypeDescription * face_type_description()
Definition: ImageMesh.h:1725
INodeIter()
Definition: ImageMesh.h:164
bool operator==(const ImageIter &a) const
Definition: ImageMesh.h:151
Vector Cross(const Vector &v1, const Vector &v2)
Definition: Vector.h:378
double get_size(const typename Node::index_type &) const
Get the size of an element (length, area, volume)
Definition: ImageMesh.h:739
std::vector< index_type > array_type
Definition: ImageMesh.h:271
const ImageIndex & operator*()
Definition: ImageMesh.h:149
const Core::Geometry::Point node2() const
Definition: ImageMesh.h:360
static const TypeDescription * edge_type_description()
Definition: ImageMesh.h:1707
size_type get_min_j() const
Definition: ImageMesh.h:646
size_type nj_
Definition: ImageMesh.h:943
Definition: Mesh.h:79
double scaled_jacobian_
Definition: ImageMesh.h:961
ImageMesh(const ImageMesh &copy)
Definition: ImageMesh.h:405
int get_weights(const Core::Geometry::Point &p, typename Node::array_type &l, double *w)
Definition: ImageMesh.h:1358
virtual void io(Piostream &)
Export this class using the old Pio system.
Definition: ImageMesh.h:1479
std::string type
Definition: Persistent.h:72
INodeSize size_type
Definition: ImageMesh.h:256
void interpolate(Core::Geometry::Point &pt, const VECTOR &coords, typename Elem::index_type idx) const
Definition: ImageMesh.h:506
virtual void transform(const Core::Geometry::Transform &t)
Definition: ImageMesh.h:1075
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, typename Elem::index_type &elem, const Core::Geometry::Point &p, double maxdist) const
Definition: ImageMesh.h:863
virtual void end_cheap_delim()
Definition: Persistent.cc:188
Point min() const
Definition: BBox.h:192
Definition: Transform.h:53
INodeSize(index_type i, index_type j)
Definition: ImageMesh.h:241
void set_min(std::vector< index_type > mins)
Definition: ImageMesh.h:1113
Core::Geometry::Transform transform_
the object space extents of a ImageMesh
Definition: ImageMesh.h:946
Definition: ImageMesh.h:290
index_type node3_index() const
Definition: ImageMesh.h:317
virtual bool has_face_normals() const
Definition: ImageMesh.h:437
INodeIter & operator++()
Definition: ImageMesh.h:170
void x(double)
Definition: Vector.h:175
bool locate(typename Edge::index_type &, const Core::Geometry::Point &) const
Definition: ImageMesh.h:794
Core::Geometry::Transform & get_transform()
Definition: ImageMesh.h:823
void set_nj(size_type j)
Definition: ImageMesh.h:672
bool find_closest_node(double &pdist, Core::Geometry::Point &result, typename Node::index_type &elem, const Core::Geometry::Point &p) const
Definition: ImageMesh.h:1826
static const TypeDescription * node_index_type_description()
Definition: ImageMesh.h:1425
bool get_neighbor(typename Face::index_type &neighbor, typename Face::index_type from, typename Edge::index_type idx) const
Definition: ImageMesh.h:1225
void get_random_point(Core::Geometry::Point &, const typename Elem::index_type &, FieldRNG &rng) const
Definition: ImageMesh.h:1399
Edge DElem
Definition: ImageMesh.h:282
static const std::string make_template_id(const std::string &templateName, const std::string &templateParam)
Definition: TypeName.h:62
std::vector< index_type > array_type
Definition: ImageMesh.h:264
ImageIndex()
Definition: ImageMesh.h:104
v
Definition: readAllFields.py:42
void get_center(Core::Geometry::Point &, const typename Node::index_type &) const
get the center point (in object space) of an element
Definition: ImageMesh.h:1323
double get_size(const typename Face::index_type &idx) const
Definition: ImageMesh.h:749
void pre_translate(const Vector &)
Definition: Transform.cc:278
double det_jacobian_
Definition: ImageMesh.h:960
double normalize()
Definition: Vector.h:437
Definition: ImageMesh.h:136
Definition: ImageMesh.h:245
bool get_coords(VECTOR &coords, const Core::Geometry::Point &p, typename Elem::index_type idx) const
Definition: ImageMesh.h:470
virtual bool get_dim(std::vector< size_type > &) const
Definition: ImageMesh.h:1099
void y(double)
Definition: Vector.h:185
double safe_normalize()
Definition: Vector.h:236
void compute_jacobian()
Definition: ImageMesh.h:1939
ImageIter()
Definition: ImageMesh.h:145
IFaceIter(const ImageMesh *m, index_type i, index_type j)
Definition: ImageMesh.h:194
Distinct type for edge Iterator.
Definition: FieldIterator.h:105
void to_index(typename Node::index_type &index, index_type i) const
Definition: ImageMesh.h:1567
IFaceSize()
Definition: ImageMesh.h:247
index_type min_i_
the min_typename Node::index_type ( incase this is a subLattice )
Definition: ImageMesh.h:938
StackVector< index_type, 4 > array_type
Definition: ImageMesh.h:257
void pwl_approx_edge(std::vector< std::vector< double > > &coords, typename Elem::index_type, unsigned int which_edge, unsigned int div_per_unit) const
Definition: ImageMesh.h:444
#define ASSERTFAIL(string)
Definition: Assert.h:52
Basis & get_basis()
Definition: ImageMesh.h:440
void Pio(Piostream &stream, Array1< T > &array)
Definition: Array1.h:65
Some convenient simple iterators for fields.
virtual const TypeDescription * get_type_description() const
Definition: ImageMesh.h:1681
INodeIter iterator
Definition: ImageMesh.h:255
void size(typename Node::size_type &) const
Definition: ImageMesh.h:1559
double get_volume(typename Cell::index_type) const
Definition: ImageMesh.h:764
bool locate(typename Cell::index_type &, const Core::Geometry::Point &) const
Definition: ImageMesh.h:796
Vector project_normal(const Vector &) const
Definition: Transform.cc:554
static const TypeDescription * node_type_description()
Definition: ImageMesh.h:1689
virtual void end_class()
Definition: Persistent.cc:178
const IFaceIndex & operator*() const
Definition: ImageMesh.h:197
bool clear_synchronization()
Definition: ImageMesh.h:1068
Basis basis_type
Definition: ImageMesh.h:97
Definition: ImageMesh.h:143
T ScaledDetMatrix3x3(const T *p)
Definition: Locate.h:106
ImageIter(const ImageMesh *m, index_type i, index_type j)
Definition: ImageMesh.h:146
Index and Iterator types required for Mesh Concept.
Definition: ImageMesh.h:253
boost::shared_ptr< ImageMesh< Basis > > handle_type
Definition: ImageMesh.h:96
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, ARRAY &coords, typename Elem::index_type &elem, const Core::Geometry::Point &p) const
Definition: ImageMesh.h:888
const Core::Geometry::Point node1() const
Definition: ImageMesh.h:354
long long index_type
Definition: Types.h:39
size_type i_
Definition: ImageMesh.h:119
IFaceSize(index_type i, index_type j)
Definition: ImageMesh.h:248
static const TypeDescription * face_index_type_description()
Definition: ImageMesh.h:1440
int get_weights(const Core::Geometry::Point &, typename Edge::array_type &, double *)
Definition: ImageMesh.h:800
int get_weights(const Core::Geometry::Point &, typename Cell::array_type &, double *)
Definition: ImageMesh.h:803
void resize(size_t size, const value_type &val=value_type())
Definition: StackVector.h:61
std::ostream & str_render(std::ostream &os) const
Definition: ImageMesh.h:114
virtual bool unsynchronize(mask_type sync)
Definition: ImageMesh.h:1061
index_type node0_index() const
Definition: ImageMesh.h:301
const ImageMesh * mesh_
Definition: ImageMesh.h:121
EdgeIterator< under_type > iterator
Definition: ImageMesh.h:262
ElemData(const ImageMesh< Basis > &msh, const typename Elem::index_type ind)
Definition: ImageMesh.h:293
Core::Geometry::Transform & set_transform(const Core::Geometry::Transform &trans)
Definition: ImageMesh.h:824
index_type node2_index() const
Definition: ImageMesh.h:311
Definition: Persistent.h:64
SCIRun::size_type size_type
Definition: ImageMesh.h:93
ImageSize()
Definition: ImageMesh.h:223
IFaceIter()
Definition: ImageMesh.h:193
Definition: ImageMesh.h:238
index_type node1_index() const
Definition: ImageMesh.h:306
SCIRun::mask_type mask_type
Definition: ImageMesh.h:94
void set_min_i(index_type i)
set the mesh statistics
Definition: ImageMesh.h:660
Distinct type for edge index.
Definition: FieldIndex.h:81
index_type j_
Definition: ImageMesh.h:235
int n
Definition: eab.py:9
virtual bool has_normals() const
Definition: ImageMesh.h:436
index_type edge1_index() const
Definition: ImageMesh.h:329
virtual int basis_order()
Definition: ImageMesh.h:434
T InverseMatrix3x3(const T *p, T *q)
Definition: Locate.h:47
double get_area(typename Face::index_type idx) const
Definition: ImageMesh.h:763
SCIRun::index_type index_type
Definition: ImageMesh.h:92
Face Elem
Definition: ImageMesh.h:281
Definition: ImageMesh.h:162
void post_scale(const Vector &)
Definition: Transform.cc:202
Core::Geometry::Vector normal_
Definition: ImageMesh.h:948
virtual bool synchronize(mask_type sync)
Definition: ImageMesh.h:1047
#define DEBUG_CONSTRUCTOR(type)
Definition: Debug.h:64
void io(Piostream &stream)
Persistent I/O.
Definition: Mesh.cc:387
SCIRun::index_type under_type
Definition: ImageMesh.h:91
void get_normal(Core::Geometry::Vector &, const typename Node::index_type &) const
Definition: ImageMesh.h:774
Definition: ImageMesh.h:267
virtual int topology_geometry() const
Definition: ImageMesh.h:828
INodeIndex()
Definition: ImageMesh.h:138
void get_elems(typename Elem::array_type &result, typename Node::index_type idx) const
get the parent element(s) of the given index
Definition: ImageMesh.h:1278
double det_jacobian(const VECTOR &coords, typename Elem::index_type idx) const
Definition: ImageMesh.h:546
void get_elems(typename Elem::array_type &, typename Face::index_type) const
Definition: ImageMesh.h:724
bool find_closest_elem(double &pdist, Core::Geometry::Point &result, typename Elem::index_type &elem, const Core::Geometry::Point &p) const
Definition: ImageMesh.h:878
Definition: Mesh.h:63
void Pio_size(Piostream &stream, Size &size)
Definition: Persistent.h:273
void get_normal(Core::Geometry::Vector &result, std::vector< double > &coords, typename Elem::index_type eidx, index_type)
Definition: ImageMesh.h:776
void z(double)
Definition: Vector.h:195
boost::shared_ptr< MeshFacade< VMesh > > MeshFacadeHandle
Definition: MeshTraits.h:61
static MeshHandle mesh_maker()
This function returns a handle for the virtual interface.
Definition: ImageMesh.h:845
Definition: VMesh.h:53
Definition: ImageMesh.h:260
void to_index(typename Cell::index_type &, index_type) const
Definition: ImageMesh.h:702
index_type edge0_index() const
Definition: ImageMesh.h:324
IFaceIter & operator++()
Definition: ImageMesh.h:199
ImageMesh(ImageMesh *mh, size_type mx, size_type my, size_type x, size_type y)
Definition: ImageMesh.h:391
const INodeIndex & operator*() const
Definition: ImageMesh.h:168
virtual bool is_editable() const
Definition: ImageMesh.h:438
void jacobian(const VECTOR &coords, typename Elem::index_type idx, double *J) const
Definition: ImageMesh.h:562
double scaled_jacobian_metric(typename Elem::index_type) const
Definition: ImageMesh.h:636
double det_inverse_jacobian_
Definition: ImageMesh.h:962
ImageSize(index_type i, index_type j)
Definition: ImageMesh.h:224
#define DEBUG_DESTRUCTOR(type)
Definition: Debug.h:65
const TypeDescription * get_type_description(Core::Basis::ConstantBasis< T > *)
Definition: Constant.h:209
bool elem_locate(INDEX &elem, MESH &msh, const Core::Geometry::Point &p)
General case locate, search each elem.
Definition: Mesh.h:188