Field3D
MACFieldUtil.h
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
43 //----------------------------------------------------------------------------//
44 
45 #ifndef _INCLUDED_Field3D_MACFieldUtil_H_
46 #define _INCLUDED_Field3D_MACFieldUtil_H_
47 
48 #include "MACField.h"
49 
50 //----------------------------------------------------------------------------//
51 
52 #include "ns.h"
53 
55 
56 //----------------------------------------------------------------------------//
57 // Utility functions
58 //----------------------------------------------------------------------------//
59 
61 template <class Data_T, class Field_T>
63  typename Field_T::Ptr cc);
64 
65 //----------------------------------------------------------------------------//
66 
68 template <class Field_T, class Data_T>
69 void convertCellCenteredToMAC(typename Field_T::Ptr cc,
70  typename MACField<Data_T>::Ptr mac);
71 
72 //----------------------------------------------------------------------------//
73 // Implementations
74 //----------------------------------------------------------------------------//
75 
77 template <class Data_T, class Field_T>
79  typename Field_T::Ptr cc)
80 {
81  // Make sure the extents and data window match
82  if (cc->extents().min != mac->extents().min ||
83  cc->extents().max != mac->extents().max ||
84  cc->dataWindow().min != mac->dataWindow().min ||
85  cc->dataWindow().max != mac->dataWindow().max ) {
86  cc->setSize(mac->extents(), mac->dataWindow());
87  }
88 
89  // Make sure mapping matches
90  if (!cc->mapping()->isIdentical(mac->mapping())) {
91  cc->setMapping(mac->mapping());
92  }
93 
94  // MAC velocities are in simulation space (axis-aligned to the
95  // mapping) because the values are stored on the faces, so rotate
96  // vectors from simulation-space to world-space when transferring
97  // from MAC to cell-centered
98 
99  bool rotateVector = false;
100  M44d ssToWsMtx;
101  MatrixFieldMapping::Ptr mapping =
102  FIELD_DYNAMIC_CAST<MatrixFieldMapping>(mac->mapping());
103  if (mapping) {
104  M44d localToWorldMtx = mapping->localToWorld();
105  V3d scale, rot, trans, shear;
106  if (extractSHRT(localToWorldMtx, scale, shear, rot, trans, false)) {
107  ssToWsMtx.rotate(rot);
108  if (rot.length2() > FLT_EPSILON)
109  rotateVector = true;
110  }
111  }
112 
113  // Loop over all the voxels in the output field ---
114 
115  typename Field_T::iterator i = cc->begin();
116  typename Field_T::iterator end = cc->end();
117 
118  if (rotateVector) {
119  for (; i != end; ++i) {
120  *i = mac->value(i.x, i.y, i.z) * ssToWsMtx;
121  }
122  } else {
123  for (; i != end; ++i) {
124  *i = mac->value(i.x, i.y, i.z);
125  }
126  }
127 }
128 
129 //----------------------------------------------------------------------------//
130 
131 template <class Field_T, class Data_T>
132 void convertCellCenteredToMAC(typename Field_T::Ptr cc,
133  typename MACField<Data_T>::Ptr mac)
134 {
135  // Make sure the extents and data window match
136  if (mac->extents().min != cc->extents().min ||
137  mac->extents().max != cc->extents().max ||
138  mac->dataWindow().min != cc->dataWindow().min ||
139  mac->dataWindow().max != cc->dataWindow().max ) {
140  mac->setSize(cc->extents(), cc->dataWindow());
141  }
142 
143  // Make sure mapping matches
144  if (!mac->mapping()->isIdentical(cc->mapping())) {
145  mac->setMapping(cc->mapping());
146  }
147 
148  Box3i data = mac->dataWindow();
149 
150  // MAC velocities are in simulation space (axis-aligned to the
151  // mapping) because the values are stored on the faces, so rotate
152  // vectors from world-space to simulation-space when transferring
153  // from cell-centered to MAC
154 
155  bool rotateVector = false;
156  M44d wsToSsMtx;
157  MatrixFieldMapping::Ptr mapping =
158  FIELD_DYNAMIC_CAST<MatrixFieldMapping>(mac->mapping());
159  if (mapping) {
160  M44d localToWorld = mapping->localToWorld();
161  V3d scale, rot, trans, shear;
162  if (FIELD3D_EXTRACT_SHRT(localToWorld, scale, shear, rot, trans, false)) {
163  wsToSsMtx.rotate(-rot);
164  rotateVector = true;
165  }
166  }
167 
168  // Use a pointer to a field below so we can substitute it out for
169  // our intermediate, rotated field if necessary, without needing to
170  // duplicate the loops. This should be more efficient CPU-wise so
171  // we don't need to do 3 matrix multiplies per cell-centered voxel
172  // because it's used in 3 separate loops (1 per MAC face).
173  typename Field_T::Ptr src = cc;
174 
175  typename Field_T::Ptr ccRotated;
176  if (rotateVector) {
177  ccRotated =
178  typename Field_T::Ptr(new Field_T);
179  ccRotated->matchDefinition(cc);
180 
181  typename Field_T::const_iterator iIn = cc->cbegin();
182  typename Field_T::const_iterator endIn = cc->cend();
183  typename Field_T::iterator iOut = ccRotated->begin();
184 
185  for (; iIn != endIn; ++iIn, ++iOut) {
186  *iOut = *iIn * wsToSsMtx;
187  }
188  src = ccRotated;
189  }
190 
191  // Set the u edge value to their closest voxel
192  for (int k = data.min.z; k <= data.max.z; k++) {
193  for (int j = data.min.y; j <= data.max.y; j++) {
194  mac->u(data.min.x, j, k) = src->value(data.min.x, j, k).x;
195  mac->u(data.max.x + 1, j, k) = src->value(data.max.x, j, k).x;
196  }
197  }
198 
199  // Set the v edge value to their closest voxel
200  for (int k = data.min.z; k <= data.max.z; k++) {
201  for (int i = data.min.x; i <= data.max.x; i++) {
202  mac->v(i, data.min.y, k) = src->value(i, data.min.y, k).y;
203  mac->v(i, data.max.y + 1, k) = src->value(i, data.max.y, k).y;
204  }
205  }
206 
207  // Set the w edge value to their closest voxel
208  for (int j = data.min.y; j <= data.max.y; j++) {
209  for (int i = data.min.x; i <= data.max.x; i++) {
210  mac->w(i, j, data.min.z) = src->value(i, j, data.min.z).z;
211  mac->w(i, j, data.max.z + 1) = src->value(i, j, data.max.z).z;
212  }
213  }
214 
215  // Loop over internal u values
216  for (int k = data.min.z; k <= data.max.z; ++k) {
217  for (int j = data.min.y; j <= data.max.y; ++j) {
218  for (int i = data.min.x + 1; i <= data.max.x; ++i) {
219  mac->u(i, j, k) =
220  (src->value(i, j, k).x + src->value(i - 1, j, k).x) * 0.5;
221  }
222  }
223  }
224 
225  // Loop over internal v values
226  for (int k = data.min.z; k <= data.max.z; ++k) {
227  for (int j = data.min.y + 1; j <= data.max.y; ++j) {
228  for (int i = data.min.x; i <= data.max.x; ++i) {
229  mac->v(i, j, k) =
230  (src->value(i, j, k).y + src->value(i, j - 1, k).y) * 0.5;
231  }
232  }
233  }
234 
235  // Loop over internal w values
236  for (int k = data.min.z + 1; k <= data.max.z; ++k) {
237  for (int j = data.min.y; j <= data.max.y; ++j) {
238  for (int i = data.min.x; i <= data.max.x; ++i) {
239  mac->w(i, j, k) =
240  (src->value(i, j, k).z + src->value(i, j, k - 1).z) * 0.5;
241  }
242  }
243  }
244 }
245 
246 //----------------------------------------------------------------------------//
247 
249 
250 //----------------------------------------------------------------------------//
251 
252 #endif // Include guard
#define FIELD3D_NAMESPACE_HEADER_CLOSE
Definition: ns.h:58
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
void convertCellCenteredToMAC(typename Field_T::Ptr cc, typename MACField< Data_T >::Ptr mac)
Converts the cell-centered field to a MAC field.
Definition: MACFieldUtil.h:132
Imath::M44d M44d
Definition: SpiMathLib.h:82
const Box3i & extents() const
Returns the extents of the data. This signifies the relevant area that the data exists over...
Definition: Field.h:254
Contains the MACField class.
const real_t & v(int i, int j, int k) const
Read access to value on v-facing wall.
Definition: MACField.h:736
const real_t & u(int i, int j, int k) const
Read access to value on u-facing wall.
Definition: MACField.h:698
FIELD3D_NAMESPACE_OPEN void convertMACToCellCentered(typename MACField< Data_T >::Ptr mac, typename Field_T::Ptr cc)
Converts the MAC field to a cell-centered field.
Definition: MACFieldUtil.h:78
virtual Data_T value(int i, int j, int k) const
Definition: MACField.h:630
const real_t & w(int i, int j, int k) const
Read access to value on w-facing wall.
Definition: MACField.h:774
void setSize(const V3i &size)
Resizes the object.
Definition: Field.h:918
boost::intrusive_ptr< MACField > Ptr
Definition: MACField.h:101
void setMapping(FieldMapping::Ptr mapping)
Sets the field&#39;s mapping.
Definition: Field.h:352
Imath::V3d V3d
Definition: SpiMathLib.h:74
#define FIELD3D_EXTRACT_SHRT
Definition: SpiMathLib.h:93
const Box3i & dataWindow() const
Returns the data window. Any coordinate inside this window is safe to pass to value() in the Field su...
Definition: Field.h:258
boost::intrusive_ptr< MatrixFieldMapping > Ptr
Convenience typedef.
Definition: FieldMapping.h:334
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Definition: Field.h:268