FiberVISH 0.2
Fish - The Fiber Bundle API for the Vish Visualization Shell
RefinementRecursion.hpp
1#ifndef __FIBER_BASEOP_REFINEMENTRECURSION_HPP
2#define __FIBER_BASEOP_REFINEMENTRECURSION_HPP
3
4#include <grid/types/RefinedFragmentSkeleton.hpp>
5
6#include <forward_list>
7#include <functional>
8#include <tuple>
9
10namespace Fiber
11{
12
13template <class FragmentContext>
14using RefinementAllowanceFunction = std::function< std::tuple<bool, FragmentContext >(const RefPtr<Skeleton>&, const RefPtr<FragmentID>&)>;
15
16template <class FragmentContext, class RecursionCriterium>
17using RefinementContinuationFunction = std::function< std::tuple<bool, RecursionCriterium>(const FragmentContext&,const RefPtr<FragmentID>&)>;
18
19template <class RecursionCriterium>
20using RefinementFragmentEmitFunction = std::function<bool(const RecursionCriterium&TerminalCriteria,const RefPtr<FragmentID>&)>;
21
22
23/*
24 Application example see RefinementRecursion.cpp
25
26 */
27template <class FragmentContext, class RecursionCriterium>
28bool ConditionalRecursion(const RefPtr<Grid>&G, const SkeletonID&ParentSid, const RefPtr<FragmentID>&ParentID,
29 const RefinementAllowanceFunction<FragmentContext>&isAllowedFragment,
30 const RefinementContinuationFunction<FragmentContext,RecursionCriterium>&wantFurtherRefinement,
31 const RefinementFragmentEmitFunction<RecursionCriterium>&emitKid,
32 const RecursionCriterium&ParentFragmentCriteria
33 )
34{
35int FragmentRefinementLayoutDimension = 3;
36
37 if (!G) return false;
38
39SkeletonID ChildrenSid = SkeletonID::nextRefinement(ParentSid, 1);
40RefinedFragmentSkeleton Refinement(G, ParentSid, ChildrenSid, FragmentRefinementLayoutDimension);
41
42RefPtr<Skeleton> ParentSkeleton = Refinement.getParentSkeleton();
43 if (Refinement && ParentSkeleton && Refinement.getChildSkeleton() )
44 {
45 const std::tuple<bool, FragmentContext>&FragmentRefinementAllowance = isAllowedFragment(ParentSkeleton, ParentID);
46 if (std::get<0>(FragmentRefinementAllowance))
47 {
49 KidsThatNeedFurtherRecursion,
50 KidsThatNeedNoRecursion;
51
52 Refinement.iterateChildren(ParentID,
53 [
54 &KidsThatNeedFurtherRecursion,
55 &KidsThatNeedNoRecursion ,
56 &FragmentRefinementAllowance ,
57 wantFurtherRefinement
58 ](const RefPtr<FragmentID>&KidID)
59 {
61 NeedMoreRefinement = wantFurtherRefinement( std::get<1>(FragmentRefinementAllowance), KidID);
62 if (std::get<0>(NeedMoreRefinement))
63 {
64 KidsThatNeedFurtherRecursion.emplace_front( KidID, std::get<1>(NeedMoreRefinement) );
65 }
66 else
67 {
68 KidsThatNeedNoRecursion.emplace_front( KidID, std::get<1>(NeedMoreRefinement) );
69 }
70 return true;
71 }
72 );
73
74 if (!KidsThatNeedFurtherRecursion.empty())
75 {
76 // todo: possibly reorder kids here
77 for(const auto&Kid : KidsThatNeedFurtherRecursion)
78 {
79 const RefPtr<FragmentID>&KidID = std::get<0>(Kid);
80 if (!ConditionalRecursion(G, ChildrenSid, KidID, isAllowedFragment, wantFurtherRefinement, emitKid, std::get<1>(Kid) ))
81 return false;
82 }
83 for(const auto&Kid : KidsThatNeedNoRecursion)
84 {
85 const RefPtr<FragmentID>&KidID = std::get<0>(Kid);
86 if (!emitKid( std::get<1>(Kid), KidID ))
87 return false;
88 }
89
90 return true;
91 }
92 }
93 }
94
95 return emitKid( ParentFragmentCriteria, ParentID );
96}
97
98template <class FragmentContext, class RecursionCriterium>
99void RefinementRecursion(const RefPtr<Grid>&G, const SkeletonID&ConnectivitySid, const RefPtr<Field>&ConnectivityField,
100 const RefinementAllowanceFunction<FragmentContext>&isAllowedFragment,
101 const RefinementContinuationFunction<FragmentContext,RecursionCriterium>&wantFurtherRefinement,
102 const RefinementFragmentEmitFunction<RecursionCriterium>&emitKid,
103 const RecursionCriterium&ParentFragmentCriteria)
104{
105 ConnectivityField->Iterate( [G, ConnectivitySid,
106 isAllowedFragment, wantFurtherRefinement, emitKid, ParentFragmentCriteria ]
107 (const RefPtr<FragmentID>&myFragmentID, const RefPtr<CreativeArrayBase>&)
108 {
109 ConditionalRecursion<FragmentContext,RecursionCriterium>
110 (G, ConnectivitySid, myFragmentID, isAllowedFragment, wantFurtherRefinement, emitKid, ParentFragmentCriteria );
111 return true;
112 }
113 );
114}
115
116template <class FragmentContext, class RecursionCriterium>
117void RefinementRecursion(const RefPtr<Grid>&G, const SkeletonID&ConnectivitySid, const RefPtr<Skeleton>&Vertices,
118 const RefinementAllowanceFunction<FragmentContext>&isAllowedFragment,
119 const RefinementContinuationFunction<FragmentContext,RecursionCriterium>&wantFurtherRefinement,
120 const RefinementFragmentEmitFunction<RecursionCriterium>&emitKid,
121 const RecursionCriterium&ParentFragmentCriteria)
122{
123 if (!G) return;
124
125RefPtr<Skeleton> ConnectivitySkeleton = (*G)(ConnectivitySid);
126
127 if (!ConnectivitySkeleton) return;
128
129RefPtr<Representation> Connectivity = (*ConnectivitySkeleton)(Vertices);
130 if (!Connectivity) return;
131RefPtr<Field> ConnectivityField = Connectivity->getPositions();
132
133 RefinementRecursion<FragmentContext,RecursionCriterium>
134 (G, ConnectivitySid, ConnectivityField, isAllowedFragment, wantFurtherRefinement, emitKid, ParentFragmentCriteria );
135}
136
137template <class FragmentContext, class RecursionCriterium>
138void RefinementRecursion(const RefPtr<Grid>&G, const SkeletonID&ConnectivitySid,
139 const RefinementAllowanceFunction<FragmentContext>&isAllowedFragment,
140 const RefinementContinuationFunction<FragmentContext,RecursionCriterium>&wantFurtherRefinement,
141 const RefinementFragmentEmitFunction<RecursionCriterium>&emitKid,
142 const RecursionCriterium&ParentFragmentCriteria)
143{
144 if (!G) return;
145
146 RefinementRecursion<FragmentContext,RecursionCriterium>
147 (G, ConnectivitySid, G->findVertices(),
148 isAllowedFragment, wantFurtherRefinement, emitKid, ParentFragmentCriteria );
149}
150
151} // namespace Fiber
152
153
154#endif // __FIBER_BASEOP_REFINEMENTRECURSION_HPP
reference emplace_front(_Args &&... __args)
bool empty() const noexcept
static SkeletonID nextRefinement(const SkeletonID &Sid, int refinement_increment)
Create a SkeletonID that is refined by a certain increment.
Definition SkeletonID.hpp:71
RefPtr< Skeleton > findVertices(int TotalRefinement=-1) const
Find the Skeleton describing the Vertices on this Grid.
Definition SkeletonMap.cpp:285
Given a fragmented field of curvilinear coordinates, (3D array of coordinates), build a uniform Grid ...
Definition FAQ.dox:2