Field3D
|
00001 //----------------------------------------------------------------------------// 00002 00003 /* 00004 * Copyright (c) 2009 Sony Pictures Imageworks Inc 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * Redistributions in binary form must reproduce the above copyright 00015 * notice, this list of conditions and the following disclaimer in the 00016 * documentation and/or other materials provided with the 00017 * distribution. Neither the name of Sony Pictures Imageworks nor the 00018 * names of its contributors may be used to endorse or promote 00019 * products derived from this software without specific prior written 00020 * permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00029 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00030 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 00031 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00032 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 00033 * OF THE POSSIBILITY OF SUCH DAMAGE. 00034 */ 00035 00036 //----------------------------------------------------------------------------// 00037 00043 //----------------------------------------------------------------------------// 00044 00045 #ifndef _INCLUDED_Field3D_Field_H_ 00046 #define _INCLUDED_Field3D_Field_H_ 00047 00048 #include <cmath> 00049 #include <vector> 00050 #include <map> 00051 00052 #include <boost/intrusive_ptr.hpp> 00053 #include <boost/thread/mutex.hpp> 00054 00055 #include "Traits.h" 00056 #include "Exception.h" 00057 #include "FieldMapping.h" 00058 #include "FieldMetadata.h" 00059 #include "Log.h" 00060 #include "RefCount.h" 00061 #include "Types.h" 00062 00063 //----------------------------------------------------------------------------// 00064 00065 #include "ns.h" 00066 00067 FIELD3D_NAMESPACE_OPEN 00068 00069 //----------------------------------------------------------------------------// 00070 // Field RTTI Replacement 00071 //----------------------------------------------------------------------------// 00072 00073 #define DEFINE_CHECK_RTTI_CALL \ 00074 virtual bool checkRTTI(const std::string &typenameStr) \ 00075 { return matchRTTI(typenameStr); } \ 00076 00077 #define DEFINE_MATCH_RTTI_CALL \ 00078 bool matchRTTI(const std::string &typenameStr) \ 00079 { \ 00080 if (typenameStr == typeid(class_type).name()) { \ 00081 return true; \ 00082 } \ 00083 return base::matchRTTI(typenameStr); \ 00084 } 00085 00086 #define DEFINE_FIELD_RTTI_CONCRETE_CLASS \ 00087 DEFINE_CHECK_RTTI_CALL \ 00088 DEFINE_MATCH_RTTI_CALL 00089 00090 #define DEFINE_FIELD_RTTI_ABSTRACT_CLASS \ 00091 DEFINE_MATCH_RTTI_CALL 00092 00093 //----------------------------------------------------------------------------// 00094 // Exceptions 00095 //----------------------------------------------------------------------------// 00096 00097 namespace Exc { 00098 00099 DECLARE_FIELD3D_GENERIC_EXCEPTION(MemoryException, Exception) 00100 DECLARE_FIELD3D_GENERIC_EXCEPTION(ResizeException, Exception) 00101 00102 } // namespace Exc 00103 00104 //----------------------------------------------------------------------------// 00105 // FieldTraits 00106 //----------------------------------------------------------------------------// 00107 00113 template <class Data_T> 00114 class FieldTraits 00115 { 00116 public: 00118 static int dataDims(); 00119 }; 00120 00121 //----------------------------------------------------------------------------// 00122 // FieldBase 00123 //----------------------------------------------------------------------------// 00124 00132 class FieldBase : public RefBase 00133 { 00134 public: 00135 00136 // Typedefs ------------------------------------------------------------------ 00137 00138 typedef boost::intrusive_ptr<FieldBase> Ptr; 00139 typedef FieldBase class_type; 00140 00141 // Constructors -------------------------------------------------------------- 00142 00145 00147 FieldBase(); 00148 00150 FieldBase(const FieldBase &); 00151 00153 virtual ~FieldBase(); 00154 00156 00157 // To be implemented by subclasses ------------------------------------------- 00158 00161 00164 virtual std::string className() const = 0; 00165 00168 virtual Ptr clone() const = 0; 00169 00171 00172 // RTTI replacement ---------------------------------------------------------- 00173 00182 00183 00184 00187 virtual bool checkRTTI(const std::string &typenameStr) = 0; 00188 00191 bool matchRTTI(const std::string &typenameStr) 00192 { return typenameStr == typeid(*this).name(); } 00193 00195 00196 // Access to metadata -------------------------------------------------------- 00197 00200 00202 FieldMetadata<FieldBase>& metadata() 00203 { return m_metadata; } 00204 00206 const FieldMetadata<FieldBase>& metadata() const 00207 { return m_metadata; } 00208 00211 virtual void metadataHasChanged(const std::string &/* name */) 00212 { /* Empty */ } 00213 00215 void copyMetadata(const FieldBase &field) 00216 { m_metadata = field.metadata(); } 00217 00219 00220 // Public data members ------------------------------------------------------- 00221 00223 std::string name; 00225 std::string attribute; 00226 00227 private: 00228 00229 // Private data members ------------------------------------------------------ 00230 00232 FieldMetadata<FieldBase> m_metadata; 00233 00234 }; 00235 00236 //----------------------------------------------------------------------------// 00237 // FieldRes 00238 //----------------------------------------------------------------------------// 00239 00257 class FieldRes : public FieldBase 00258 { 00259 public: 00260 00261 // Typedefs ------------------------------------------------------------------ 00262 00263 typedef boost::intrusive_ptr<FieldRes> Ptr; 00264 typedef std::vector<Ptr> Vec; 00265 00266 virtual std::string dataTypeString() const = 0; 00267 00268 // RTTI replacement ---------------------------------------------------------- 00269 00270 typedef FieldRes class_type; 00271 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00272 00273 // Ctor, dtor ---------------------------------------------------------------- 00274 00276 FieldRes(); 00277 00280 FieldRes(const FieldRes &src); 00281 00282 // Main methods -------------------------------------------------------------- 00283 00288 inline const Box3i& extents() const 00289 { return m_extents; } 00292 inline const Box3i& dataWindow() const 00293 { return m_dataWindow; } 00294 00295 inline V3i const dataResolution() const 00296 { return m_dataWindow.max - m_dataWindow.min + V3i(1); } 00297 00299 void setMapping(FieldMapping::Ptr mapping); 00300 00302 FieldMapping::Ptr mapping() 00303 { return m_mapping; } 00304 00306 const FieldMapping::Ptr mapping() const 00307 { return m_mapping; } 00308 00310 bool isInBounds(int i, int j, int k); 00311 00312 // To be implemented by subclasses ------------------------------------------- 00313 00318 virtual long long int memSize() const 00319 { return sizeof(*this); } 00320 00321 protected: 00322 00323 // Typedefs ------------------------------------------------------------------ 00324 00325 typedef MatrixFieldMapping default_mapping; 00326 00327 // Data members -------------------------------------------------------------- 00328 00333 Box3i m_extents; 00336 Box3i m_dataWindow; 00338 FieldMapping::Ptr m_mapping; 00339 00340 private: 00341 00342 // Typedefs ------------------------------------------------------------------ 00343 00345 typedef FieldBase base; 00346 00347 }; 00348 00349 //----------------------------------------------------------------------------// 00350 00351 inline FieldRes::FieldRes() 00352 : m_mapping(new default_mapping) 00353 { 00354 m_extents = Box3i(V3i(0), V3i(-1)); 00355 m_dataWindow = m_extents; 00356 m_mapping->setExtents(m_extents); 00357 } 00358 00359 //----------------------------------------------------------------------------// 00360 00361 inline FieldRes::FieldRes(const FieldRes &src) 00362 : FieldBase(src) 00363 { 00364 // Call base class first 00365 // FieldBase(src); 00366 // Copy self 00367 *this = src; 00368 m_mapping = src.mapping()->clone(); 00369 } 00370 00371 //----------------------------------------------------------------------------// 00372 00373 inline void FieldRes::setMapping(FieldMapping::Ptr mapping) 00374 { 00375 if (mapping) { 00376 m_mapping = mapping->clone(); 00377 m_mapping->setExtents(m_extents); 00378 } else { 00379 Msg::print(Msg::SevWarning, 00380 "Tried to call FieldRes::setMapping with null pointer"); 00381 } 00382 } 00383 00384 //----------------------------------------------------------------------------// 00385 00386 inline bool FieldRes::isInBounds(int i, int j, int k) 00387 { 00388 // Check bounds 00389 if (i < m_dataWindow.min.x || i > m_dataWindow.max.x || 00390 j < m_dataWindow.min.y || j > m_dataWindow.max.y || 00391 k < m_dataWindow.min.z || k > m_dataWindow.max.z) { 00392 return false; 00393 } 00394 00395 return true; 00396 } 00397 00398 //----------------------------------------------------------------------------// 00399 // field_dynamic_cast 00400 //----------------------------------------------------------------------------// 00401 00405 template <class Field_T> 00406 typename Field_T::Ptr 00407 field_dynamic_cast(FieldBase::Ptr field) 00408 { 00409 if (!field) 00410 return NULL; 00411 std::string tgtTypeString = typeid(Field_T).name(); 00412 if (field->checkRTTI(tgtTypeString)) { 00413 return static_cast<Field_T*>(field.get()); 00414 } else { 00415 return NULL; 00416 } 00417 } 00418 00419 //----------------------------------------------------------------------------// 00420 // Field 00421 //----------------------------------------------------------------------------// 00422 00433 template <class Data_T> 00434 class Field : public FieldRes 00435 { 00436 public: 00437 00438 // Typedefs ------------------------------------------------------------------ 00439 00440 typedef boost::intrusive_ptr<Field> Ptr; 00441 00443 typedef Data_T value_type; 00444 00448 typedef std::vector<Ptr> Vec; 00449 00450 // RTTI replacement ---------------------------------------------------------- 00451 00452 typedef Field<Data_T> class_type; 00453 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00454 00455 // Constructors -------------------------------------------------------------- 00456 00458 virtual ~Field() 00459 { /* Empty */ } 00460 00461 // Iterators ----------------------------------------------------------------- 00462 00465 class const_iterator; 00466 00468 const_iterator cbegin() const; 00470 const_iterator cbegin(const Box3i &subset) const; 00472 const_iterator cend() const; 00475 const_iterator cend(const Box3i &subset) const; 00476 00477 // To be implemented by subclasses ------------------------------------------- 00478 00485 virtual Data_T value(int i, int j, int k) const = 0; 00486 00487 // Other member functions ---------------------------------------------------- 00488 00489 virtual std::string dataTypeString() const 00490 { return DataTypeTraits<Data_T>::name(); } 00491 00492 private: 00493 00494 // Typedefs ------------------------------------------------------------------ 00495 00497 typedef FieldRes base; 00498 00499 }; 00500 00501 //----------------------------------------------------------------------------// 00502 00503 template <class Data_T> 00504 typename Field<Data_T>::const_iterator 00505 Field<Data_T>::cbegin() const 00506 { 00507 if (FieldRes::dataResolution() == V3i(0)) 00508 return cend(); 00509 return const_iterator(*this, m_dataWindow, m_dataWindow.min); 00510 } 00511 00512 //----------------------------------------------------------------------------// 00513 00514 template <class Data_T> 00515 typename Field<Data_T>::const_iterator 00516 Field<Data_T>::cbegin(const Box3i &subset) const 00517 { 00518 if (subset.isEmpty()) 00519 return cend(subset); 00520 return const_iterator(*this, subset, subset.min); 00521 } 00522 00523 //----------------------------------------------------------------------------// 00524 00525 template <class Data_T> 00526 typename Field<Data_T>::const_iterator 00527 Field<Data_T>::cend() const 00528 { 00529 return const_iterator(*this, m_dataWindow, 00530 V3i(m_dataWindow.min.x, 00531 m_dataWindow.min.y, 00532 m_dataWindow.max.z + 1)); 00533 } 00534 00535 //----------------------------------------------------------------------------// 00536 00537 template <class Data_T> 00538 typename Field<Data_T>::const_iterator 00539 Field<Data_T>::cend(const Box3i &subset) const 00540 { 00541 return const_iterator(*this, subset, V3i(subset.min.x, 00542 subset.min.y, 00543 subset.max.z + 1)); 00544 } 00545 00546 //----------------------------------------------------------------------------// 00547 // Field::const_iterator 00548 //----------------------------------------------------------------------------// 00549 00550 template <class Data_T> 00551 class Field<Data_T>::const_iterator 00552 { 00553 00554 public: 00555 00556 // Constructors -------------------------------------------------------------- 00557 00558 const_iterator(const const_iterator &i) 00559 : x(i.x), y(i.y), z(i.z), 00560 m_window(i.m_window), m_field(i.m_field) 00561 { } 00562 00563 const_iterator(const Field<Data_T> &field, const Box3i &window, 00564 const V3i ¤tPos) 00565 : x(currentPos.x), y(currentPos.y), z(currentPos.z), 00566 m_window(window), m_field(field) 00567 { } 00568 00569 // Operators ----------------------------------------------------------------- 00570 00571 inline const const_iterator& operator ++ () 00572 { 00573 if (x == m_window.max.x) { 00574 if (y == m_window.max.y) { 00575 x = m_window.min.x; 00576 y = m_window.min.y; 00577 ++z; 00578 } else { 00579 x = m_window.min.x; 00580 ++y; 00581 } 00582 } else { 00583 ++x; 00584 } 00585 return *this; 00586 } 00587 template <class Iter_T> 00588 bool operator == (const Iter_T &rhs) const 00589 { 00590 return x == rhs.x && y == rhs.y && z == rhs.z; 00591 } 00592 template <class Iter_T> 00593 bool operator != (const Iter_T &rhs) const 00594 { 00595 return x != rhs.x || y != rhs.y || z != rhs.z; 00596 } 00597 inline Data_T operator * () const 00598 { 00599 return m_field.value(x, y, z); 00600 } 00601 // Public data members ------------------------------------------------------- 00602 00604 int x, y, z; 00605 00606 private: 00607 00608 // Private data members ------------------------------------------------------ 00609 00611 Box3i m_window; 00613 const Field<Data_T> &m_field; 00614 00615 }; 00616 00617 //----------------------------------------------------------------------------// 00618 // WritableField 00619 //----------------------------------------------------------------------------// 00620 00627 //----------------------------------------------------------------------------// 00628 00629 template <class Data_T> 00630 class WritableField 00631 : public Field<Data_T> 00632 { 00633 public: 00634 00635 // Typedefs ------------------------------------------------------------------ 00636 00637 typedef boost::intrusive_ptr<WritableField> Ptr; 00638 00639 // RTTI replacement ---------------------------------------------------------- 00640 00641 typedef WritableField<Data_T> class_type; 00642 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00643 00644 // Iterators ----------------------------------------------------------------- 00645 00648 class iterator; 00649 00651 inline iterator begin(); 00653 inline iterator begin(const Box3i &subset); 00655 inline iterator end(); 00658 inline iterator end(const Box3i &subset); 00659 00660 // To be implemented by subclasses ------------------------------------------- 00661 00670 virtual Data_T& lvalue(int i, int j, int k) = 0; 00671 00672 // Main methods -------------------------------------------------------------- 00673 00676 virtual void clear(const Data_T &value) 00677 { std::fill(begin(), end(), value); } 00678 00679 private: 00680 00681 // Typedefs ------------------------------------------------------------------ 00682 00683 typedef Field<Data_T> base; 00684 00685 }; 00686 00687 //----------------------------------------------------------------------------// 00688 00689 template <class Data_T> 00690 inline typename WritableField<Data_T>::iterator 00691 WritableField<Data_T>::begin() 00692 { 00693 if (FieldRes::dataResolution() == V3i(0)) 00694 return end(); 00695 return iterator(*this, Field<Data_T>::m_dataWindow, 00696 Field<Data_T>::m_dataWindow.min); 00697 } 00698 00699 //----------------------------------------------------------------------------// 00700 00701 template <class Data_T> 00702 inline typename WritableField<Data_T>::iterator 00703 WritableField<Data_T>::begin(const Box3i &subset) 00704 { 00705 if (subset.isEmpty()) 00706 return end(subset); 00707 return iterator(*this, subset, subset.min); 00708 } 00709 00710 //----------------------------------------------------------------------------// 00711 00712 template <class Data_T> 00713 inline typename WritableField<Data_T>::iterator 00714 WritableField<Data_T>::end() 00715 { return iterator(*this, Field<Data_T>::m_dataWindow, 00716 V3i(Field<Data_T>::m_dataWindow.min.x, 00717 Field<Data_T>::m_dataWindow.min.y, 00718 Field<Data_T>::m_dataWindow.max.z + 1)); 00719 } 00720 00721 //----------------------------------------------------------------------------// 00722 00723 template <class Data_T> 00724 inline typename WritableField<Data_T>::iterator 00725 WritableField<Data_T>::end(const Box3i &subset) 00726 { return iterator(*this, subset, 00727 V3i(subset.min.x, subset.min.y, subset.max.z + 1)); 00728 } 00729 00730 //----------------------------------------------------------------------------// 00731 // WritableField::iterator 00732 //----------------------------------------------------------------------------// 00733 00734 template <class Data_T> 00735 class WritableField<Data_T>::iterator 00736 { 00737 00738 public: 00739 00740 // Constructors -------------------------------------------------------------- 00741 00742 iterator(WritableField<Data_T> &field, const Box3i &window, 00743 const V3i ¤tPos) 00744 : x(currentPos.x), y(currentPos.y), z(currentPos.z), 00745 m_window(window), m_field(field) 00746 { } 00747 00748 // Operators ----------------------------------------------------------------- 00749 00750 inline const iterator& operator ++ () 00751 { 00752 if (x == m_window.max.x) { 00753 if (y == m_window.max.y) { 00754 x = m_window.min.x; 00755 y = m_window.min.y; 00756 ++z; 00757 } else { 00758 x = m_window.min.x; 00759 ++y; 00760 } 00761 } else { 00762 ++x; 00763 } 00764 return *this; 00765 } 00766 00767 template <class Iter_T> 00768 bool operator == (const Iter_T &rhs) const 00769 { 00770 return x == rhs.x && y == rhs.y && z == rhs.z; 00771 } 00772 00773 template <class Iter_T> 00774 bool operator != (const Iter_T &rhs) const 00775 { 00776 return x != rhs.x || y != rhs.y || z != rhs.z; 00777 } 00778 00779 inline Data_T& operator * () const 00780 { 00781 return m_field.lvalue(x, y, z); 00782 } 00783 00784 // Public data members ------------------------------------------------------- 00785 00787 int x, y, z; 00788 00789 private: 00790 00791 // Private data members ------------------------------------------------------ 00792 00794 Box3i m_window; 00796 WritableField<Data_T> &m_field; 00797 00798 }; 00799 00800 //----------------------------------------------------------------------------// 00801 // ResizableField 00802 //----------------------------------------------------------------------------// 00803 00812 //----------------------------------------------------------------------------// 00813 00814 template <class Data_T> 00815 class ResizableField 00816 : public WritableField<Data_T> 00817 { 00818 public: 00819 00820 // Typedefs ------------------------------------------------------------------ 00821 00822 typedef boost::intrusive_ptr<ResizableField> Ptr; 00823 00824 // RTTI replacement ---------------------------------------------------------- 00825 00826 typedef ResizableField<Data_T> class_type; 00827 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00828 00829 // Main methods -------------------------------------------------------------- 00830 00834 void setSize(const V3i &size); 00838 void setSize(const Box3i &extents); 00842 void setSize(const Box3i &extents, const Box3i &dataWindow); 00846 void setSize(const V3i &size, int padding); 00847 00849 void copyFrom(typename Field<Data_T>::Ptr other); 00852 template <class Data_T2> 00853 void copyFrom(typename Field<Data_T2>::Ptr other); 00854 00856 void matchDefinition(FieldRes::Ptr fieldToMatch); 00857 00858 protected: 00859 00860 // Typedefs ------------------------------------------------------------------ 00861 00862 typedef WritableField<Data_T> base; 00863 00864 // To be implemented by subclasses ------------------------------------------- 00865 00869 virtual void sizeChanged() 00870 { base::m_mapping->setExtents(base::m_extents); } 00871 00872 }; 00873 00874 //----------------------------------------------------------------------------// 00875 00876 template <class Data_T> 00877 void ResizableField<Data_T>::setSize(const V3i &size) 00878 { 00879 Field<Data_T>::m_extents.min = V3i(0); 00880 Field<Data_T>::m_extents.max = size - V3i(1); 00881 Field<Data_T>::m_dataWindow = Field<Data_T>::m_extents; 00882 00883 // Tell subclasses that the size changed so they can update themselves. 00884 sizeChanged(); 00885 } 00886 00887 //----------------------------------------------------------------------------// 00888 00889 template <class Data_T> 00890 void ResizableField<Data_T>::setSize(const Box3i &extents) 00891 { 00892 Field<Data_T>::m_extents = extents; 00893 Field<Data_T>::m_dataWindow = extents; 00894 // Tell subclasses that the size changed so they can update themselves. 00895 sizeChanged(); 00896 } 00897 00898 //----------------------------------------------------------------------------// 00899 00900 template <class Data_T> 00901 void ResizableField<Data_T>::setSize(const Box3i &extents, 00902 const Box3i &dataWindow) 00903 { 00904 00905 Field<Data_T>::m_extents = extents; 00906 Field<Data_T>::m_dataWindow = dataWindow; 00907 // Tell subclasses that the size changed so they can update themselves. 00908 sizeChanged(); 00909 } 00910 00911 //----------------------------------------------------------------------------// 00912 00913 template <class Data_T> 00914 void ResizableField<Data_T>::setSize(const V3i &size, int padding) 00915 { 00916 setSize(Box3i(V3i(0), size - V3i(1)), 00917 Box3i(V3i(-padding), 00918 size + V3i(padding - 1))); 00919 } 00920 00921 //----------------------------------------------------------------------------// 00922 00923 template <class Data_T> 00924 void ResizableField<Data_T>::copyFrom(typename Field<Data_T>::Ptr other) 00925 { 00926 // Set mapping 00927 setMapping(other->mapping()); 00928 // Set size to match 00929 setSize(other->extents(), other->dataWindow()); 00930 00931 // Copy over the data 00932 typename base::iterator i = base::begin(); 00933 typename base::iterator end = base::end(); 00934 typename Field<Data_T>::const_iterator c = other->cbegin(); 00935 for (; i != end; ++i, ++c) 00936 *i = *c; 00937 } 00938 00939 //----------------------------------------------------------------------------// 00940 00941 template <class Data_T> 00942 template <class Data_T2> 00943 void ResizableField<Data_T>::copyFrom(typename Field<Data_T2>::Ptr other) 00944 { 00945 // Set mapping 00946 setMapping(other->mapping()); 00947 // Set size to match 00948 setSize(other->extents(), other->dataWindow()); 00949 // Copy over the data 00950 typename base::iterator i = base::begin(); 00951 typename base::iterator end = base::end(); 00952 typename Field<Data_T2>::const_iterator c = other->cbegin(); 00953 for (; i != end; ++i, ++c) 00954 *i = *c; 00955 } 00956 00957 //----------------------------------------------------------------------------// 00958 00959 template <class Data_T> 00960 void ResizableField<Data_T>::matchDefinition(FieldRes::Ptr fieldToMatch) 00961 { 00962 setSize(fieldToMatch->extents(), fieldToMatch->dataWindow()); 00963 FieldRes::setMapping(fieldToMatch->mapping()); 00964 } 00965 00966 //----------------------------------------------------------------------------// 00967 // Field-related utility functions 00968 //----------------------------------------------------------------------------// 00969 00972 template <class Data_T, class Data_T2> 00973 bool sameDefinition(typename Field<Data_T>::Ptr a, 00974 typename Field<Data_T2>::Ptr b) 00975 { 00976 if (a->extents() != b->extents()) { 00977 return false; 00978 } 00979 if (a->dataWindow() != b->dataWindow()) { 00980 return false; 00981 } 00982 if (!a->mapping()->isIdentical(b->mapping())) { 00983 return false; 00984 } 00985 return true; 00986 } 00987 00988 //----------------------------------------------------------------------------// 00989 00992 template <class Data_T> 00993 bool isIdentical(typename Field<Data_T>::Ptr a, typename Field<Data_T>::Ptr b) 00994 { 00995 if (!sameDefinition<Data_T, Data_T>(a, b)) { 00996 return false; 00997 } 00998 // If data window is the same, we can safely assume that the range of 00999 // both fields' iterators are the same. 01000 typename Field<Data_T>::const_iterator is1 = a->cbegin(); 01001 typename Field<Data_T>::const_iterator is2 = b->cbegin(); 01002 typename Field<Data_T>::const_iterator ie1 = a->cend(); 01003 bool same = true; 01004 for (; is1 != ie1; ++is1, ++is2) { 01005 if (*is1 != *is2) { 01006 same = false; 01007 break; 01008 } 01009 } 01010 return same; 01011 } 01012 01013 //----------------------------------------------------------------------------// 01014 01017 inline int contToDisc(double contCoord) 01018 { 01019 return static_cast<int>(std::floor(contCoord)); 01020 } 01021 01022 //----------------------------------------------------------------------------// 01023 01026 inline double discToCont(int discCoord) 01027 { 01028 return static_cast<double>(discCoord) + 0.5; 01029 } 01030 01031 //----------------------------------------------------------------------------// 01032 01034 inline V2i contToDisc(const V2d &contCoord) 01035 { 01036 return V2i(contToDisc(contCoord.x), contToDisc(contCoord.y)); 01037 } 01038 01039 //----------------------------------------------------------------------------// 01040 01042 inline V2d discToCont(const V2i &discCoord) 01043 { 01044 return V2d(discToCont(discCoord.x), discToCont(discCoord.y)); 01045 } 01046 01047 //----------------------------------------------------------------------------// 01048 01050 inline V3i contToDisc(const V3d &contCoord) 01051 { 01052 return V3i(contToDisc(contCoord.x), contToDisc(contCoord.y), 01053 contToDisc(contCoord.z)); 01054 } 01055 01056 //----------------------------------------------------------------------------// 01057 01059 inline V3d discToCont(const V3i &discCoord) 01060 { 01061 return V3d(discToCont(discCoord.x), discToCont(discCoord.y), 01062 discToCont(discCoord.z)); 01063 } 01064 01065 //----------------------------------------------------------------------------// 01066 01068 template <class Iter_T> 01069 void advance(Iter_T &iter, int num) 01070 { 01071 if (num <= 0) return; 01072 for (int i=0; i<num; ++i, ++iter); 01073 } 01074 01075 //----------------------------------------------------------------------------// 01076 01078 template <class Iter_T> 01079 void advance(Iter_T &iter, int num, const Iter_T &end) 01080 { 01081 if (num <= 0) 01082 return; 01083 for (int i=0; i<num && iter != end; ++i, ++iter); 01084 } 01085 01086 //----------------------------------------------------------------------------// 01087 01088 FIELD3D_NAMESPACE_HEADER_CLOSE 01089 01090 //----------------------------------------------------------------------------// 01091 01092 #endif // Include guard 01093