HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SIM_FieldUtils.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: SIM_FieldUtils.h ( SIM Library, C++)
7  *
8  * COMMENTS:
9  * Templated functions for common behaviours
10  * in SIM_Fields.
11  */
12 
13 #ifndef __SIM_FieldUtils__
14 #define __SIM_FieldUtils__
15 
16 #include <GU/GU_Types.h>
17 
18 #include "SIM_ScalarField.h"
19 #include "SIM_MatrixField.h"
20 #include "SIM_VectorField.h"
21 #include "SIM_IndexField.h"
22 
23 ///
24 /// Returns true if there is a slice to be performed.
25 /// The slice is the half inclusive interval [minvxl, maxvxl)
26 ///
27 inline bool
28 SIMfieldUtilsComputeSliceWithBorder(const UT_Vector3 &slice, const UT_Vector3 &totaldiv, UT_Vector3 overlapneg, UT_Vector3 overlappos, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
29 {
30  if (slice.isEqual(UT_Vector3(1, 1, 1)))
31  {
32  minvxl = UT_Vector3(0, 0, 0);
33  maxvxl = totaldiv;
34  // Trivially unsliced
35  return false;
36  }
37 
38  int sx, sy, sz;
39  int x, y, z;
40 
41  sx = SYSrint(slice(0));
42  sy = SYSrint(slice(1));
43  sz = SYSrint(slice(2));
44 
45  if (slicenum < 0 || slicenum >= sx*sy*sz)
46  {
47  // Unclear if this should be impossible via UI, and if so,
48  // how to make it so.
49  slicenum = 0;
50  }
51  x = slicenum % sx;
52  slicenum -= x;
53  slicenum /= sx;
54  y = slicenum % sy;
55  slicenum -= y;
56  slicenum /= sy;
57  z = slicenum;
58 
59  minvxl.x() = SYSrint( x * (totaldiv.x() / sx) );
60  maxvxl.x() = SYSrint( (x+1) * (totaldiv.x() / sx) );
61  minvxl.y() = SYSrint( y * (totaldiv.y() / sy) );
62  maxvxl.y() = SYSrint( (y+1) * (totaldiv.y() / sy) );
63  minvxl.z() = SYSrint( z * (totaldiv.z() / sz) );
64  maxvxl.z() = SYSrint( (z+1) * (totaldiv.z() / sz) );
65 
66  // Adjust for our borders.
67  minvxl -= overlapneg;
68  maxvxl += overlappos;
69 
70  minvxl.x() = SYSclamp(minvxl.x(), 0.0, totaldiv.x());
71  maxvxl.x() = SYSclamp(maxvxl.x(), 0.0, totaldiv.x());
72  minvxl.y() = SYSclamp(minvxl.y(), 0.0, totaldiv.y());
73  maxvxl.y() = SYSclamp(maxvxl.y(), 0.0, totaldiv.y());
74  minvxl.z() = SYSclamp(minvxl.z(), 0.0, totaldiv.z());
75  maxvxl.z() = SYSclamp(maxvxl.z(), 0.0, totaldiv.z());
76 
77  // Special case: we need at least one voxel in each direction.
78  if (maxvxl.x() - minvxl.x() < 1)
79  maxvxl.x()++;
80  if (maxvxl.y() - minvxl.y() < 1)
81  maxvxl.y()++;
82  if (maxvxl.z() - minvxl.z() < 1)
83  maxvxl.z()++;
84 
85  // Clamp again...
86  maxvxl.x() = SYSclamp(maxvxl.x(), 0.0, totaldiv.x());
87  maxvxl.y() = SYSclamp(maxvxl.y(), 0.0, totaldiv.y());
88  maxvxl.z() = SYSclamp(maxvxl.z(), 0.0, totaldiv.z());
89 
90  // Verify we are still valid.
91  if (maxvxl.x() - minvxl.x() < 1)
92  minvxl.x()--;
93  if (maxvxl.y() - minvxl.y() < 1)
94  minvxl.y()--;
95  if (maxvxl.z() - minvxl.z() < 1)
96  minvxl.z()--;
97 
98  return true;
99 }
100 
101 template <typename FIELDTYPE>
102 bool
103 SIMfieldUtilsComputeSliceWithBorder(const FIELDTYPE *field, const UT_Vector3 &totaldiv, UT_Vector3 overlapneg, UT_Vector3 overlappos, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
104 {
105  UT_Vector3 slice = field->getSliceDivisions();
106 
107  return SIMfieldUtilsComputeSliceWithBorder(slice, totaldiv, overlapneg, overlappos, slicenum, minvxl, maxvxl);
108 }
109 
110 
111 template <typename FIELDTYPE>
112 bool
113 SIMfieldUtilsComputeSlice(const FIELDTYPE *field, const UT_Vector3 &totaldiv, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
114 {
116  field, totaldiv,
117  field->getSliceOverlapNeg(), field->getSliceOverlapPos(),
118  slicenum, minvxl, maxvxl);
119 }
120 
121 /// Returns true if there is any overlap between the two
122 /// slices. [minvxl, maxvxl) is the region of overlap.
123 /// This is the intersection of the two slice fields.
124 template <typename FIELDTYPE>
125 bool
126 SIMfieldUtilsGetSliceBorder(const FIELDTYPE *field,
127  int a_slice, int b_slice,
128  UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
129 {
130  UT_Vector3 a_min, a_max, b_min, b_max;
131  UT_Vector3 div;
132 
134 
135  SIMfieldUtilsComputeSlice(field, div, a_slice, a_min, a_max);
136  SIMfieldUtilsComputeSlice(field, div, b_slice, b_min, b_max);
137 
138  UT_BoundingBox a_box(a_min, a_max), b_box(b_min, b_max);
139 
140  if (!a_box.computeIntersection(b_box))
141  return false;
142 
143  minvxl = a_box.minvec();
144  maxvxl = a_box.maxvec();
145 
146  return true;
147 }
148 
149 template <typename FIELDTYPE>
151 SIMfieldUtilsGetDivisionsNoSlice(const FIELDTYPE *field)
152 {
153  UT_Vector3 div;
154  int uniform;
155 
156  uniform = field->getUniformVoxels();
157  if (uniform)
158  {
159  UT_Vector3 size, searchsize;
160  int axis, a;
161  fpreal voxelsize;
162  fpreal uniformdiv;
163 
164  size = field->getRawSize();
165  uniformdiv = field->getRawUniformDivisions();
166 
167  searchsize = size;
168 
169  // Force voxels to be uniform, by hook or by crook.
170  // This axis will be taken as authoritative.
171  axis = uniform-1;
172 
173  if (field->getTwoDField())
174  {
175  // We cannot use an axis that isn't represented.
176  // For maximum axis case, we clamp the non represented
177  // axis to 0 size to make sure we ignore it.
178  switch (field->getVoxelPlane())
179  {
180  case GU_PLANE_XY:
181  if (axis == 2)
182  axis = 0;
183  searchsize(2) = 0.0;
184  break;
185  case GU_PLANE_YZ:
186  if (axis == 0)
187  axis = 1;
188  searchsize(0) = 0.0;
189  break;
190  case GU_PLANE_XZ:
191  if (axis == 1)
192  axis = 2;
193  searchsize(1) = 0.0;
194  break;
195  }
196  }
197 
198  // Check to see if they requested a maximum voxel option.
199  if (axis == 3)
200  {
201  axis = searchsize.findMaxAbsAxis();
202  }
203 
204  // If the user is specifying by voxel size...
205  if (axis == 4)
206  {
207  voxelsize = field->getRawDivisionSize();
208  }
209  else
210  {
211  voxelsize = size(axis) / uniformdiv;
212  }
213 
214 
215  // It is possible for the user to accidentally specify a
216  // zero size through use of a ladder handle, which, obviously,
217  // leads to bad things.
218  if (SYSequalZero(voxelsize))
219  {
220  // This, presumeably, also means that all axes are
221  // the same as we found no maximum!
222  div = uniformdiv;
223  }
224  else
225  {
226  // Determine the dimensions of the divisions.
227  for (a = 0; a < 3; a++)
228  {
229  div(a) = SYSrint(size(a)/voxelsize);
230  if (div(a) < 1.0)
231  div(a) = 1.0;
232  }
233  // div(axis) should evaluate to uniformdiv.
234  // The exception will be if we are currently building
235  // our divisions and thus have uniformdiv == 0.
236  // Similarly, if we have specified by voxel size, they
237  // will not match.
238  UT_ASSERT(!uniformdiv || (axis == 4) || SYSisEqual(div(axis), uniformdiv));
239  }
240  }
241  else
242  {
243  div = field->getRawDivisions();
244  }
245 
246  if (field->getTwoDField())
247  {
248  // Clamp to twod.
249  switch (field->getVoxelPlane())
250  {
251  case GU_PLANE_XY:
252  div.z() = 1.0;
253  break;
254  case GU_PLANE_YZ:
255  div.x() = 1.0;
256  break;
257  case GU_PLANE_XZ:
258  div.y() = 1.0;
259  break;
260  }
261  }
262 
263  return div;
264 }
265 
266 template <typename FIELDTYPE>
268 SIMfieldUtilsGetDivisions(const FIELDTYPE *field)
269 {
270  UT_Vector3 minvxl, maxvxl;
271  UT_Vector3 div;
272 
274 
275  // Now compute divisions for our particular slice.
276  SIMfieldUtilsComputeSlice(field, div, field->getSlice(), minvxl, maxvxl);
277 
278  maxvxl -= minvxl;
279 
280  return maxvxl;
281 }
282 
283 template <typename FIELDTYPE>
285 SIMfieldUtilsGetSizeNoSlice(const FIELDTYPE *field)
286 {
288  int uniform;
289 
290  size = field->getRawSize();
291 
292  uniform = field->getUniformVoxels();
293 
294  if (uniform)
295  {
296  int axis;
297  fpreal voxelsize;
298  UT_Vector3 div;
299  UT_Vector3 searchsize;
300 
301  searchsize = size;
302  axis = uniform-1;
303 
304  if (field->getTwoDField())
305  {
306  // We cannot use an axis that isn't represented.
307  switch (field->getVoxelPlane())
308  {
309  case GU_PLANE_XY:
310  if (axis == 2)
311  axis = 0;
312  searchsize(2) = 0;
313  break;
314  case GU_PLANE_YZ:
315  if (axis == 0)
316  axis = 1;
317  searchsize(0) = 0;
318  break;
319  case GU_PLANE_XZ:
320  if (axis == 1)
321  axis = 2;
322  searchsize(1) = 0;
323  break;
324  }
325  }
326 
327  // Check to see if they requested a maximum voxel option.
328  if (axis == 3)
329  axis = searchsize.findMaxAbsAxis();
330 
331  // Taking into account 2d and uniformality:
333 
334  // Recompute voxelsize...
335  if (axis == 4)
336  voxelsize = field->getRawDivisionSize();
337  else
338  voxelsize = size(axis) / div(axis);
339 
340  // Now the other dimensions are a direct copy
341  size = voxelsize * div;
342  }
343 
344  // Size should never be zero. We demand at least one voxel, so
345  // should have computed a non-zero size if we had a non-zero voxel
346  // size. If we get a zero voxelsize, thi sis the cahcne to fix
347  // it. 1.0 is a random number here, there is no good answer
348  // in these cases.
349  if (size.x() == 0)
350  size.x() = 1;
351  if (size.y() == 0)
352  size.y() = 1;
353  if (size.z() == 0)
354  size.z() = 1;
355 
356  return size;
357 }
358 
359 template <typename FIELDTYPE>
361 SIMfieldUtilsGetSize(const FIELDTYPE *field)
362 {
364  UT_Vector3 div;
365  UT_Vector3 minvxl, maxvxl;
366 
368  size = SIMfieldUtilsGetSizeNoSlice(field);
369 
370  if (SIMfieldUtilsComputeSlice(field, div, field->getSlice(), minvxl, maxvxl))
371  {
372  UT_Vector3 voxelsize;
373 
374  voxelsize = size / div;
375 
376  // Get actual sliced size.
377  maxvxl -= minvxl;
378 
379  // Recompute oursize from there.
380  size = maxvxl * voxelsize;
381  }
382 
383  return size;
384 }
385 
386 template <typename FIELDTYPE>
388 SIMfieldUtilsGetCenter(const FIELDTYPE *field)
389 {
391  UT_Vector3 div;
392  UT_Vector3 minvxl, maxvxl;
393  UT_Vector3 center;
394 
396  center = field->getRawCenter();
397 
398  if (SIMfieldUtilsComputeSlice(field, div, field->getSlice(), minvxl, maxvxl))
399  {
400  UT_Vector3 voxelsize;
401 
402  size = SIMfieldUtilsGetSizeNoSlice(field);
403 
404  voxelsize = size / div;
405  // My actual center is found by averaging min/maxvxl and
406  // casting back into our large voxel space.
407  minvxl += maxvxl;
408  minvxl *= 0.5;
409 
410  // Make our coordinates relative to the center of the box
411  minvxl -= div / 2;
412 
413  // Convert to space
414  minvxl *= voxelsize;
415 
416  center += minvxl;
417  }
418 
419  return center;
420 }
421 
422 
423 template <typename FIELDTYPE, typename F2>
424 void
425 SIMfieldUtilsMatch(FIELDTYPE *field, const F2 *srcfield)
426 {
427  field->setUniformVoxels(srcfield->getUniformVoxels());
428  field->setTwoDField(srcfield->getTwoDField());
429  field->setVoxelPlane(srcfield->getVoxelPlane());
430 
431  field->setRawDivisions(srcfield->getRawDivisions());
432  field->setRawDivisionSize(srcfield->getRawDivisionSize());
433  field->setRawUniformDivisions(srcfield->getRawUniformDivisions());
434  field->setRawSize(srcfield->getRawSize());
435  field->setRawCenter(srcfield->getRawCenter());
436 
437  field->setSlice(srcfield->getSlice());
438  field->setSliceDivisions(srcfield->getSliceDivisions());
439  field->setSliceOverlapNeg(srcfield->getSliceOverlapNeg());
440  field->setSliceOverlapPos(srcfield->getSliceOverlapPos());
441 
442  UT_String pospath;
443  srcfield->getPositionPath(pospath);
444  field->setPositionPath(pospath);
445 
446  field->testForNan();
447 
448  field->updateTotalVoxels();
449 }
450 
451 inline void
453 {
454  raw[0] = field->stealField();
455 }
456 
457 inline void
459 {
460  raw[0] = field->stealField();
461 }
462 
463 inline void
465 {
466  for (int i = 0; i < 3; i++)
467  raw[i] = field->stealField(i);
468 }
469 
470 inline void
472 {
473  for (int i = 0; i < 3; i++)
474  for (int j = 0; j < 3; j++)
475  raw[i*3+j] = field->stealField(i, j);
476 }
477 
478 template <typename RAWFIELD>
479 void
481  const char *address, int port,
482  RAWFIELD *dest,
483  RAWFIELD *src,
484  int slicenum,
485  int offx, int offy, int offz,
486  UT_Vector3 olddiv, UT_Vector3 newdiv,
487  UT_Vector3 slicediv,
488  UT_Vector3 overlapneg, UT_Vector3 overlappos);
489 
490 inline void
492  int offx, int offy, int offz,
493  bool keepdata,
494  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
495  const char *address,
496  int port)
497 {
498  if (keepdata)
499  {
500  field->getField()->fieldNC()->copyWithOffset(*raw[0]->field(),
501  offx, offy, offz);
502  if (UTisstring(address) && port > 0)
503  {
505  address, port,
506  field->getField(),
507  raw[0],
508  field->getSlice(),
509  offx, offy, offz,
510  olddivvec, newdivvec,
511  field->getSliceDivisions(),
512  field->getSliceOverlapNeg(),
513  field->getSliceOverlapPos());
514  }
515 
516  }
517  delete raw[0];
518 }
519 
520 inline void
522  int offx, int offy, int offz,
523  bool keepdata,
524  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
525  const char *address,
526  int port)
527 {
528  if (keepdata)
529  {
530  field->getField()->fieldNC()->copyWithOffset(*raw[0]->field(),
531  offx, offy, offz);
532  if (UTisstring(address) && port > 0)
533  {
535  address, port,
536  field->getField(),
537  raw[0],
538  field->getSlice(),
539  offx, offy, offz,
540  olddivvec, newdivvec,
541  field->getSliceDivisions(),
542  field->getSliceOverlapNeg(),
543  field->getSliceOverlapPos());
544  }
545  }
546  delete raw[0];
547 }
548 
549 inline void
551  int offx, int offy, int offz,
552  bool keepdata,
553  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
554  const char *address,
555  int port)
556 {
557  for (int i = 0; i < 3; i++)
558  {
559  if (keepdata)
560  {
561  field->getField(i)->fieldNC()->copyWithOffset(*raw[i]->field(),
562  offx, offy, offz);
563  if (UTisstring(address) && port > 0)
564  {
566  address, port,
567  field->getField(i),
568  raw[i],
569  field->getSlice(),
570  offx, offy, offz,
571  olddivvec, newdivvec,
572  field->getSliceDivisions(),
573  field->getSliceOverlapNeg(),
574  field->getSliceOverlapPos());
575  }
576  }
577  delete raw[i];
578  }
579 }
580 
581 inline void
583  int offx, int offy, int offz,
584  bool keepdata,
585  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
586  const char *address,
587  int port)
588 {
589  for (int i = 0; i < 3; i++)
590  for (int j = 0; j < 3; j++)
591  {
592  if (keepdata)
593  {
594  field->getField(i, j)->fieldNC()->copyWithOffset(*raw[i*3+j]->field(),
595  offx, offy, offz);
596 
597  if (UTisstring(address) && port > 0)
598  {
600  address, port,
601  field->getField(i, j),
602  raw[i*3+j],
603  field->getSlice(),
604  offx, offy, offz,
605  olddivvec, newdivvec,
606  field->getSliceDivisions(),
607  field->getSliceOverlapNeg(),
608  field->getSliceOverlapPos());
609  }
610  }
611  delete raw[i*3+j];
612  }
613 }
614 
615 template <typename FIELDTYPE>
616 void
618  UT_Vector3 size, UT_Vector3 center,
619  bool keepdata,
620  const char *address,
621  int port)
622 {
623  UT_Vector3 voxelsize, newsize, newcenter;
624  UT_Vector3 oldcenter, oldsize, offset;
625  typename FIELDTYPE::rawfield_type *oldfields[9];
626  int voxeloffset[3];
627  int newdiv[3], olddiv[3], uniformdiv, axis;
628  UT_Vector3 olddivvec, searchsize;
629 
630  voxelsize = field->getVoxelSize();
631 
632  if (SYSequalZero(voxelsize.x()) ||
633  SYSequalZero(voxelsize.y()) ||
634  SYSequalZero(voxelsize.z()))
635  {
636  // Zero sized voxels can't be resized as we can't
637  // meaningfully find a new size for them.
638  return;
639  }
640 
641  // We need the unsliced sizes.
642  oldcenter = field->getRawCenter();
643  oldsize = SIMfieldUtilsGetSizeNoSlice(field);
644  olddivvec = SIMfieldUtilsGetDivisionsNoSlice(field);
645  olddiv[0] = (int) SYSrint(olddivvec.x());
646  olddiv[1] = (int) SYSrint(olddivvec.y());
647  olddiv[2] = (int) SYSrint(olddivvec.z());
648 
649  // Find what range this slice consisted of before the slice.
650  UT_Vector3 oldslicemin, oldslicemax;
651  SIMfieldUtilsComputeSlice(field, olddivvec, field->getSlice(), oldslicemin, oldslicemax);
652 
653  // This is the offset into voxel space. We basically want
654  // to quantize all of our coordinates to be integer voxelsize
655  // steps from this offset.
656  // Note it is not the old center, as it is valid to center
657  // on the mid point of a voxel if we have an odd number of
658  // voxels! Thus it is quanitzed as per the bottom left.
659  UT_Vector3 oldoffset;
660 
661  oldoffset = oldcenter - oldsize/2.0f;
662 
663  // Get the coordinates of our new boxes edges and quantize to
664  // exact voxel numbers.
665  UT_Vector3 newbot, newtop;
666 
667  newbot = center - size/2;
668  newtop = center + size/2;
669 
670  newbot -= oldoffset;
671  newtop -= oldoffset;
672  newbot /= voxelsize;
673  newtop /= voxelsize;
674  // It is depressingly common for things to exactly match up
675  // due to users using a size 0.1 and unit boxes.
676  newtop.x() = SYSrint(newtop.x() + 0.0001);
677  newtop.y() = SYSrint(newtop.y() + 0.0001);
678  newtop.z() = SYSrint(newtop.z() + 0.0001);
679  newbot.x() = SYSrint(newbot.x() - 0.0001);
680  newbot.y() = SYSrint(newbot.y() - 0.0001);
681  newbot.z() = SYSrint(newbot.z() - 0.0001);
682  newbot *= voxelsize;
683  newtop *= voxelsize;
684  newbot += oldoffset;
685  newtop += oldoffset;
686 
687  // We can now recompute our desired center and size from
688  // these quantized values.
689  newcenter = (newbot + newtop) / 2;
690  newsize = newtop - newbot;
691 
692  // Calculate our new size as an integer number of voxels from the
693  // old size.
694  newdiv[0] = SYSrint(newsize.x()/voxelsize.x());
695  newdiv[1] = SYSrint(newsize.y()/voxelsize.y());
696  newdiv[2] = SYSrint(newsize.z()/voxelsize.z());
697 
698  // We can't have zero divisions on any axis.
699  // Note we need to bump our center half a voxel in this case
700  // because it needs to now be voxel centered.
701  if (newdiv[0] == 0)
702  {
703  newcenter.x() -= voxelsize.x()/2;
704  newdiv[0] = 1;
705  }
706  if (newdiv[1] == 0)
707  {
708  newcenter.y() -= voxelsize.y()/2;
709  newdiv[1] = 1;
710  }
711  if (newdiv[2] == 0)
712  {
713  newcenter.z() -= voxelsize.z()/2;
714  newdiv[2] = 1;
715  }
716 
717  // Compute our new size from the new divisions.
718  newsize.x() = newdiv[0] * voxelsize.x();
719  newsize.y() = newdiv[1] * voxelsize.y();
720  newsize.z() = newdiv[2] * voxelsize.z();
721 
722  // We refuse to move the voxel plane if it is 2d.
723  if (field->getTwoDField())
724  {
725  switch (field->getVoxelPlane())
726  {
727  case GU_PLANE_XY:
728  newcenter.z() = oldcenter.z();
729  break;
730  case GU_PLANE_YZ:
731  newcenter.x() = oldcenter.x();
732  break;
733  case GU_PLANE_XZ:
734  newcenter.y() = oldcenter.y();
735  break;
736  }
737  }
738 
739  // Check to see if we have a no-op.
740  if (oldcenter.isEqual(newcenter) &&
741  olddiv[0] == newdiv[0] &&
742  olddiv[1] == newdiv[1] &&
743  olddiv[2] == newdiv[2])
744  return;
745 
746  // Before we adjust our settings, we better steal the old
747  // field as this will cause it to be rebuilt!
748  SIMfieldUtilsStealFields(oldfields, field);
749 
750  // Reset our raw division and uniform division choices
751  // so we'll compute newdiv in the end.
752  field->setRawDivisions(UT_Vector3(newdiv[0], newdiv[1], newdiv[2]));
753 
754  uniformdiv = newdiv[0];
755  axis = field->getUniformVoxels()-1;
756 
757  // Avoid non-existent axes:
758  searchsize = newsize;
759  if (field->getTwoDField())
760  {
761  switch (field->getVoxelPlane())
762  {
763  case GU_PLANE_XY:
764  if (axis == 2)
765  axis = 0;
766  searchsize(2) = 0.0;
767  break;
768  case GU_PLANE_YZ:
769  if (axis == 0)
770  axis = 1;
771  searchsize(0) = 0.0;
772  break;
773  case GU_PLANE_XZ:
774  if (axis == 1)
775  axis = 2;
776  searchsize(1) = 0.0;
777  break;
778  }
779  }
780 
781  // Check to see if they requested a maximum voxel option.
782  if (axis == 3)
783  {
784  axis = searchsize.findMaxAbsAxis();
785  }
786 
787  // Read up the appropriate choice
788  if (axis >= 0 && axis < 3)
789  uniformdiv = newdiv[axis];
790 
791  field->setRawUniformDivisions(uniformdiv);
792 
793  // We do not need to set our DivisionSize since it is unaffected.
794 
795  field->setCenter(newcenter);
796  // Not setSize as we want to keep 2d/uniform!
797  field->setRawSize(newsize);
798  // This is not the same as it will round off voxels and deal
799  // with 2d!
800  newsize = SIMfieldUtilsGetSizeNoSlice(field);
801  UT_Vector3 newdivvec = SIMfieldUtilsGetDivisionsNoSlice(field);
802 
803  // Now fill in the values...
804  // We determine a voxel offset between our two fields
805  offset = (newcenter - newsize/2) - (oldcenter - oldsize / 2);
806  offset /= voxelsize;
807 
808  // field[x] = oldfield[x+offset];
809  // However, oldfield is relative to oldslicemin, new field to
810  // newslicemin
811  UT_Vector3 newslicemin, newslicemax;
812  SIMfieldUtilsComputeSlice(field, newdivvec, field->getSlice(), newslicemin, newslicemax);
813 
814  offset += newslicemin - oldslicemin;
815 
816  voxeloffset[0] = SYSrint(offset.x());
817  voxeloffset[1] = SYSrint(offset.y());
818  voxeloffset[2] = SYSrint(offset.z());
819 
820  // Filling in is very simple.
821  SIMfieldUtilsCopyWithOffset(field, oldfields,
822  voxeloffset[0],
823  voxeloffset[1],
824  voxeloffset[2],
825  keepdata,
826  olddivvec, newdivvec,
827  address, port);
828 
829  field->updateTotalVoxels();
830 
831  field->pubHandleModification();
832 }
833 
834 #endif
835 
void SIMfieldUtilsStealFields(SIM_RawIndexField **raw, SIM_IndexField *field)
GA_API const UT_StringHolder div
SIM_RawField * getField(int axis) const
Retrieve raw field.
int findMaxAbsAxis() const
These allow you to find out what indices to use for different axes.
Definition: UT_Vector3.h:480
SIM_RawField * stealField(int i, int j)
SIM_RawField * stealField(int axis)
UT_Vector3T< float > UT_Vector3
GLdouble GLdouble GLdouble z
Definition: glcorearb.h:847
UT_Vector3 SIMfieldUtilsGetSizeNoSlice(const FIELDTYPE *field)
UT_VoxelArrayF * fieldNC() const
Definition: SIM_RawField.h:470
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
SIM_RawField * getField(int i, int j) const
Retrieve raw field.
GLint y
Definition: glcorearb.h:102
This class holds a three dimensional scalar field.
UT_Vector3 SIMfieldUtilsGetDivisionsNoSlice(const FIELDTYPE *field)
void copyWithOffset(const UT_VoxelArray< T > &src, int offx, int offy, int offz)
SYS_FORCE_INLINE T & x(void)
Definition: UT_Vector3.h:581
void SIMfieldUtilsResizeKeepData(FIELDTYPE *field, UT_Vector3 size, UT_Vector3 center, bool keepdata, const char *address, int port)
png_uint_32 i
Definition: png.h:2877
bool SIMfieldUtilsComputeSliceWithBorder(const UT_Vector3 &slice, const UT_Vector3 &totaldiv, UT_Vector3 overlapneg, UT_Vector3 overlappos, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
GLsizeiptr size
Definition: glcorearb.h:663
UT_Vector3 SIMfieldUtilsGetSize(const FIELDTYPE *field)
SIM_RawIndexField * stealField()
SYS_FORCE_INLINE T & z(void)
Definition: UT_Vector3.h:585
void SIMfieldUtilsCopyWithOffset(SIM_IndexField *field, SIM_RawIndexField **raw, int offx, int offy, int offz, bool keepdata, UT_Vector3 olddivvec, UT_Vector3 newdivvec, const char *address, int port)
void SIMfieldUtilsMatch(FIELDTYPE *field, const F2 *srcfield)
SIM_RawIndexField * getField() const
Retrieve raw field.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
UT_Vector3 SIMfieldUtilsGetDivisions(const FIELDTYPE *field)
GLintptr offset
Definition: glcorearb.h:664
void SIMfieldUtilsExchangeFields(const char *address, int port, RAWFIELD *dest, RAWFIELD *src, int slicenum, int offx, int offy, int offz, UT_Vector3 olddiv, UT_Vector3 newdiv, UT_Vector3 slicediv, UT_Vector3 overlapneg, UT_Vector3 overlappos)
SIM_RawField * stealField()
This class holds a three dimensional tensor field.
bool SIMfieldUtilsGetSliceBorder(const FIELDTYPE *field, int a_slice, int b_slice, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
fpreal32 SYSrint(fpreal32 val)
Definition: SYS_Floor.h:163
UT_Vector3 SIMfieldUtilsGetCenter(const FIELDTYPE *field)
bool SIMfieldUtilsComputeSlice(const FIELDTYPE *field, const UT_Vector3 &totaldiv, int slicenum, UT_Vector3 &minvxl, UT_Vector3 &maxvxl)
SYS_FORCE_INLINE T & y(void)
Definition: UT_Vector3.h:583
double fpreal
Definition: SYS_Types.h:263
typedef int
Definition: png.h:1175
SYS_FORCE_INLINE bool UTisstring(const char *s)
Definition: UT_String.h:58
SYS_FORCE_INLINE bool isEqual(const UT_FixedVector< S, SIZE, S_INSTANTIATED > &that, S tol=S(SYS_FTOLERANCE)) const
GLint GLenum GLint x
Definition: glcorearb.h:408
This class holds a three dimensional scalar field.
UT_VoxelArrayI * fieldNC() const
SIM_RawField * getField() const
Retrieve raw field.
This class holds a three dimensional vector field.
GLenum src
Definition: glcorearb.h:1792