Fish - FiberLib for VISH 0.3
Fish - The Fiber Bundle API for the Vish Visualization Shell
033-CellTensor.cpp File Reference

[← Previous Example] [Next Example → 040-FragmentedBinding.cpp ]. More...

#include <fiber/bundle/Bundle.hpp>
#include <fiber/finit/FinitAPI.h>
#include <fiber/field/ArrayRef.hpp>
#include <fiber/field/UniformCartesianArray.hpp>
#include <eagle/PhysicalSpace.hpp>
#include <eagle/ColorSpace.hpp>
#include <fiber/fiberop/Range.hpp>
#include <fiber/baseop/ExpandBBox.hpp>
#include <random>

Functions

void makeUniformPointCloudFragment (RefPtr< Field > &Positions, const Eagle::BoundingBox &BBox, const MultiIndex< 3 > FragmentDims, const string &FragmentName, int PartialFactor)
 The CellTensor and its simpler version, the CellSize.
void CreateEquidistantPointCloud (BundlePtr &BP)
 Create a coordinate field with equidistantly distributed points to demonstrate functionality of the CellSize parameter.
void makeRandomPointCloudFragment (RefPtr< Field > &Positions, const Eagle::BoundingBox &BBox, const MultiIndex< 3 > FragmentDims, const string &FragmentName)
void CreateRandomPointCloud (BundlePtr &BP)
void makeRegularPointCloudFragment (RefPtr< Field > &Positions, const Eagle::BoundingBox &BBox, const MultiIndex< 3 > FragmentDims, const string &FragmentName)
void CreateRegularPointCloud (BundlePtr &BP)
int main ()

Detailed Description

[← Previous Example] [Next Example → 040-FragmentedBinding.cpp ].

In FiberLib Tutorial

#include <fiber/bundle/Bundle.hpp>
#include <fiber/finit/FinitAPI.h>
#include <fiber/field/ArrayRef.hpp>
#include <fiber/field/UniformCartesianArray.hpp>
#include <eagle/PhysicalSpace.hpp>
#include <eagle/ColorSpace.hpp>
#include <fiber/fiberop/Range.hpp>
#include <fiber/baseop/ExpandBBox.hpp>
#include <random>
using namespace Fiber;
using namespace Eagle::PhysicalSpace;
using rgb16 = Eagle::rgb16_t;
/**@brief The CellTensor and its simpler version, the CellSize.
Demonstrate creating point clouds with a variety of distributions
and the corresponding cell size or cell tensor.
The simple cell size as scalar value only works for equidistant
distributions. The cell tensor generalizes to also non-equidistant
distributions.
*/
const Eagle::BoundingBox&BBox,
const MultiIndex<3> FragmentDims,
const string &FragmentName,
int PartialFactor
)
{
size_t PointsPerFragment = PartialFactor>0 ? FragmentDims.size()/PartialFactor: FragmentDims.size();
Ref<UniformCartesianArray> Distribution(BBox, FragmentDims);
//
// Creates a MemArray with a file-write creator, defining
// the type of the creator at this state.
//
ArrayRef<point, 1> Coordinates( PointsPerFragment );
auto CellVector = Distribution->cell_diagonal();
auto CellSize = CellVector[0];
index_t idx = 0;
for(auto I : FragmentDims)
{
if (PartialFactor<2)
idx = I.linear(FragmentDims);
point&P = Coordinates[ idx ];
P.x() = BBox.min()[0] + I[0] * CellVector[0];
P.y() = BBox.min()[1] + I[1] * CellVector[1];
P.z() = BBox.min()[2] + I[2] * CellVector[2];
if (++idx >= PointsPerFragment)
break;
}
auto myFragmentCreator = Positions->createCreator(Coordinates, FragmentName);
setCreatorRange( *myFragmentCreator, BBox.min(), BBox.max() );
(*myFragmentCreator) << "CellSize" << CellSize;
}
/**
Create a coordinate field with equidistantly distributed points
to demonstrate functionality of the CellSize parameter
AI test: post this function body into the AI of your choice and ask it why the last two fragments fail.
*/
{
RefPtr<Field>&Positions = BP[0.0]["EquidistantPointCloud"].makeCartesianRepresentation(3)[ FIBER_POSITIONS ];
/*
The next two fragments demonstrate square fragments which are halfway
filled with equidistantly distributed points. The uniform cell size parameter works.
*/
{
string FragmentName = "UniformSquarePartial-Coarse";
const MultiIndex<3> FragmentDims = MIndex(16,16,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, 0.0, 0.0}, point{0.0-1/16.0, 1.0, 0.0} };
makeUniformPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName, 2);
}
{
string FragmentName = "UniformSquarePartial-Fine";
const MultiIndex<3> FragmentDims = MIndex(32,32,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, 0.0, 0.0}, point{1.0, 1.0, 0.0} };
makeUniformPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName, 2);
}
/*
The next two fragments demonstrate rectangular fragments which are fully
filled with equidistantly distributed points. The uniform cell size parameter works.
*/
{
string FragmentName = "UniformRectangular-Coarse";
const MultiIndex<3> FragmentDims = MIndex(16, 8,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, -0.5, 0.0}, point{0.0-1./16, -0.0-1./16, 0.0} };
makeUniformPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName, 1);
}
{
string FragmentName = "UniformRectangular-Fine";
const MultiIndex<3> FragmentDims = MIndex(32,16,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, -0.5, 0.0}, point{1.0, -0.0-1./16, 0.0} };
makeUniformPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName, 1);
}
/*
The next two fragments demonstrate rectangular fragments which are fully
filled with non-uniformely distributed points.
The uniform cell size parameter does NOT work in this case.
*/
{
string FragmentName = "NotWorking:UniformCoarse";
const MultiIndex<3> FragmentDims = MIndex(16,16,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, -1.0, 0.0}, point{0.0-1/16.0, -0.5-1./16, 0.0} };
makeUniformPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName, 1);
}
{
string FragmentName = "NotWorking:UniformFine";
const MultiIndex<3> FragmentDims = MIndex(32,32,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, -1.0, 0.0}, point{1.0, -0.5-1./32, 0.0} };
makeUniformPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName, 1);
}
}
static double random_double(double min, double max)
{
static thread_local std::mt19937_64 rng(std::random_device{}());
return dist(rng);
}
void makeRandomPointCloudFragment(RefPtr<Field>&Positions,
const Eagle::BoundingBox&BBox,
const MultiIndex<3> FragmentDims,
const string &FragmentName)
{
size_t PointsPerFragment = FragmentDims.size();
Ref<UniformCartesianArray> Distribution(BBox, FragmentDims);
//
// Creates a MemArray with a file-write creator, defining
// the type of the creator at this state.
//
ArrayRef<point, 1> Coordinates( PointsPerFragment );
auto CellVector = Distribution->cell_diagonal();
auto CellSize = CellVector[0];
for(auto I : FragmentDims)
{
index_t idx = I.linear(FragmentDims);
point&P = Coordinates[ idx ];
for(int i=0; i<3; i++)
P[i] = random_double(BBox.min()[i], BBox.max()[i] );
}
auto myFragmentCreator = Positions->createCreator(Coordinates, FragmentName);
setCreatorRange( *myFragmentCreator, BBox.min(), BBox.max() );
(*myFragmentCreator) << "CellSize" << CellSize;
}
void CreateRandomPointCloud(BundlePtr&BP)
{
RefPtr<Field>&Positions = BP[0.0]["RandomPointCloud"].makeCartesianRepresentation(3)[ FIBER_POSITIONS ];
/*
The next two fragments demonstrate square fragments which are halfway
filled with equidistantly distributed points. The uniform cell size parameter works.
*/
{
string FragmentName = "UniformSquarePartial-Coarse";
const MultiIndex<3> FragmentDims = MIndex(16,16,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, 0.0, 0.0}, point{0.0, 1.0, 0.0} };
makeRandomPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
{
string FragmentName = "UniformSquarePartial-Fine";
const MultiIndex<3> FragmentDims = MIndex(32,32,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, 0.0, 0.0}, point{1.0, 1.0, 0.0} };
makeRandomPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
/*
The next two fragments demonstrate rectangular fragments which are fully
filled with equidistantly distributed points. The uniform cell size parameter works.
*/
{
string FragmentName = "UniformRectangular-Coarse";
const MultiIndex<3> FragmentDims = MIndex(16, 8,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, -0.5, 0.0}, point{0.0, -0.0, 0.0} };
makeRandomPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
{
string FragmentName = "UniformRectangular-Fine";
const MultiIndex<3> FragmentDims = MIndex(32,16,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, -0.5, 0.0}, point{1.0, -0.0, 0.0} };
makeRandomPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
}
void makeRegularPointCloudFragment(RefPtr<Field>&Positions,
const Eagle::BoundingBox&BBox,
const MultiIndex<3> FragmentDims,
const string &FragmentName)
{
size_t PointsPerFragment = FragmentDims.size();
Ref<UniformCartesianArray> Distribution(BBox, FragmentDims);
//
// Creates a MemArray with a file-write creator, defining
// the type of the creator at this state.
//
ArrayRef<point, 1> Coordinates( PointsPerFragment );
auto CellVector = Distribution->cell_diagonal();
for(auto I : FragmentDims)
{
index_t idx = I.linear(FragmentDims);
point&P = Coordinates[ idx ];
P.x() = BBox.min()[0] + I[0] * CellVector[0];
P.y() = BBox.min()[1] + I[1] * CellVector[1];
P.z() = BBox.min()[2] + I[2] * CellVector[2];
}
auto myFragmentCreator = Positions->createCreator(Coordinates, FragmentName);
setCreatorRange( *myFragmentCreator, BBox.min(), BBox.max() );
Eagle::metric33 CellTensor = {};
CellTensor(0,0) = 1./( CellVector[0]*CellVector[0] );
CellTensor(1,1) = 1./( CellVector[1]*CellVector[1] );
CellTensor(2,2) = 1./( CellVector[2]*CellVector[2] );
(*myFragmentCreator) << "CellTensor" << CellTensor;
}
void CreateRegularPointCloud(BundlePtr&BP)
{
RefPtr<Field>&Positions = BP[0.0]["RegularPointCloud"].makeCartesianRepresentation(3)[ FIBER_POSITIONS ];
/*
The next two fragments demonstrate square fragments which are halfway
filled with equidistantly distributed points. The uniform cell size parameter works.
*/
{
string FragmentName = "UniformSquarePartial-Coarse";
const MultiIndex<3> FragmentDims = MIndex(16,16,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, 0.0, 0.0}, point{0.0-1/16.0, 1.0, 0.0} };
makeRegularPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
{
string FragmentName = "UniformSquarePartial-Fine";
const MultiIndex<3> FragmentDims = MIndex(32,32,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, 0.0, 0.0}, point{1.0, 1.0, 0.0} };
makeRegularPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
/*
The next two fragments demonstrate rectangular fragments which are fully
filled with equidistantly distributed points. The uniform cell size parameter works.
*/
{
string FragmentName = "UniformRectangular-Coarse";
const MultiIndex<3> FragmentDims = MIndex(16, 8,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, -0.5, 0.0}, point{0.0-1./16, -0.0-1./16, 0.0} };
makeRegularPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
{
string FragmentName = "UniformRectangular-Fine";
const MultiIndex<3> FragmentDims = MIndex(32,16,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, -0.5, 0.0}, point{1.0, -0.0-1./16, 0.0} };
makeRegularPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
{
string FragmentName = "NotWorking:UniformCoarse";
const MultiIndex<3> FragmentDims = MIndex(16,16,1);
Ref<Eagle::BoundingBox> BBox{ point{-1.0, -1.0, 0.0}, point{0.0-1/16.0, -0.5-1./16, 0.0} };
makeRegularPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
{
string FragmentName = "NotWorking:UniformFine";
const MultiIndex<3> FragmentDims = MIndex(32,32,1);
Ref<Eagle::BoundingBox> BBox{ point{0.0, -1.0, 0.0}, point{1.0, -0.5-1./32, 0.0} };
makeRegularPointCloudFragment(Positions, *BBox, FragmentDims, FragmentName);
}
}
int main()
{
// Initialize I/O layers (only required for standalone binaries)
Finit();
//
// Create a bundle object with a grid at T=1.0, named "DemoGrid", in
// a three-dimensional cartesian representation, using the default
// coordinate system.
//
BundlePtr BP = new Bundle();
//
// Save the bundle to a file, even future data
// that are added to the bundle later. This feature
// is called "binding" a file to the Bundle.
//
BP->bindToNew("PointCloud.f5");
Verbose(0) << "Bundle Binder: " << BP->getBinder();
Assert(BP->isBound());
CreateRandomPointCloud(BP);
CreateRegularPointCloud(BP);
return 0;
}
int main()
Demonstrates minimal usage of the FiberLib Create Bundle, insert a time slice, and safe it to a file.
Definition 010-SimpleSave.cpp:13
void makeUniformPointCloudFragment(RefPtr< Field > &Positions, const Eagle::BoundingBox &BBox, const MultiIndex< 3 > FragmentDims, const string &FragmentName, int PartialFactor)
The CellTensor and its simpler version, the CellSize.
Definition 033-CellTensor.cpp:30
void CreateEquidistantPointCloud(BundlePtr &BP)
Create a coordinate field with equidistantly distributed points to demonstrate functionality of the C...
Definition 033-CellTensor.cpp:77
constexpr const _Tp & max(const _Tp &__a, const _Tp &__b)
constexpr const _Tp & min(const _Tp &__a, const _Tp &__b)
mersenne_twister_engine< uint_fast64_t, 64, 312, 156, 31, 0xb5026f5aa96619e9ULL, 29, 0x5555555555555555ULL, 17, 0x71d67fffeda60000ULL, 37, 0xfff7eee000000000ULL, 43, 6364136223846793005ULL > mt19937_64
An array reference class, which is a convenience class for reference pointers to multidimensional mem...
Definition ArrayRef.hpp:28
Convenience class that implements a pointer to a Bundle object but adds some useful member funtions t...
Definition Bundle.hpp:779
The main entity holding all information.
Definition Bundle.hpp:173
A multidimensional index that is automatically a lower-dimensional index via recursion.
Definition MultiIndex.hpp:449
index_t size() const noexcept
Recursive function to compute the entire number of elements.
Definition MultiIndex.hpp:774
Eagle::DomainVector< VectorType, Domain, scalar_t > CellSize(const Eagle::DomainVector< VectorType, Domain, scalar_t > &V, const MultiIndex< VectorType::SIZE > &Dividend, const MultiIndex< VectorType::SIZE > &Stride=MultiIndex< VectorType::SIZE >(1))
Compute the size of a "cell" given a distance between a set of points.
Definition MultiIndex.hpp:1095
StrongPtr< Object, ObjectBase > RefPtr
DomainVector< Vector< color16_t, 3 >, RGB > rgb16_t
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2
IndexTypeConfig< sizeof(void *)>::index_t index_t
Define the index type as according to the size of a pointer, i.e.
Definition Index.hpp:22
RefPtr< DataRange< Type > > setCreatorRange(CreativeArrayBase &CAB, const Type &Min, const Type &Max)
Set the range information on a data Creator with type information as provided implicitly by the type ...
Definition Range.hpp:1222

Function Documentation

◆ CreateEquidistantPointCloud()

void CreateEquidistantPointCloud ( BundlePtr & BP)

Create a coordinate field with equidistantly distributed points to demonstrate functionality of the CellSize parameter.

AI test: post this function body into the AI of your choice and ask it why the last two fragments fail.

References makeUniformPointCloudFragment().

◆ makeUniformPointCloudFragment()

void makeUniformPointCloudFragment ( RefPtr< Field > & Positions,
const Eagle::BoundingBox & BBox,
const MultiIndex< 3 > FragmentDims,
const string & FragmentName,
int PartialFactor )

The CellTensor and its simpler version, the CellSize.

Demonstrate creating point clouds with a variety of distributions and the corresponding cell size or cell tensor. The simple cell size as scalar value only works for equidistant distributions. The cell tensor generalizes to also non-equidistant distributions.

References Eagle::PhysicalSpace::AABB::max(), Eagle::PhysicalSpace::AABB::min(), and Fiber::MultiIndex< Dims >::size().

Referenced by CreateEquidistantPointCloud().