FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
Resample.hpp
1#ifndef __BASEOP_RESAMPLE_HPP
2#define __BASEOP_RESAMPLE_HPP
3
4#include <memcore/RefPtr.hpp>
5#include <memcore/Verbose.hpp>
6
7#include "gridopDllApi.h"
8#include <grid/Representation.hpp>
9
10#include <vector/LinearIpol.hpp>
11#include <vector/Interpolate.hpp>
12#include <vector/MultiCopy.hpp>
13
14
15namespace Fiber
16{
17
21template <Dims_t Dims, typename DestType, typename SrcType, class Converter = PlainCopyConvert>
22MultiArray<Dims,DestType>&Resample(MultiArray<Dims,DestType>&DestData
23 , const MultiArray<Dims,SrcType>&SourceData
24 , const MultiIndex<Dims>&DestOffset = MultiIndex<Dims>()
25 , const MultiIndex<Dims>&SourceOffset = MultiIndex<Dims>()
26 , const Converter&C = Converter()
27 )
28{
29const MultiIndex<Dims>&SrcDims = SourceData.Size();
30const MultiIndex<Dims>&DstDims = DestData.Size();
31
32/*
33Given the destination index we get the float-point source index via:
34
35SrcIndex = DstIndex*SrcDims/DstDims;
36
37 Rescaling is always specified via integer dimensions to ensure
38 consistency of the dimensions, though the interpolation could
39 handly arbitrary floating point mappings. Do we have a need
40 for exact index scaling without rounding to integer factors?
41 */
42FixedArray<double, Dims> IndexScale;
43 for(int i=0; i<Dims; i++)
44 {
45 IndexScale[i] = SrcDims[i] / double(DstDims[i]);
46 }
47
48#pragma message "TODO: Check whether the index scale is an integer in all dimensions, and if so, use MultiCopy.hpp's Copy operation"
49
50FixedArray<double,Dims> SrcIndex;
51#pragma message "TODO: Pass Interpolation type - linear/cubic - as template argument"
52Interpolate<Dims, SrcType, LinearIpol<SrcType> > Ipol(SourceData, SrcIndex);
53
54 Verbose(30) << " Resampling over " << DstDims << " destination indices with scale " << IndexScale;
55
56 for(auto DstIndex : DstDims)
57 {
58 for(int i=0; i<Dims; i++)
59 SrcIndex[i] = DstIndex[i]*IndexScale[i];
60
61 C.copy( DestData[ DstIndex], Ipol.eval() );
62 }
63
64 return DestData;
65}
66
67} // namespace Fiber
68
69
70#include <field/RegularlyFragmentedField.hpp>
71
72namespace Fiber
73{
74
80template <Dims_t Dims>
82{
83 FixedArray<double, Dims> IndexScale;
84 Field::CreationFailAlternative CreationMode = Field::CreationFailAlternative::Discardable;
85
86 RefPtr<Field> OutputField;
87 RefPtr<Field> InputField;
88
90 {
91 IndexScale.set(1.0);
92 }
93
94 RefPtr<Field>&createEmptyField(const RefPtr<Field>&theInputField,
96 {
97 InputField = theInputField;
98
100 {
101#pragma warning "reuse fragment ID collection!?"
102// const RefPtr<CreatorConstructionContext> CT;
103
104 OutputField = new RegularlyFragmentedField<Dims>( RegularInputField->getNumberOfFragments() );
105
106 Verbose(20) << "CreativeFieldResampler created empty field with regular fragmentation, using "
107 << RegularInputField->getNumberOfFragments() << " fragments";
108
109 }
110 else
111 {
112 OutputField = new Field( theOutputFragmentIDCollection );
113
114 Verbose(20) << "CreativeFieldResampler created empty field with no predefined fragmentation";
115 }
116 return OutputField;
117 }
118
119 RefPtr<Field>&compute()
120 {
121 if (OutputField)
122 {
123 InputField->iterate( *this );
124 }
125
126 return OutputField;
127 }
128};
129
130
136template <int Dims, typename DestType, typename SrcType = DestType, class Converter = PlainCopyConvert>
138{
140 {
142
143 Verbose(20) << "CreativeResampleFragmentIterator: Iterating over a source fragment of type "
144 << typeid(SrcType) << " to be put into destination type " << typeid(DestType);
145
147 {
149 for(int i=0; i<Dims; i++)
150 {
151// DestDims[i] = index_t( SrcData->Size()[i] * this->IndexScale[i] );
152 DestDims[i] = index_t( SrcData->Size()[i] * this->IndexScale[i] ) -1;
153 }
154
155 Verbose(20) << "CreativeResampleFragmentIterator: Creating a destination fragment of size " << DestDims;
156
158
159 Resample( *DestData, *SrcData);
160
161 if (!this->OutputField->createCreator( DestData, f, this->CreationMode))
162 {
163 Verbose(0) << "CreativeResampleFragmentIterator: Could not create a Creator, which is not so good.";
164 }
165 }
166 else
167 {
169 Verbose(15) << "SourceData is " << SourceData;
170 else
171 Verbose(15) << "No acceptable input data type was found.";
172 }
173
174 return true;
175 }
176};
177
178
186
187} // namespace Fiber
188
189
190#include <grid/Grid.hpp>
191
192
193namespace Fiber
194{
195
196extern gridop_API
197RefPtr<Field> ResampleRegularGrid3D(Grid&OutputGrid, const Grid&InputGrid,
198 const string&Fieldname,
199 const FixedArray<double, 3>&IndexScale,
200 const std::string&ChartName = std::string() );
201
202
203} // namespace Fiber
204
205#endif
_Expr< _ValFunClos< _ValArray, _Tp >, _Tp > apply(_Tp __func(_Tp)) const
An iterator with an optional DataCreator, which is just a class to intercept creation of data along a...
Definition CreativeIterator.hpp:34
A Field is a collection of CreativeArrayBase reference pointers which are accessed via FragmentID obj...
Definition Field.hpp:245
Base class for iterators over the fragments of a field.
Definition FragmentID.hpp:249
void set(const T &Value)
Set all elements to the same value.
Definition vector/Iterator.hpp:724
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
Base class for resampling n-dimensional fields.
Definition Resample.hpp:82
Strategy: Iterate over the source grid, creating a fragments in the new Grid as specified by the resa...
Definition Resample.hpp:138
bool apply(const RefPtr< FragmentID > &f, const RefPtr< CreativeArrayBase > &SourceFragment) override
Iteration callback function.
Definition Resample.hpp:139
A resample class specifically for uniform arrays.
Definition Resample.hpp:183