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 // Exceptions 00071 //----------------------------------------------------------------------------// 00072 00073 namespace Exc { 00074 00075 DECLARE_FIELD3D_GENERIC_EXCEPTION(MemoryException, Exception) 00076 DECLARE_FIELD3D_GENERIC_EXCEPTION(ResizeException, Exception) 00077 00078 } // namespace Exc 00079 00080 //----------------------------------------------------------------------------// 00081 // FieldBase 00082 //----------------------------------------------------------------------------// 00083 00091 class FieldBase : public RefBase 00092 { 00093 public: 00094 00095 // Typedefs ------------------------------------------------------------------ 00096 00097 typedef boost::intrusive_ptr<FieldBase> Ptr; 00098 typedef FieldBase class_type; 00099 00100 // Constructors -------------------------------------------------------------- 00101 00104 00106 FieldBase(); 00107 00109 FieldBase(const FieldBase &); 00110 00112 virtual ~FieldBase(); 00113 00115 00116 // RTTI replacement ---------------------------------------------------------- 00117 00118 static const char *staticClassName() 00119 { 00120 return "FieldBase"; 00121 } 00122 00123 static const char* classType() 00124 { 00125 return staticClassName(); 00126 } 00127 00128 // To be implemented by subclasses ------------------------------------------- 00129 00132 00138 virtual std::string className() const = 0; 00139 00142 virtual Ptr clone() const = 0; 00143 00145 00146 // Access to metadata -------------------------------------------------------- 00147 00150 00152 FieldMetadata<FieldBase>& metadata() 00153 { return m_metadata; } 00154 00156 const FieldMetadata<FieldBase>& metadata() const 00157 { return m_metadata; } 00158 00161 virtual void metadataHasChanged(const std::string &/* name */) 00162 { /* Empty */ } 00163 00165 void copyMetadata(const FieldBase &field) 00166 { m_metadata = field.metadata(); } 00167 00169 00170 // Public data members ------------------------------------------------------- 00171 00173 std::string name; 00175 std::string attribute; 00176 00177 private: 00178 00179 // Private data members ------------------------------------------------------ 00180 00182 FieldMetadata<FieldBase> m_metadata; 00183 00184 }; 00185 00186 //----------------------------------------------------------------------------// 00187 // FieldRes 00188 //----------------------------------------------------------------------------// 00189 00207 //----------------------------------------------------------------------------// 00208 00209 class FieldRes : public FieldBase 00210 { 00211 public: 00212 00213 // Typedefs ------------------------------------------------------------------ 00214 00215 typedef boost::intrusive_ptr<FieldRes> Ptr; 00216 typedef std::vector<Ptr> Vec; 00217 00218 // RTTI replacement ---------------------------------------------------------- 00219 00220 typedef FieldRes class_type; 00221 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00222 00223 virtual std::string dataTypeString() const 00224 { return std::string("FieldRes"); } 00225 00226 static const char *staticClassName() 00227 { 00228 return "FieldRes"; 00229 } 00230 00231 static const char *classType() 00232 { 00233 return staticClassName(); 00234 } 00235 00236 // Ctor, dtor ---------------------------------------------------------------- 00237 00239 FieldRes(); 00240 00243 FieldRes(const FieldRes &src); 00244 00245 // Main methods -------------------------------------------------------------- 00246 00251 inline const Box3i& extents() const 00252 { return m_extents; } 00255 inline const Box3i& dataWindow() const 00256 { return m_dataWindow; } 00257 00258 inline V3i const dataResolution() const 00259 { return m_dataWindow.max - m_dataWindow.min + V3i(1); } 00260 00262 void setMapping(FieldMapping::Ptr mapping); 00263 00265 FieldMapping::Ptr mapping() 00266 { return m_mapping; } 00267 00269 const FieldMapping::Ptr mapping() const 00270 { return m_mapping; } 00271 00273 bool isInBounds(int i, int j, int k) const; 00274 00275 // To be implemented by subclasses ------------------------------------------- 00276 00281 virtual long long int memSize() const 00282 { return sizeof(*this); } 00283 00284 protected: 00285 00286 // Typedefs ------------------------------------------------------------------ 00287 00288 typedef MatrixFieldMapping default_mapping; 00289 00290 // Data members -------------------------------------------------------------- 00291 00296 Box3i m_extents; 00299 Box3i m_dataWindow; 00301 FieldMapping::Ptr m_mapping; 00302 00303 private: 00304 00305 // Typedefs ------------------------------------------------------------------ 00306 00308 typedef FieldBase base; 00309 00310 }; 00311 00312 //----------------------------------------------------------------------------// 00313 00314 inline FieldRes::FieldRes() 00315 : m_mapping(new default_mapping) 00316 { 00317 m_extents = Box3i(V3i(0), V3i(-1)); 00318 m_dataWindow = m_extents; 00319 m_mapping->setExtents(m_extents); 00320 } 00321 00322 //----------------------------------------------------------------------------// 00323 00324 inline FieldRes::FieldRes(const FieldRes &src) 00325 : FieldBase(src) 00326 { 00327 // Call base class first 00328 // FieldBase(src); 00329 // Copy self 00330 *this = src; 00331 m_mapping = src.mapping()->clone(); 00332 } 00333 00334 //----------------------------------------------------------------------------// 00335 00336 inline void FieldRes::setMapping(FieldMapping::Ptr mapping) 00337 { 00338 if (mapping) { 00339 m_mapping = mapping->clone(); 00340 m_mapping->setExtents(m_extents); 00341 } else { 00342 Msg::print(Msg::SevWarning, 00343 "Tried to call FieldRes::setMapping with null pointer"); 00344 } 00345 } 00346 00347 //----------------------------------------------------------------------------// 00348 00349 inline bool FieldRes::isInBounds(int i, int j, int k) const 00350 { 00351 // Check bounds 00352 if (i < m_dataWindow.min.x || i > m_dataWindow.max.x || 00353 j < m_dataWindow.min.y || j > m_dataWindow.max.y || 00354 k < m_dataWindow.min.z || k > m_dataWindow.max.z) { 00355 return false; 00356 } 00357 00358 return true; 00359 } 00360 00361 //----------------------------------------------------------------------------// 00362 // Field 00363 //----------------------------------------------------------------------------// 00364 00375 template <class Data_T> 00376 class Field : public FieldRes 00377 { 00378 public: 00379 00380 // Typedefs ------------------------------------------------------------------ 00381 00382 typedef boost::intrusive_ptr<Field> Ptr; 00383 00385 typedef Data_T value_type; 00386 00390 typedef std::vector<Ptr> Vec; 00391 00392 // RTTI replacement ---------------------------------------------------------- 00393 00394 typedef Field<Data_T> class_type; 00395 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00396 00397 static const char *staticClassName() 00398 { 00399 return "Field"; 00400 } 00401 00402 static const char* classType() 00403 { 00404 return Field<Data_T>::ms_classType.name(); 00405 } 00406 00407 // Constructors -------------------------------------------------------------- 00408 00410 virtual ~Field() 00411 { /* Empty */ } 00412 00413 // Iterators ----------------------------------------------------------------- 00414 00417 class const_iterator; 00418 00420 const_iterator cbegin() const; 00422 const_iterator cbegin(const Box3i &subset) const; 00424 const_iterator cend() const; 00427 const_iterator cend(const Box3i &subset) const; 00428 00429 // To be implemented by subclasses ------------------------------------------- 00430 00437 virtual Data_T value(int i, int j, int k) const = 0; 00438 00439 // Other member functions ---------------------------------------------------- 00440 00441 virtual std::string dataTypeString() const 00442 { return DataTypeTraits<Data_T>::name(); } 00443 00444 00445 private: 00446 00447 // Static data members ------------------------------------------------------- 00448 00449 static TemplatedFieldType<Field<Data_T> > ms_classType; 00450 00451 // Typedefs ------------------------------------------------------------------ 00452 00454 typedef FieldRes base; 00455 00456 }; 00457 00458 //----------------------------------------------------------------------------// 00459 00460 #define FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(field) \ 00461 template <typename Data_T> \ 00462 TemplatedFieldType<field<Data_T> > field<Data_T>::ms_classType = \ 00463 TemplatedFieldType<field<Data_T> >(); \ 00464 00465 FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(Field); 00466 00467 //----------------------------------------------------------------------------// 00468 00469 template <class Data_T> 00470 typename Field<Data_T>::const_iterator 00471 Field<Data_T>::cbegin() const 00472 { 00473 if (FieldRes::dataResolution() == V3i(0)) 00474 return cend(); 00475 return const_iterator(*this, m_dataWindow, m_dataWindow.min); 00476 } 00477 00478 //----------------------------------------------------------------------------// 00479 00480 template <class Data_T> 00481 typename Field<Data_T>::const_iterator 00482 Field<Data_T>::cbegin(const Box3i &subset) const 00483 { 00484 if (subset.isEmpty()) 00485 return cend(subset); 00486 return const_iterator(*this, subset, subset.min); 00487 } 00488 00489 //----------------------------------------------------------------------------// 00490 00491 template <class Data_T> 00492 typename Field<Data_T>::const_iterator 00493 Field<Data_T>::cend() const 00494 { 00495 return const_iterator(*this, m_dataWindow, 00496 V3i(m_dataWindow.min.x, 00497 m_dataWindow.min.y, 00498 m_dataWindow.max.z + 1)); 00499 } 00500 00501 //----------------------------------------------------------------------------// 00502 00503 template <class Data_T> 00504 typename Field<Data_T>::const_iterator 00505 Field<Data_T>::cend(const Box3i &subset) const 00506 { 00507 return const_iterator(*this, subset, V3i(subset.min.x, 00508 subset.min.y, 00509 subset.max.z + 1)); 00510 } 00511 00512 //----------------------------------------------------------------------------// 00513 // Field::const_iterator 00514 //----------------------------------------------------------------------------// 00515 00516 template <class Data_T> 00517 class Field<Data_T>::const_iterator 00518 { 00519 00520 public: 00521 00522 // Constructors -------------------------------------------------------------- 00523 00524 const_iterator(const const_iterator &i) 00525 : x(i.x), y(i.y), z(i.z), 00526 m_window(i.m_window), m_field(i.m_field) 00527 { } 00528 00529 const_iterator(const Field<Data_T> &field, const Box3i &window, 00530 const V3i ¤tPos) 00531 : x(currentPos.x), y(currentPos.y), z(currentPos.z), 00532 m_window(window), m_field(field) 00533 { } 00534 00535 // Operators ----------------------------------------------------------------- 00536 00537 inline const const_iterator& operator ++ () 00538 { 00539 if (x == m_window.max.x) { 00540 if (y == m_window.max.y) { 00541 x = m_window.min.x; 00542 y = m_window.min.y; 00543 ++z; 00544 } else { 00545 x = m_window.min.x; 00546 ++y; 00547 } 00548 } else { 00549 ++x; 00550 } 00551 return *this; 00552 } 00553 template <class Iter_T> 00554 bool operator == (const Iter_T &rhs) const 00555 { 00556 return x == rhs.x && y == rhs.y && z == rhs.z; 00557 } 00558 template <class Iter_T> 00559 bool operator != (const Iter_T &rhs) const 00560 { 00561 return x != rhs.x || y != rhs.y || z != rhs.z; 00562 } 00563 inline Data_T operator * () const 00564 { 00565 return m_field.value(x, y, z); 00566 } 00567 // Public data members ------------------------------------------------------- 00568 00570 int x, y, z; 00571 00572 private: 00573 00574 // Private data members ------------------------------------------------------ 00575 00577 Box3i m_window; 00579 const Field<Data_T> &m_field; 00580 00581 }; 00582 00583 //----------------------------------------------------------------------------// 00584 // WritableField 00585 //----------------------------------------------------------------------------// 00586 00593 //----------------------------------------------------------------------------// 00594 00595 template <class Data_T> 00596 class WritableField 00597 : public Field<Data_T> 00598 { 00599 public: 00600 00601 // Typedefs ------------------------------------------------------------------ 00602 00603 typedef boost::intrusive_ptr<WritableField> Ptr; 00604 00605 // RTTI replacement ---------------------------------------------------------- 00606 00607 typedef WritableField<Data_T> class_type; 00608 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00609 00610 static const char *staticClassName() 00611 { 00612 return "WritableField"; 00613 } 00614 00615 static const char* classType() 00616 { 00617 return WritableField<Data_T>::ms_classType.name(); 00618 } 00619 00620 // Iterators ----------------------------------------------------------------- 00621 00624 class iterator; 00625 00627 inline iterator begin(); 00629 inline iterator begin(const Box3i &subset); 00631 inline iterator end(); 00634 inline iterator end(const Box3i &subset); 00635 00636 // To be implemented by subclasses ------------------------------------------- 00637 00646 virtual Data_T& lvalue(int i, int j, int k) = 0; 00647 00648 // Main methods -------------------------------------------------------------- 00649 00652 virtual void clear(const Data_T &value) 00653 { std::fill(begin(), end(), value); } 00654 00655 private: 00656 00657 // Static data members ------------------------------------------------------- 00658 00659 static TemplatedFieldType<WritableField<Data_T> > ms_classType; 00660 00661 // Typedefs ------------------------------------------------------------------ 00662 00663 typedef Field<Data_T> base; 00664 00665 }; 00666 00667 //----------------------------------------------------------------------------// 00668 00669 FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(WritableField); 00670 00671 //----------------------------------------------------------------------------// 00672 00673 template <class Data_T> 00674 inline typename WritableField<Data_T>::iterator 00675 WritableField<Data_T>::begin() 00676 { 00677 if (FieldRes::dataResolution() == V3i(0)) 00678 return end(); 00679 return iterator(*this, Field<Data_T>::m_dataWindow, 00680 Field<Data_T>::m_dataWindow.min); 00681 } 00682 00683 //----------------------------------------------------------------------------// 00684 00685 template <class Data_T> 00686 inline typename WritableField<Data_T>::iterator 00687 WritableField<Data_T>::begin(const Box3i &subset) 00688 { 00689 if (subset.isEmpty()) 00690 return end(subset); 00691 return iterator(*this, subset, subset.min); 00692 } 00693 00694 //----------------------------------------------------------------------------// 00695 00696 template <class Data_T> 00697 inline typename WritableField<Data_T>::iterator 00698 WritableField<Data_T>::end() 00699 { return iterator(*this, Field<Data_T>::m_dataWindow, 00700 V3i(Field<Data_T>::m_dataWindow.min.x, 00701 Field<Data_T>::m_dataWindow.min.y, 00702 Field<Data_T>::m_dataWindow.max.z + 1)); 00703 } 00704 00705 //----------------------------------------------------------------------------// 00706 00707 template <class Data_T> 00708 inline typename WritableField<Data_T>::iterator 00709 WritableField<Data_T>::end(const Box3i &subset) 00710 { return iterator(*this, subset, 00711 V3i(subset.min.x, subset.min.y, subset.max.z + 1)); 00712 } 00713 00714 //----------------------------------------------------------------------------// 00715 // WritableField::iterator 00716 //----------------------------------------------------------------------------// 00717 00718 template <class Data_T> 00719 class WritableField<Data_T>::iterator 00720 { 00721 public: 00722 00723 // Constructors -------------------------------------------------------------- 00724 00725 iterator(WritableField<Data_T> &field, const Box3i &window, 00726 const V3i ¤tPos) 00727 : x(currentPos.x), y(currentPos.y), z(currentPos.z), 00728 m_window(window), m_field(field) 00729 { } 00730 00731 // Operators ----------------------------------------------------------------- 00732 00733 inline const iterator& operator ++ () 00734 { 00735 if (x == m_window.max.x) { 00736 if (y == m_window.max.y) { 00737 x = m_window.min.x; 00738 y = m_window.min.y; 00739 ++z; 00740 } else { 00741 x = m_window.min.x; 00742 ++y; 00743 } 00744 } else { 00745 ++x; 00746 } 00747 return *this; 00748 } 00749 00750 template <class Iter_T> 00751 bool operator == (const Iter_T &rhs) const 00752 { 00753 return x == rhs.x && y == rhs.y && z == rhs.z; 00754 } 00755 00756 template <class Iter_T> 00757 bool operator != (const Iter_T &rhs) const 00758 { 00759 return x != rhs.x || y != rhs.y || z != rhs.z; 00760 } 00761 00762 inline Data_T& operator * () const 00763 { 00764 return m_field.lvalue(x, y, z); 00765 } 00766 00767 // Public data members ------------------------------------------------------- 00768 00770 int x, y, z; 00771 00772 private: 00773 00774 // Private data members ------------------------------------------------------ 00775 00777 Box3i m_window; 00779 WritableField<Data_T> &m_field; 00780 00781 }; 00782 00783 //----------------------------------------------------------------------------// 00784 // ResizableField 00785 //----------------------------------------------------------------------------// 00786 00795 //----------------------------------------------------------------------------// 00796 00797 template <class Data_T> 00798 class ResizableField 00799 : public WritableField<Data_T> 00800 { 00801 public: 00802 00803 // Typedefs ------------------------------------------------------------------ 00804 00805 typedef boost::intrusive_ptr<ResizableField> Ptr; 00806 00807 // RTTI replacement ---------------------------------------------------------- 00808 00809 typedef ResizableField<Data_T> class_type; 00810 DEFINE_FIELD_RTTI_ABSTRACT_CLASS; 00811 00812 static const char *staticClassName() 00813 { 00814 return "ResizableField"; 00815 } 00816 00817 static const char* classType() 00818 { 00819 return ResizableField<Data_T>::ms_classType.name(); 00820 } 00821 00822 // Main methods -------------------------------------------------------------- 00823 00827 void setSize(const V3i &size); 00831 void setSize(const Box3i &extents); 00835 void setSize(const Box3i &extents, const Box3i &dataWindow); 00839 void setSize(const V3i &size, int padding); 00840 00842 void copyFrom(typename Field<Data_T>::Ptr other); 00845 template <class Data_T2> 00846 void copyFrom(typename Field<Data_T2>::Ptr other); 00847 00849 void matchDefinition(FieldRes::Ptr fieldToMatch); 00850 00851 protected: 00852 00853 // Static data members ------------------------------------------------------- 00854 00855 static TemplatedFieldType<ResizableField<Data_T> > ms_classType; 00856 00857 // Typedefs ------------------------------------------------------------------ 00858 00859 typedef WritableField<Data_T> base; 00860 00861 // To be implemented by subclasses ------------------------------------------- 00862 00866 virtual void sizeChanged() 00867 { base::m_mapping->setExtents(base::m_extents); } 00868 00869 }; 00870 00871 //----------------------------------------------------------------------------// 00872 00873 FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(ResizableField); 00874 00875 //----------------------------------------------------------------------------// 00876 00877 template <class Data_T> 00878 void ResizableField<Data_T>::setSize(const V3i &size) 00879 { 00880 Field<Data_T>::m_extents.min = V3i(0); 00881 Field<Data_T>::m_extents.max = size - V3i(1); 00882 Field<Data_T>::m_dataWindow = Field<Data_T>::m_extents; 00883 00884 // Tell subclasses that the size changed so they can update themselves. 00885 sizeChanged(); 00886 } 00887 00888 //----------------------------------------------------------------------------// 00889 00890 template <class Data_T> 00891 void ResizableField<Data_T>::setSize(const Box3i &extents) 00892 { 00893 Field<Data_T>::m_extents = extents; 00894 Field<Data_T>::m_dataWindow = extents; 00895 // Tell subclasses that the size changed so they can update themselves. 00896 sizeChanged(); 00897 } 00898 00899 //----------------------------------------------------------------------------// 00900 00901 template <class Data_T> 00902 void ResizableField<Data_T>::setSize(const Box3i &extents, 00903 const Box3i &dataWindow) 00904 { 00905 00906 Field<Data_T>::m_extents = extents; 00907 Field<Data_T>::m_dataWindow = dataWindow; 00908 // Tell subclasses that the size changed so they can update themselves. 00909 sizeChanged(); 00910 } 00911 00912 //----------------------------------------------------------------------------// 00913 00914 template <class Data_T> 00915 void ResizableField<Data_T>::setSize(const V3i &size, int padding) 00916 { 00917 setSize(Box3i(V3i(0), size - V3i(1)), 00918 Box3i(V3i(-padding), 00919 size + V3i(padding - 1))); 00920 } 00921 00922 //----------------------------------------------------------------------------// 00923 00924 template <class Data_T> 00925 void ResizableField<Data_T>::copyFrom(typename Field<Data_T>::Ptr other) 00926 { 00927 // Set mapping 00928 FieldRes::setMapping(other->mapping()); 00929 // Set size to match 00930 setSize(other->extents(), other->dataWindow()); 00931 00932 // Copy over the data 00933 typename base::iterator i = base::begin(); 00934 typename base::iterator end = base::end(); 00935 typename Field<Data_T>::const_iterator c = other->cbegin(); 00936 for (; i != end; ++i, ++c) 00937 *i = *c; 00938 } 00939 00940 //----------------------------------------------------------------------------// 00941 00942 template <class Data_T> 00943 template <class Data_T2> 00944 void ResizableField<Data_T>::copyFrom(typename Field<Data_T2>::Ptr other) 00945 { 00946 // Set mapping 00947 setMapping(other->mapping()); 00948 // Set size to match 00949 setSize(other->extents(), other->dataWindow()); 00950 // Copy over the data 00951 typename base::iterator i = base::begin(); 00952 typename base::iterator end = base::end(); 00953 typename Field<Data_T2>::const_iterator c = other->cbegin(); 00954 for (; i != end; ++i, ++c) 00955 *i = *c; 00956 } 00957 00958 //----------------------------------------------------------------------------// 00959 00960 template <class Data_T> 00961 void ResizableField<Data_T>::matchDefinition(FieldRes::Ptr fieldToMatch) 00962 { 00963 setSize(fieldToMatch->extents(), fieldToMatch->dataWindow()); 00964 FieldRes::setMapping(fieldToMatch->mapping()); 00965 } 00966 00967 //----------------------------------------------------------------------------// 00968 // Field-related utility functions 00969 //----------------------------------------------------------------------------// 00970 00973 template <class Data_T, class Data_T2> 00974 bool sameDefinition(typename Field<Data_T>::Ptr a, 00975 typename Field<Data_T2>::Ptr b) 00976 { 00977 if (a->extents() != b->extents()) { 00978 return false; 00979 } 00980 if (a->dataWindow() != b->dataWindow()) { 00981 return false; 00982 } 00983 if (!a->mapping()->isIdentical(b->mapping())) { 00984 return false; 00985 } 00986 return true; 00987 } 00988 00989 //----------------------------------------------------------------------------// 00990 00993 template <class Data_T> 00994 bool isIdentical(typename Field<Data_T>::Ptr a, typename Field<Data_T>::Ptr b) 00995 { 00996 if (!sameDefinition<Data_T, Data_T>(a, b)) { 00997 return false; 00998 } 00999 // If data window is the same, we can safely assume that the range of 01000 // both fields' iterators are the same. 01001 typename Field<Data_T>::const_iterator is1 = a->cbegin(); 01002 typename Field<Data_T>::const_iterator is2 = b->cbegin(); 01003 typename Field<Data_T>::const_iterator ie1 = a->cend(); 01004 bool same = true; 01005 for (; is1 != ie1; ++is1, ++is2) { 01006 if (*is1 != *is2) { 01007 same = false; 01008 break; 01009 } 01010 } 01011 return same; 01012 } 01013 01014 //----------------------------------------------------------------------------// 01015 01018 inline int contToDisc(double contCoord) 01019 { 01020 return static_cast<int>(std::floor(contCoord)); 01021 } 01022 01023 //----------------------------------------------------------------------------// 01024 01027 inline double discToCont(int discCoord) 01028 { 01029 return static_cast<double>(discCoord) + 0.5; 01030 } 01031 01032 //----------------------------------------------------------------------------// 01033 01035 inline V2i contToDisc(const V2d &contCoord) 01036 { 01037 return V2i(contToDisc(contCoord.x), contToDisc(contCoord.y)); 01038 } 01039 01040 //----------------------------------------------------------------------------// 01041 01043 inline V2d discToCont(const V2i &discCoord) 01044 { 01045 return V2d(discToCont(discCoord.x), discToCont(discCoord.y)); 01046 } 01047 01048 //----------------------------------------------------------------------------// 01049 01051 inline V3i contToDisc(const V3d &contCoord) 01052 { 01053 return V3i(contToDisc(contCoord.x), contToDisc(contCoord.y), 01054 contToDisc(contCoord.z)); 01055 } 01056 01057 //----------------------------------------------------------------------------// 01058 01060 inline V3d discToCont(const V3i &discCoord) 01061 { 01062 return V3d(discToCont(discCoord.x), discToCont(discCoord.y), 01063 discToCont(discCoord.z)); 01064 } 01065 01066 //----------------------------------------------------------------------------// 01067 01069 template <class Iter_T> 01070 void advance(Iter_T &iter, int num) 01071 { 01072 if (num <= 0) return; 01073 for (int i=0; i<num; ++i, ++iter); 01074 } 01075 01076 //----------------------------------------------------------------------------// 01077 01079 template <class Iter_T> 01080 void advance(Iter_T &iter, int num, const Iter_T &end) 01081 { 01082 if (num <= 0) 01083 return; 01084 for (int i=0; i<num && iter != end; ++i, ++iter); 01085 } 01086 01087 //----------------------------------------------------------------------------// 01088 01089 FIELD3D_NAMESPACE_HEADER_CLOSE 01090 01091 //----------------------------------------------------------------------------// 01092 01093 #endif // Include guard 01094