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 00042 //----------------------------------------------------------------------------// 00043 00044 #ifndef _INCLUDED_Field3D_DenseField_H_ 00045 #define _INCLUDED_Field3D_DenseField_H_ 00046 00047 #include <vector> 00048 00049 #include <boost/lexical_cast.hpp> 00050 00051 #include "Field.h" 00052 00053 //----------------------------------------------------------------------------// 00054 00055 #include "ns.h" 00056 00057 FIELD3D_NAMESPACE_OPEN 00058 00059 //----------------------------------------------------------------------------// 00060 // Forward declarations 00061 //----------------------------------------------------------------------------// 00062 00063 template <class Field_T> 00064 class LinearGenericFieldInterp; 00065 template <class Field_T> 00066 class CubicGenericFieldInterp; 00067 00068 //----------------------------------------------------------------------------// 00069 // DenseField 00070 //----------------------------------------------------------------------------// 00071 00079 //----------------------------------------------------------------------------// 00080 00081 template <class Data_T> 00082 class DenseField 00083 : public ResizableField<Data_T> 00084 { 00085 public: 00086 00087 // Typedefs ------------------------------------------------------------------ 00088 00089 typedef boost::intrusive_ptr<DenseField> Ptr; 00090 typedef std::vector<Ptr> Vec; 00091 00092 typedef LinearGenericFieldInterp<DenseField<Data_T> > LinearInterp; 00093 typedef CubicGenericFieldInterp<DenseField<Data_T> > CubicInterp; 00094 00095 typedef ResizableField<Data_T> base; 00096 00097 // Constructors -------------------------------------------------------------- 00098 00101 00103 DenseField(); 00104 00105 // \} 00106 00107 // Main methods -------------------------------------------------------------- 00108 00110 virtual void clear(const Data_T &value); 00111 00112 // From Field base class ----------------------------------------------------- 00113 00116 virtual Data_T value(int i, int j, int k) const; 00117 virtual long long int memSize() const; 00119 00120 // RTTI replacement ---------------------------------------------------------- 00121 00122 typedef DenseField<Data_T> class_type; 00123 DEFINE_FIELD_RTTI_CONCRETE_CLASS 00124 00125 static const char *staticClassName() 00126 { 00127 return "DenseField"; 00128 } 00129 00130 static const char *classType() 00131 { 00132 return DenseField<Data_T>::ms_classType.name(); 00133 } 00134 00135 // From WritableField base class --------------------------------------------- 00136 00139 virtual Data_T& lvalue(int i, int j, int k); 00141 00142 // Concrete voxel access ----------------------------------------------------- 00143 00145 const Data_T& fastValue(int i, int j, int k) const; 00147 Data_T& fastLValue(int i, int j, int k); 00148 00149 // Iterators ----------------------------------------------------------------- 00150 00153 00155 class const_iterator; 00156 00158 class iterator; 00159 00161 const_iterator cbegin() const; 00163 const_iterator cbegin(const Box3i &subset) const; 00165 const_iterator cend() const; 00168 const_iterator cend(const Box3i &subset) const; 00170 iterator begin(); 00172 iterator begin(const Box3i &subset); 00174 iterator end(); 00177 iterator end(const Box3i &subset); 00178 00180 00181 // Utility methods ----------------------------------------------------------- 00182 00186 const FIELD3D_VEC3_T<size_t> &internalMemSize() const 00187 { return m_memSize; } 00188 00189 // From FieldBase ------------------------------------------------------------ 00190 00193 00194 virtual std::string className() const 00195 { return staticClassName(); } 00196 00197 virtual FieldBase::Ptr clone() const 00198 { return Ptr(new DenseField(*this)); } 00199 00201 00202 protected: 00203 00204 // From ResizableField class ------------------------------------------------- 00205 00206 virtual void sizeChanged(); 00207 00208 // Data members -------------------------------------------------------------- 00209 00211 FIELD3D_VEC3_T<size_t> m_memSize; 00213 size_t m_memSizeXY; 00215 std::vector<Data_T> m_data; 00216 00217 private: 00218 00219 // Static data members ------------------------------------------------------- 00220 00221 static TemplatedFieldType<DenseField<Data_T> > ms_classType; 00222 00223 // Direct access to memory for iterators ------------------------------------- 00224 00226 inline Data_T* ptr(int i, int j, int k); 00228 inline const Data_T* ptr(int i, int j, int k) const; 00229 00230 }; 00231 00232 //----------------------------------------------------------------------------// 00233 // Typedefs 00234 //----------------------------------------------------------------------------// 00235 00236 typedef DenseField<half> DenseFieldh; 00237 typedef DenseField<float> DenseFieldf; 00238 typedef DenseField<double> DenseFieldd; 00239 typedef DenseField<V3h> DenseField3h; 00240 typedef DenseField<V3f> DenseField3f; 00241 typedef DenseField<V3d> DenseField3d; 00242 00243 //----------------------------------------------------------------------------// 00244 // DenseField::const_iterator 00245 //----------------------------------------------------------------------------// 00246 00247 template <class Data_T> 00248 class DenseField<Data_T>::const_iterator 00249 { 00250 public: 00251 00252 // Typedefs ------------------------------------------------------------------ 00253 00254 typedef DenseField<Data_T> class_type; 00255 00256 // Constructors -------------------------------------------------------------- 00257 00258 const_iterator(const class_type &field, const Box3i &window, 00259 const V3i ¤tPos) 00260 : x(currentPos.x), y(currentPos.y), z(currentPos.z), 00261 m_window(window), m_field(field) 00262 { m_p = m_field.ptr(x, y, z); } 00263 00264 // Operators ----------------------------------------------------------------- 00265 00266 const const_iterator& operator ++ () 00267 { 00268 if (x == m_window.max.x) { 00269 if (y == m_window.max.y) { 00270 m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z); 00271 } else { 00272 m_p = m_field.ptr(x = m_window.min.x, ++y, z); 00273 } 00274 } else { 00275 ++x; 00276 ++m_p; 00277 } 00278 return *this; 00279 } 00280 00281 template <class Iter_T> 00282 inline bool operator == (const Iter_T &rhs) const 00283 { 00284 return m_p == &(*rhs); 00285 } 00286 00287 template <class Iter_T> 00288 inline bool operator != (const Iter_T &rhs) const 00289 { 00290 return m_p != &(*rhs); 00291 } 00292 00293 inline const Data_T& operator * () const 00294 { 00295 return *m_p; 00296 } 00297 00298 inline const Data_T* operator -> () const 00299 { 00300 return m_p; 00301 } 00302 00303 // Public data members ------------------------------------------------------- 00304 00306 int x, y, z; 00307 00308 private: 00309 00310 // Private data members ------------------------------------------------------ 00311 00313 const Data_T *m_p; 00315 Box3i m_window; 00317 const class_type &m_field; 00318 00319 }; 00320 00321 //----------------------------------------------------------------------------// 00322 // DenseField::iterator 00323 //----------------------------------------------------------------------------// 00324 00325 template <class Data_T> 00326 class DenseField<Data_T>::iterator 00327 { 00328 public: 00329 00330 // Typedefs ------------------------------------------------------------------ 00331 00332 typedef DenseField<Data_T> class_type; 00333 00334 // Constructors -------------------------------------------------------------- 00335 00336 iterator(class_type &field, const Box3i &window, 00337 const V3i ¤tPos) 00338 : x(currentPos.x), y(currentPos.y), z(currentPos.z), 00339 m_window(window), m_field(field) 00340 { m_p = m_field.ptr(x, y, z); } 00341 00342 // Operators ----------------------------------------------------------------- 00343 00344 const iterator& operator ++ () 00345 { 00346 if (x == m_window.max.x) { 00347 if (y == m_window.max.y) { 00348 m_p = m_field.ptr(x = m_window.min.x, y = m_window.min.y, ++z); 00349 } else { 00350 m_p = m_field.ptr(x = m_window.min.x, ++y, z); 00351 } 00352 } else { 00353 ++x; 00354 ++m_p; 00355 } 00356 return *this; 00357 } 00358 00359 template <class Iter_T> 00360 inline bool operator == (const Iter_T &rhs) const 00361 { 00362 return m_p == &(*rhs); 00363 } 00364 00365 template <class Iter_T> 00366 inline bool operator != (const Iter_T &rhs) const 00367 { 00368 return m_p != &(*rhs); 00369 } 00370 00371 inline Data_T& operator * () const 00372 { 00373 return *m_p; 00374 } 00375 00376 inline Data_T* operator -> () const 00377 { 00378 return m_p; 00379 } 00380 00381 // Public data members ------------------------------------------------------- 00382 00384 int x, y, z; 00385 00386 private: 00387 00388 // Private data members ------------------------------------------------------ 00389 00391 Data_T *m_p; 00393 Box3i m_window; 00395 class_type &m_field; 00396 }; 00397 00398 //----------------------------------------------------------------------------// 00399 // DenseField implementations 00400 //----------------------------------------------------------------------------// 00401 00402 template <class Data_T> 00403 DenseField<Data_T>::DenseField() 00404 : base(), 00405 m_memSize(0), m_memSizeXY(0) 00406 { 00407 // Empty 00408 } 00409 00410 //----------------------------------------------------------------------------// 00411 00412 template <class Data_T> 00413 void DenseField<Data_T>::clear(const Data_T &value) 00414 { 00415 std::fill(m_data.begin(), m_data.end(), value); 00416 } 00417 00418 //----------------------------------------------------------------------------// 00419 00420 template <class Data_T> 00421 Data_T DenseField<Data_T>::value(int i, int j, int k) const 00422 { 00423 return fastValue(i, j, k); 00424 } 00425 00426 //----------------------------------------------------------------------------// 00427 00428 template <class Data_T> 00429 long long int DenseField<Data_T>::memSize() const 00430 { 00431 long long int superClassMemSize = base::memSize(); 00432 long long int vectorMemSize = m_data.capacity() * sizeof(Data_T); 00433 return sizeof(*this) + vectorMemSize + superClassMemSize; 00434 } 00435 00436 //----------------------------------------------------------------------------// 00437 00438 template <class Data_T> 00439 Data_T& DenseField<Data_T>::lvalue(int i, int j, int k) 00440 { 00441 return fastLValue(i, j, k); 00442 } 00443 00444 //----------------------------------------------------------------------------// 00445 00446 template <class Data_T> 00447 const Data_T& DenseField<Data_T>::fastValue(int i, int j, int k) const 00448 { 00449 assert (i >= base::m_dataWindow.min.x); 00450 assert (i <= base::m_dataWindow.max.x); 00451 assert (j >= base::m_dataWindow.min.y); 00452 assert (j <= base::m_dataWindow.max.y); 00453 assert (k >= base::m_dataWindow.min.z); 00454 assert (k <= base::m_dataWindow.max.z); 00455 // Add crop window offset 00456 i -= base::m_dataWindow.min.x; 00457 j -= base::m_dataWindow.min.y; 00458 k -= base::m_dataWindow.min.z; 00459 // Access data 00460 return m_data[i + j * m_memSize.x + k * m_memSizeXY]; 00461 } 00462 00463 //----------------------------------------------------------------------------// 00464 00465 template <class Data_T> 00466 Data_T& DenseField<Data_T>::fastLValue(int i, int j, int k) 00467 { 00468 assert (i >= base::m_dataWindow.min.x); 00469 assert (i <= base::m_dataWindow.max.x); 00470 assert (j >= base::m_dataWindow.min.y); 00471 assert (j <= base::m_dataWindow.max.y); 00472 assert (k >= base::m_dataWindow.min.z); 00473 assert (k <= base::m_dataWindow.max.z); 00474 // Add crop window offset 00475 i -= base::m_dataWindow.min.x; 00476 j -= base::m_dataWindow.min.y; 00477 k -= base::m_dataWindow.min.z; 00478 // Access data 00479 return m_data[i + j * m_memSize.x + k * m_memSizeXY]; 00480 } 00481 00482 //----------------------------------------------------------------------------// 00483 00484 template <class Data_T> 00485 typename DenseField<Data_T>::const_iterator 00486 DenseField<Data_T>::cbegin() const 00487 { 00488 if (FieldRes::dataResolution() == V3i(0)) 00489 return cend(); 00490 return const_iterator(*this, base::m_dataWindow, base::m_dataWindow.min); 00491 } 00492 00493 //----------------------------------------------------------------------------// 00494 00495 template <class Data_T> 00496 typename DenseField<Data_T>::const_iterator 00497 DenseField<Data_T>::cbegin(const Box3i &subset) const 00498 { 00499 if (subset.isEmpty()) 00500 return cend(subset); 00501 return const_iterator(*this, subset, subset.min); 00502 } 00503 00504 //----------------------------------------------------------------------------// 00505 00506 template <class Data_T> 00507 typename DenseField<Data_T>::const_iterator 00508 DenseField<Data_T>::cend() const 00509 { 00510 return const_iterator(*this, base::m_dataWindow, 00511 V3i(base::m_dataWindow.min.x, 00512 base::m_dataWindow.min.y, 00513 base::m_dataWindow.max.z + 1)); 00514 } 00515 00516 //----------------------------------------------------------------------------// 00517 00518 template <class Data_T> 00519 typename DenseField<Data_T>::const_iterator 00520 DenseField<Data_T>::cend(const Box3i &subset) const 00521 { 00522 return const_iterator(*this, subset, 00523 V3i(subset.min.x, subset.min.y, subset.max.z + 1)); 00524 } 00525 00526 //----------------------------------------------------------------------------// 00527 00528 template <class Data_T> 00529 typename DenseField<Data_T>::iterator 00530 DenseField<Data_T>::begin() 00531 { 00532 if (FieldRes::dataResolution() == V3i(0)) 00533 return end(); 00534 return iterator(*this, base::m_dataWindow, base::m_dataWindow.min); } 00535 00536 //----------------------------------------------------------------------------// 00537 00538 template <class Data_T> 00539 typename DenseField<Data_T>::iterator 00540 DenseField<Data_T>::begin(const Box3i &subset) 00541 { 00542 if (subset.isEmpty()) 00543 return end(subset); 00544 return iterator(*this, subset, subset.min); 00545 } 00546 00547 //----------------------------------------------------------------------------// 00548 00549 template <class Data_T> 00550 typename DenseField<Data_T>::iterator 00551 DenseField<Data_T>::end() 00552 { 00553 return iterator(*this, base::m_dataWindow, 00554 V3i(base::m_dataWindow.min.x, 00555 base::m_dataWindow.min.y, 00556 base::m_dataWindow.max.z + 1)); 00557 } 00558 00559 //----------------------------------------------------------------------------// 00560 00561 template <class Data_T> 00562 typename DenseField<Data_T>::iterator 00563 DenseField<Data_T>::end(const Box3i &subset) 00564 { 00565 return iterator(*this, subset, 00566 V3i(subset.min.x, subset.min.y, subset.max.z + 1)); 00567 } 00568 00569 //----------------------------------------------------------------------------// 00570 00571 template <class Data_T> 00572 void DenseField<Data_T>::sizeChanged() 00573 { 00574 // Call base class 00575 base::sizeChanged(); 00576 00577 // Calculate offsets 00578 m_memSize = base::m_dataWindow.max - base::m_dataWindow.min + V3i(1); 00579 m_memSizeXY = m_memSize.x * m_memSize.y; 00580 00581 // Check that mem size is >= 0 in all dimensions 00582 if (base::m_dataWindow.max.x < base::m_dataWindow.min.x || 00583 base::m_dataWindow.max.y < base::m_dataWindow.min.y || 00584 base::m_dataWindow.max.z < base::m_dataWindow.min.z) 00585 throw Exc::ResizeException("Attempt to resize ResizableField object " 00586 "using negative size. Data window was: " + 00587 boost::lexical_cast<std::string>( 00588 base::m_dataWindow.min) + " - " + 00589 boost::lexical_cast<std::string>( 00590 base::m_dataWindow.max)); 00591 00592 // Allocate memory 00593 try { 00594 std::vector<Data_T>().swap(m_data); 00595 m_data.resize(m_memSize.x * m_memSize.y * m_memSize.z); 00596 } 00597 catch (std::bad_alloc &e) { 00598 throw Exc::MemoryException("Couldn't allocate DenseField of size " + 00599 boost::lexical_cast<std::string>(m_memSize)); 00600 } 00601 } 00602 00603 //----------------------------------------------------------------------------// 00604 00605 template <class Data_T> 00606 inline Data_T* DenseField<Data_T>::ptr(int i, int j, int k) 00607 { 00608 // Add crop window offset 00609 i -= base::m_dataWindow.min.x; 00610 j -= base::m_dataWindow.min.y; 00611 k -= base::m_dataWindow.min.z; 00612 // Access data 00613 return &m_data[i + j * m_memSize.x + k * m_memSizeXY]; 00614 } 00615 00616 //----------------------------------------------------------------------------// 00617 00618 template <class Data_T> 00619 inline const Data_T* DenseField<Data_T>::ptr(int i, int j, int k) const 00620 { 00621 // Add crop window offset 00622 i -= base::m_dataWindow.min.x; 00623 j -= base::m_dataWindow.min.y; 00624 k -= base::m_dataWindow.min.z; 00625 // Access data 00626 return &m_data[i + j * m_memSize.x + k * m_memSizeXY]; 00627 } 00628 00629 //----------------------------------------------------------------------------// 00630 // Static data member instantiation 00631 //----------------------------------------------------------------------------// 00632 00633 FIELD3D_CLASSTYPE_TEMPL_INSTANTIATION(DenseField); 00634 00635 //----------------------------------------------------------------------------// 00636 00637 FIELD3D_NAMESPACE_HEADER_CLOSE 00638 00639 //----------------------------------------------------------------------------// 00640 00641 #endif // Include guard