Field value - min/max convenience function

67 views
Skip to first unread message

Nicholas Yue

unread,
Oct 25, 2012, 3:43:55 AM10/25/12
to field...@googlegroups.com
Hi,

Is there an easy call to find the min/max value of a given field
value stored in a *.f3d file ?

Regards

--
Nicholas Yue
Graphics - RenderMan, Visualization, OpenGL, HDF5
Custom Dev - C++ porting, OSX, Linux, Windows
http://au.linkedin.com/in/nicholasyue
https://vimeo.com/channels/naiadtools

Andrew Selle

unread,
Oct 25, 2012, 4:12:20 AM10/25/12
to field...@googlegroups.com
There isn't an especially easy way of doing this right now. I suspect you are asking this, because you are trying to implement the Range() function in prman's ImplicitField interface in an efficient way? 

Efficient way.
You could create an up-front voxel buffer of min's and max's and then do min-reduction and max-reduction's (so you have min and max voxel buffers at various resolutions). Then whenever you need to query a bounding box of some size, choose the appropriate mip-level and min/max the appropriate voxels to get a final value. It would be fairly manual. 

Easy (But inefficient way)
Given your voxel/frustum you would like to find the min max of. Figure out what voxels are inside the bounded volumes and compute min and max by iterating over each voxel.

-Andy


--
You received this message because you are subscribed to the Google Groups "Field3D dev" group.
To post to this group, send email to field...@googlegroups.com.
To unsubscribe from this group, send email to field3d-dev+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/field3d-dev?hl=en.


Magnus Wrenninge

unread,
Oct 25, 2012, 1:28:12 PM10/25/12
to field...@googlegroups.com
I think Andrew sums it up nicely. If you need to bound sub-regions then you'll need to do some extra work. Do you need the global min/max or for a subset?

Either way, the min and the max for a given subdomain should be easiest to find using something like this:
(assuming a float field, and apologies for any syntax errors, doing this from memory)

template <typename T>
struct MinMaxFunctor
{
MinMaxFunctor() : m_min(std::numeric_limits<T>::max(), m_max(std::numeric_limits<T>::min() { }
void operator(T value) { m_min = std::min(m_min, value); m_max = std::max(m_max, value); }
T min() { return m_min; }
T max() { return m_max; }
};

BBox subdomain = yourSubDomain();
auto minMax = for_each(field->cbegin(subdomain), field->cend(subdomain), MinMaxFunctor<float>());
float min = minMax.min();
float max = minMax.max();


Magnus


To unsubscribe from this group, send email to field3d-dev...@googlegroups.com.
Message has been deleted

Maik Figura

unread,
May 31, 2013, 10:21:15 AM5/31/13
to field...@googlegroups.com
Hey, 

I was wondering if there is a convinient way (or more of a standard way) to iterate over a subset of blocks? 
Finding the global min/max was fairly easy given all the sample code in the newsgroup and inside the houdini plugin. 
Finding the min/max for a subset of blocks, seems a bit more complicated (as stated by Magnus). I tried the following approch: 

// creating a Box3i of a subset I want to calc min/max of
Field3D::Box3i bi_box(vsP_min, vsP_max);

// getting the block indexes of the min and the max (they probably differ, span over multiple blocks)
// lower bounds
int bx, by, bz;
field->getBlockCoord(vsP_min.x, vsP_min.y, vsP_min.z, bx, by, bz);

// upper bounds
int bex, bey, bez;
field->getBlockCoord(vsP_max.x, vsP_max.y, vsP_max.z, bex, bey, bez);

// create subdomain I want to iterate over (spans over multiple blocks)
Field3D::Box3i boundBox(V3i(bx,by,bz), V3i(bex,bey,bez));

// iterate over this subset
Field3D::SparseFieldf::iterator it = field->begin(boundBox);
Field3D::SparseFieldf::iterator it_end = field->end(boundBox);
for ( ; it != it_end; ++it) {

 // do something 

}

Cheers
Maik 

Magnus Wrenninge

unread,
Jun 2, 2013, 1:35:14 AM6/2/13
to field...@googlegroups.com
Hi Maik,

First off - do you need to know the min/max values for a specific set of blocks, or within a voxel region that isn't necessarily block-aligned? While not optimal, you could pick out the appropriate blocks to check by doing:

Box3i regionToCheck = ...;
for (SparseField<T>::block_iterator i = field.blockBegin(), end = field.blockEnd(); i != end; ++iBlock) 
{
  if (regionToCheck.intersects(i.blockBoundingBox()) {
    // Check region that overlaps with block
  } else {
    // Skip, not relevant
  }
}

In your example, you're passing block coordinates to field->begin()/end(), but begin()/end() expects voxel coordinates. You could actually just do:

for (SparseField<T>::iterator i = field.begin(bi_box), end = field.end(bi_box); i != end; ++i) {
  // Do something
}

... but it won't iterate in a memory coherent fashion, so the code above that uses blockBegin() may be more efficient. 


Magnus


--
You received this message because you are subscribed to the Google Groups "Field3D dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to field3d-dev...@googlegroups.com.
To post to this group, send email to field...@googlegroups.com.

Maik Figura

unread,
Jun 2, 2013, 4:23:15 PM6/2/13
to field...@googlegroups.com
Hey Magnus, 

I need the min/max values for a region of voxels that is probably not block aligned. Also, Iit doesnt matter if this region of space gets traversed block vise or not, as long as all Voxels in this region getting checked for min/max at some point. I realized that my posted example could not really work. Thanks for sharing that little snippet, while I was playing around this weekend, this was pretty much the same I came up with.
I was wondering why this is not optimal. Am I right that this (lets say I have many different regions to check) always iterates over all allocated blocks? because of: 

for (SparseField<T>::block_iterator i = field.blockBegin(), end = field.blockEnd(); i != end; ++iBlock) 
{

I still cant figure out wether it is possible to traverse just that subregion of voxels in a more efficient manner with the provided Field3D API, or not. Is there a more direct way of just traversing over a regionToCheck, instead of using the intersect check (even though the intersect check should be really fast)? If there is a way, it would be great if one could share it, even if its only pseudo code I am happy to work work with it. I guess one would have to get all allocated blocks inbetween the Box3i regionToCheck and then only traverse those. 
I am just curious if there is a better way. I read the previous posts, and of course the "mipmap" approach sounds nice, but somehow this feels like overkill.

Besides that, I really enjoy working with the Field3D API and its doc. 

Magnus Wrenninge

unread,
Jun 7, 2013, 2:29:28 PM6/7/13
to field...@googlegroups.com
Hi Maik,

The reason it's not optimal is because it skips around in memory more than if you traversed the voxels block-by-block. You lose cache efficiencies, so it's a bit slower. But it does traverse just "regionToCheck" without touching any other voxels.

Hope that helps,

Magnus


--
You received this message because you are subscribed to the Google Groups "Field3D dev" group.

Maik Figura

unread,
Jun 10, 2013, 5:28:21 AM6/10/13
to field...@googlegroups.com
Hi Magnus, 

okay! Thanks for clarifying. 

Cheers
Maik 
Reply all
Reply to author
Forward
0 new messages