HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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  field->setVoxelSize(srcfield->getVoxelSize());
451 }
452 
453 inline void
455 {
456  raw[0] = field->stealField();
457 }
458 
459 inline void
461 {
462  raw[0] = field->stealField();
463 }
464 
465 inline void
467 {
468  for (int i = 0; i < 3; i++)
469  raw[i] = field->stealField(i);
470 }
471 
472 inline void
474 {
475  for (int i = 0; i < 3; i++)
476  for (int j = 0; j < 3; j++)
477  raw[i*3+j] = field->stealField(i, j);
478 }
479 
480 template <typename RAWFIELD>
481 void
483  const char *address, int port,
484  RAWFIELD *dest,
485  RAWFIELD *src,
486  int slicenum,
487  int offx, int offy, int offz,
488  UT_Vector3 olddiv, UT_Vector3 newdiv,
489  UT_Vector3 slicediv,
490  UT_Vector3 overlapneg, UT_Vector3 overlappos);
491 
492 inline void
494  int offx, int offy, int offz,
495  bool keepdata,
496  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
497  const char *address,
498  int port)
499 {
500  if (keepdata)
501  {
502  field->getField()->fieldNC()->copyWithOffset(*raw[0]->field(),
503  offx, offy, offz);
504  if (UTisstring(address) && port > 0)
505  {
507  address, port,
508  field->getField(),
509  raw[0],
510  field->getSlice(),
511  offx, offy, offz,
512  olddivvec, newdivvec,
513  field->getSliceDivisions(),
514  field->getSliceOverlapNeg(),
515  field->getSliceOverlapPos());
516  }
517 
518  }
519  delete raw[0];
520 }
521 
522 inline void
524  int offx, int offy, int offz,
525  bool keepdata,
526  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
527  const char *address,
528  int port)
529 {
530  if (keepdata)
531  {
532  field->getField()->fieldNC()->copyWithOffset(*raw[0]->field(),
533  offx, offy, offz);
534  if (UTisstring(address) && port > 0)
535  {
537  address, port,
538  field->getField(),
539  raw[0],
540  field->getSlice(),
541  offx, offy, offz,
542  olddivvec, newdivvec,
543  field->getSliceDivisions(),
544  field->getSliceOverlapNeg(),
545  field->getSliceOverlapPos());
546  }
547  }
548  delete raw[0];
549 }
550 
551 inline void
553  int offx, int offy, int offz,
554  bool keepdata,
555  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
556  const char *address,
557  int port)
558 {
559  for (int i = 0; i < 3; i++)
560  {
561  if (keepdata)
562  {
563  field->getField(i)->fieldNC()->copyWithOffset(*raw[i]->field(),
564  offx, offy, offz);
565  if (UTisstring(address) && port > 0)
566  {
568  address, port,
569  field->getField(i),
570  raw[i],
571  field->getSlice(),
572  offx, offy, offz,
573  olddivvec, newdivvec,
574  field->getSliceDivisions(),
575  field->getSliceOverlapNeg(),
576  field->getSliceOverlapPos());
577  }
578  }
579  delete raw[i];
580  }
581 }
582 
583 inline void
585  int offx, int offy, int offz,
586  bool keepdata,
587  UT_Vector3 olddivvec, UT_Vector3 newdivvec,
588  const char *address,
589  int port)
590 {
591  for (int i = 0; i < 3; i++)
592  for (int j = 0; j < 3; j++)
593  {
594  if (keepdata)
595  {
596  field->getField(i, j)->fieldNC()->copyWithOffset(*raw[i*3+j]->field(),
597  offx, offy, offz);
598 
599  if (UTisstring(address) && port > 0)
600  {
602  address, port,
603  field->getField(i, j),
604  raw[i*3+j],
605  field->getSlice(),
606  offx, offy, offz,
607  olddivvec, newdivvec,
608  field->getSliceDivisions(),
609  field->getSliceOverlapNeg(),
610  field->getSliceOverlapPos());
611  }
612  }
613  delete raw[i*3+j];
614  }
615 }
616 
617 template <typename FIELDTYPE>
618 void
620  UT_Vector3 size, UT_Vector3 center,
621  bool keepdata,
622  const char *address,
623  int port,
624  bool &snapvalid,
625  UT_Vector3 &snapsize, UT_Vector3 &snapcenter)
626 {
627  UT_Vector3 voxelsize, newsize, newcenter;
628  UT_Vector3 oldcenter, oldsize, offset;
629  typename FIELDTYPE::rawfield_type *oldfields[9];
630  int voxeloffset[3];
631  int newdiv[3], olddiv[3], uniformdiv, axis;
632  UT_Vector3 olddivvec, searchsize;
633 
634  voxelsize = field->getVoxelSize();
635 
636  if (SYSequalZero(voxelsize.x()) ||
637  SYSequalZero(voxelsize.y()) ||
638  SYSequalZero(voxelsize.z()))
639  {
640  // Zero sized voxels can't be resized as we can't
641  // meaningfully find a new size for them.
642  return;
643  }
644 
645  // We need the unsliced sizes.
646  oldcenter = field->getRawCenter();
647  oldsize = SIMfieldUtilsGetSizeNoSlice(field);
648  olddivvec = SIMfieldUtilsGetDivisionsNoSlice(field);
649  olddiv[0] = (int) SYSrint(olddivvec.x());
650  olddiv[1] = (int) SYSrint(olddivvec.y());
651  olddiv[2] = (int) SYSrint(olddivvec.z());
652 
653  // Find what range this slice consisted of before the slice.
654  UT_Vector3 oldslicemin, oldslicemax;
655  SIMfieldUtilsComputeSlice(field, olddivvec, field->getSlice(), oldslicemin, oldslicemax);
656 
657  // This is the offset into voxel space. We basically want
658  // to quantize all of our coordinates to be integer voxelsize
659  // steps from this offset.
660  // Note it is not the old center, as it is valid to center
661  // on the mid point of a voxel if we have an odd number of
662  // voxels! Thus it is quanitzed as per the bottom left.
663  UT_Vector3 oldoffset;
664 
665  oldoffset = oldcenter - oldsize/2.0f;
666 
667  // Get the coordinates of our new boxes edges and quantize to
668  // exact voxel numbers.
669  UT_Vector3 newbot, newtop;
670 
671  newbot = center - size/2;
672  newtop = center + size/2;
673 
674  newbot -= oldoffset;
675  newtop -= oldoffset;
676  newbot /= voxelsize;
677  newtop /= voxelsize;
678  // It is depressingly common for things to exactly match up
679  // due to users using a size 0.1 and unit boxes.
680  newtop.x() = SYSrint(newtop.x() + 0.0001);
681  newtop.y() = SYSrint(newtop.y() + 0.0001);
682  newtop.z() = SYSrint(newtop.z() + 0.0001);
683  newbot.x() = SYSrint(newbot.x() - 0.0001);
684  newbot.y() = SYSrint(newbot.y() - 0.0001);
685  newbot.z() = SYSrint(newbot.z() - 0.0001);
686  newbot *= voxelsize;
687  newtop *= voxelsize;
688  newbot += oldoffset;
689  newtop += oldoffset;
690 
691  // We can now recompute our desired center and size from
692  // these quantized values.
693  newcenter = (newbot + newtop) / 2;
694  newsize = newtop - newbot;
695 
696  // Calculate our new size as an integer number of voxels from the
697  // old size.
698  newdiv[0] = SYSrint(newsize.x()/voxelsize.x());
699  newdiv[1] = SYSrint(newsize.y()/voxelsize.y());
700  newdiv[2] = SYSrint(newsize.z()/voxelsize.z());
701 
702  // We can't have zero divisions on any axis.
703  // Note we need to bump our center half a voxel in this case
704  // because it needs to now be voxel centered.
705  if (newdiv[0] == 0)
706  {
707  newcenter.x() -= voxelsize.x()/2;
708  newdiv[0] = 1;
709  }
710  if (newdiv[1] == 0)
711  {
712  newcenter.y() -= voxelsize.y()/2;
713  newdiv[1] = 1;
714  }
715  if (newdiv[2] == 0)
716  {
717  newcenter.z() -= voxelsize.z()/2;
718  newdiv[2] = 1;
719  }
720 
721  // Compute our new size from the new divisions.
722  newsize.x() = newdiv[0] * voxelsize.x();
723  newsize.y() = newdiv[1] * voxelsize.y();
724  newsize.z() = newdiv[2] * voxelsize.z();
725 
726  // We refuse to move the voxel plane if it is 2d.
727  if (field->getTwoDField())
728  {
729  switch (field->getVoxelPlane())
730  {
731  case GU_PLANE_XY:
732  newcenter.z() = oldcenter.z();
733  break;
734  case GU_PLANE_YZ:
735  newcenter.x() = oldcenter.x();
736  break;
737  case GU_PLANE_XZ:
738  newcenter.y() = oldcenter.y();
739  break;
740  }
741  }
742 
743  // Check to see if we have a no-op.
744  if (oldcenter.isEqual(newcenter) &&
745  olddiv[0] == newdiv[0] &&
746  olddiv[1] == newdiv[1] &&
747  olddiv[2] == newdiv[2])
748  return;
749 
750  // Before we adjust our settings, we better steal the old
751  // field as this will cause it to be rebuilt!
752  SIMfieldUtilsStealFields(oldfields, field);
753 
754  // Reset our raw division and uniform division choices
755  // so we'll compute newdiv in the end.
756  field->setRawDivisions(UT_Vector3(newdiv[0], newdiv[1], newdiv[2]));
757 
758  uniformdiv = newdiv[0];
759  axis = field->getUniformVoxels()-1;
760 
761  // Avoid non-existent axes:
762  searchsize = newsize;
763  if (field->getTwoDField())
764  {
765  switch (field->getVoxelPlane())
766  {
767  case GU_PLANE_XY:
768  if (axis == 2)
769  axis = 0;
770  searchsize(2) = 0.0;
771  break;
772  case GU_PLANE_YZ:
773  if (axis == 0)
774  axis = 1;
775  searchsize(0) = 0.0;
776  break;
777  case GU_PLANE_XZ:
778  if (axis == 1)
779  axis = 2;
780  searchsize(1) = 0.0;
781  break;
782  }
783  }
784 
785  // Check to see if they requested a maximum voxel option.
786  if (axis == 3)
787  {
788  axis = searchsize.findMaxAbsAxis();
789  }
790 
791  // Read up the appropriate choice
792  if (axis >= 0 && axis < 3)
793  uniformdiv = newdiv[axis];
794 
795  field->setRawUniformDivisions(uniformdiv);
796 
797  // We do not need to set our DivisionSize since it is unaffected.
798  if (snapvalid)
799  {
800  if (snapcenter.isEqual(newcenter) &&
801  snapsize.isEqual(newsize))
802  {
803  newcenter = snapcenter;
804  newsize = snapsize;
805  }
806  }
807  snapcenter = newcenter;
808  snapsize = newsize;
809  snapvalid = true;
810 
811  field->setCenter(newcenter);
812  // Not setSize as we want to keep 2d/uniform!
813  field->setRawSize(newsize);
814  // This is not the same as it will round off voxels and deal
815  // with 2d!
816  newsize = SIMfieldUtilsGetSizeNoSlice(field);
817  UT_Vector3 newdivvec = SIMfieldUtilsGetDivisionsNoSlice(field);
818 
819  // Now fill in the values...
820  // We determine a voxel offset between our two fields
821  offset = (newcenter - newsize/2) - (oldcenter - oldsize / 2);
822  offset /= voxelsize;
823 
824  // field[x] = oldfield[x+offset];
825  // However, oldfield is relative to oldslicemin, new field to
826  // newslicemin
827  UT_Vector3 newslicemin, newslicemax;
828  SIMfieldUtilsComputeSlice(field, newdivvec, field->getSlice(), newslicemin, newslicemax);
829 
830  offset += newslicemin - oldslicemin;
831 
832  voxeloffset[0] = SYSrint(offset.x());
833  voxeloffset[1] = SYSrint(offset.y());
834  voxeloffset[2] = SYSrint(offset.z());
835 
836  // Filling in is very simple.
837  SIMfieldUtilsCopyWithOffset(field, oldfields,
838  voxeloffset[0],
839  voxeloffset[1],
840  voxeloffset[2],
841  keepdata,
842  olddivvec, newdivvec,
843  address, port);
844 
845  field->updateTotalVoxels();
846 
847  field->pubHandleModification();
848 
849  field->setVoxelSize(voxelsize);
850 }
851 
852 template <typename FIELDTYPE>
853 void
855  UT_Vector3 size, UT_Vector3 center,
856  bool keepdata,
857  const char *address,
858  int port)
859 {
860  bool snapvalid = false;
861  UT_Vector3 snapcenter, snapsize;
862  SIMfieldUtilsResizeKeepDataAndSnap(field, size, center,
863  keepdata, address, port,
864  snapvalid, snapsize, snapcenter);
865 
866 }
867 
868 
869 #endif
870 
void SIMfieldUtilsStealFields(SIM_RawIndexField **raw, SIM_IndexField *field)
void SIMfieldUtilsResizeKeepDataAndSnap(FIELDTYPE *field, UT_Vector3 size, UT_Vector3 center, bool keepdata, const char *address, int port, bool &snapvalid, UT_Vector3 &snapsize, UT_Vector3 &snapcenter)
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:397
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:488
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:498
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:502
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.
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:500
double fpreal
Definition: SYS_Types.h:270
typedef int
Definition: png.h:1175
SYS_FORCE_INLINE bool UTisstring(const char *s)
Definition: UT_String.h:57
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.
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:126
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