11 Structure::Structure(
int concurrency,
volatile bool* the_cancelFlag)
12 : Structure(
FreeSpace::ptr(nullptr),concurrency,the_cancelFlag)
20 concurrency(aconcurrency),
21 cancelFlag(the_cancelFlag)
60 Q_ASSERT(p->l==p->clone()->l);
61 p->clone()->l = p->l->clone();
62 Q_ASSERT(p->l!=p->clone()->l);
65 Q_ASSERT(p->h==p->clone()->h);
66 p->clone()->h = p->h->clone();
67 Q_ASSERT(p->h!=p->clone()->h);
80 p->clone()->setOwner(
this);
101 const_cast<FreeSpace::ptr&>(this->
fs).swap( const_cast<FreeSpace::ptr&>(that.
fs));
132 if (
fs->wrapRight() ||
fs->wrapTop()) {
169 if (
fs->wrapRight()) {
173 else if (
fs->wrapTop()) {
182 Q_ASSERT(i < fs->n-1);
228 merge(fringe,buddy, r1,r2);
255 for( ; u && v; u = u->
next(), v = v->next())
261 Q_ASSERT(u->
dir!=v->dir);
262 Q_ASSERT(u->
lower()+offset==v->lower());
263 Q_ASSERT(u->
upper()+offset==v->upper());
274 Q_ASSERT(r.
i0 >= 0 && r.
i1 <
fs->n);
275 Q_ASSERT(r.
j0 >= 0 && r.
j1 <
fs->m);
276 Q_ASSERT(r.
i0 < r.
i1);
277 Q_ASSERT(r.
j0 < r.
j1);
279 Q_ASSERT(r.
i0 < r.
i1);
280 Q_ASSERT(r.
j0 < r.
j1);
297 : owner(the_owner), node(nullptr)
306 if (concurrency <= 1 || (r.
width()==1 && r.
height()==1))
378 else if ((r.
i1-r.
i0) > (r.
j1-r.
j0)){
405 Q_ASSERT(this->
first(fringe).size()==this->
second(fringe).size());
408 for( ; i1 && j1; i1=i1->
next(), i2=i2->
next(), j1=j1->next(), j2=j2->
next())
411 Q_ASSERT(i1->
lower()==j1->lower());
415 Q_ASSERT(j1->upper()==j2->
upper());
417 if (i1->
upper() < j1->upper())
421 else if (i1->
upper() > j1->upper())
434 for ( ; i1; i1=i1->
next(), i2=i2->
next(), j1=j1->next(), j2=j2->
next())
450 for ( ; j1; i1=i1->
next(), i2=i2->
next(), j1=j1->next(), j2=j2->
next())
452 Q_ASSERT(j1->lower()==j1->upper());
457 this->
split2(i1, j1->upper(), i2);
464 Q_ASSERT(this->
first(fringe).size()==this->
second(fringe).size());
577 if ((*i1 == *i1n) && (*i2 == *i2n))
625 if ((L->l != K) && (L->h != K))
continue;
627 if (L->h==K) L->h = h;
628 if (L->l==K) L->l = l;
679 for( ; K && I; K=K->
next(), I=I->next(), K1=K1->
next(), I2=I2->
next())
712 if (!K1->
l) K1->
l = l2;
713 if (!K1->
h) K1->
h = h2;
750 for( ; K; K=K->
next())
756 if (K->
h && K->
h->
ori==fringe)
775 Q_ASSERT(K->
h->
twin(1)==I->twin(3));
783 if (K->
l && K->
l->
ori==fringe)
804 Q_ASSERT(K->
l->
twin(1)==I->twin(3));
816 Q_ASSERT(K3->
dir==K->
dir);
817 Q_ASSERT(K3->
ori==K->
ori);
822 if (!K->
l) K->
l = K3->
l;
823 if (!K->
h) K->
h = K3->
h;
824 Q_ASSERT(K->
l && K->
h);
855 list.insert_before(
copy,seg);
857 Q_ASSERT(
copy->next()==seg);
963 Q_ASSERT(ival.
l || ival.
h);
969 Q_ASSERT(ival.
l && ival.
h);
978 Q_ASSERT(ival.
l || ival.
h);
984 Q_ASSERT(ival.
l && ival.
h);
1005 Q_ASSERT(i2->
twin(1)==i4);
1006 Q_ASSERT(i2->
twin(2)==i3);
1007 Q_ASSERT(i2->
twin(3)==i1);
1008 Q_ASSERT(i2->
twin(4)==i2);
1010 Q_ASSERT(i3->
twin(1)==i1);
1011 Q_ASSERT(i3->
twin(2)==i2);
1012 Q_ASSERT(i3->
twin(3)==i4);
1013 Q_ASSERT(i3->
twin(4)==i3);
1016 Q_ASSERT(!i1 && !i2 && !i3 && !i4);
1024 :
str(astr), current(ival.l), last(ival.h)
1026 if (!current) current = ifnull;
1027 if (!last) last = ifnull;
1029 Q_ASSERT(current && last);
1030 Q_ASSERT(current->dir == last->dir);
1035 :
str(astr), current(a), last(b)
1037 Q_ASSERT(current && last);
1038 Q_ASSERT(current->dir == last->dir);
1053 return out <<
"{" <<
str.bottom() << std::endl
1054 <<
" "<<
str.top() << std::endl
1055 <<
" "<<
str.left() << std::endl
1056 <<
" "<<
str.right() <<
"}" << std::endl;
void testCancelFlag()
check for user interrupion The canceFlag should be polled in regular intervals. If the user requested...
void calculateColumns(int i, int j)
compute a region of the reachability structure. may span the double free-space!.
StructureTask(Structure *owner)
constructor with Structure
BoundaryList & first(Orientation ori)
bool empty_see_through_interval(Pointer p)
test intersection of intervals. Assumes a SEE_THROUGH segment.
StructureIterator & operator++()
pre-increment; advance the iterator
static assert_hook after_single_cell
void insert_last(BLinkedListElement *el)
insert a new element at the end of the list; the list takes ownership of the element....
void singleCell(int i, int j)
create a BoundarySegment from one cell of the free-space-diagram
reachable: other intervals are reachable
int j1
top bound, exclusive
bottom and left part of the reachability structure
void split2(Pointer &a, double x, Pointer &b)
split a reachabiliy segment and its opposite segment
BoundaryList & second(Orientation ori)
virtual ~MergeTask()
destructor; releases memory
a sub-task, computing a region of the reachability structure
task object for parallel execution. When the reachability structur is computed in parallel threads,...
static StructureTask * createTask(Structure *owner, const frechet::Rect &r, tbb::flow::graph &graph, int concurrency)
static constructor
see-through: other interals are visible with a straight line
global definitions for all algorithms.
StructureTask * child2
prerquisite task; only after child1 and child2 are finished, start the merging task
void calcRecursive(const Rect &r)
Divide & Conquer algorithm. Merge regions recursively. Makes use of paralel threads.
tbb::flow::continue_msg msg_t
used to connect nodes in the dependency graph
const Orientation ori
horizontal or vertical
non-accesible. no interval is reachable from this one
static assert_hook before_merge
data::LinkedList< BoundarySegment > BoundaryList
a double-linked list of reachability segments. makes up one of the four edges of a reachability struc...
int concat(BLinkedList &that)
append all elements of another list, taking ownership of the new elements
Direction
direction of a Pointer inside the reachability structure.
Pointer current
current location of the iterator
static assert_hook after_merge
The StructureIterator class.
void(* assert_hook)(Structure *, const Rect *, Structure *, const Rect *, Orientation)
hooks for Unit Tests. Only used in debug mode.
thrown by long-runner tasks
Pointer nextReachable(Pointer p)
find next reachable segment
struct frechet::reach::BoundarySegment::@4 temp
temporary data used during merge and split operations
boundary interval in the reachability structure. Represents an interval on the boundary of the FreeSp...
Pointer prevReachable(Pointer p)
find previous reachable segment
virtual ~StructureTask()
destructor
void mergeConsecutive(Orientation ori)
could be used to merge indentical intervals. Reduces the number of intervals (and thus the complexity...
describes l,h pointers. Both pointers are assumed to point into the same rectangle section (right-top...
Structure * owner
the underlying reachability structure
void copy(const Structure &that)
assigment function
int compare_pointers(Pointer a, Pointer b)
compare two pointers on opposite parts of a reachability structure (eitehr left->right-top,...
void swap(Structure &that)
swap content with another object
BoundaryList & boundary(Orientation ori, Direction dir)
StructureIterator(const Structure &str, Pointer first, Pointer last)
constructor with two segments
void merge(Orientation fringe, Structure &that, const Rect &r1, const Rect &r2)
merge this structure with another structure
volatile bool * cancelFlag
used when running ia a background thread to indicate cancellation by the user
MergeTask(Structure *owner, frechet::Rect r, tbb::flow::graph &graph, int concurrency)
default constructor
Structure & operator=(const Structure &that)
assigment operator
virtual ~Structure()
destructor; releases all memory
Structure(int concurrency=1, volatile bool *cancelFlag=nullptr)
empty constructor
void shift(Point offset)
shift the reachability structure by a given offset. The shifted second copy is then merged to compute...
BoundarySegment * Pointer
(dumb) pointer to a BoundarySegment object
static bool assertPointerInterval(Pointer p, const PointerInterval &ival)
for debugging and unit tests, check if reachability intervals are consistent
int i1
right bound, exclusive
Type type
reachability label
QPointF Point
a point in the plane; with double floating point precision. This type is heavily used throughout all ...
void synchIntervals(Orientation fringe, Structure &that)
before mergin two reachabiliry structures, its intervals must be synchronized
a very simple Rectangle structure, with integer boundaries.
int j0
top bound, inclusive
Pointer split(Pointer seg, double y, Pointer twin)
split a reachabiliy segment Adjust l,h pointers into that segment.
void crossLink(Pointer i1, Pointer i2, Pointer j1, Pointer j2)
set up links between four opposite segments. This pointer chain will be used to traverse a reachabili...
std::ostream & operator<<(std::ostream &out, const BoundaryList &list)
print operator for debugging
void updatePointers(Pointer K, Pointer l, Pointer h, Pointer K1)
update all l,h, pointers that point into a segment
bool contains(double x) const
containment test
Pointer calculateSingle()
compute the reachability structure for an open curve, based on a single free-space-diagram.
right and top part of the reachability structure
void clear()
clears pointers, keep interval bounds
Orientation
Segment Orientation.
tbb::flow::continue_node< msg_t > node_t
a node in the dependency graph
void swap(LinkedList< T > &that)
exchange all elements with another list, taking ownership of the new elements
void takeOwnership()
for debugging: fill in owner pointers
const FreeSpace::ptr fs
the underlying free-space; may be nullptr
CalculateTask(Structure *owner, frechet::Rect r, tbb::flow::graph &graph)
default constructor
Pointer calculate()
compute the reachability structure from the underlying free-space diagram. Uses a divide-and-conquere...
second segment = right and top edge
const Direction dir
left/right or bottom/top
void doCalcRecursive(const Rect &r)
Merge regions recursively. Uses only one thread.
const Structure & str
the associated reachability structure
Pointer l
points to the lowest segment of the interval
int compare_interval(Pointer a, Pointer b)
compare two pointers in the same part of a reachability structure (either right-top,...
StructureTask * child1
prerquisite task; only after child1 and child2 are finished, start the merging task
int i0
left bound, inclusive
Pointer next(Pointer p) const
used when traversing reachability segments. Traversal direction is discussed in frechet::reach::Direc...
void markNonAccesible(Orientation fringe, Structure &that)
mark non-accesible segments
virtual void start() override
computes the reachability structure for the given region
Orientation opposite(Orientation ori)
The FreeSpace class models the Free-Space Diagram calculated from two curves.
virtual void start() override
perform the merging
int concurrency
number of parallel threads to use
Structure buddy
structure to merge with
The Reachability Structure; maintains a list of intervals on the border of Free Space,...
Pointer prev(Pointer p) const
used when traversing reachability segments. Traversal direction is discussed in frechet::reach::Direc...
Pointer h
points to the highest segment of the interval
Pointer findStartingPoint(Orientation edge)
after the reachability structure is computed, find the starting interval of a feasible path....
first segment = bottom and left edge
virtual void start()=0
abstract method for starting a task
an interval of two double values.
node_t * node
a node in the dependency graph
Pointer _twin
points to a segment on the opposite edge of the reachability structure. twins have the same boundary ...
void scanAndMerge(Pointer K, Orientation fringe)
scan and merge one segment
boost::shared_ptr< FreeSpace > ptr
smart pointer to FreeSpace object
bool empty_interval(Pointer a, Pointer b)
test intersection of intervals
static bool assertSynchedIntervals(Pointer i1, Pointer i2, Pointer i3, Pointer i4)
for debugging and unit tests, check if reachability intervals are consistent
a sub-taks, performing the merging of two reachability structures
Pointer calculateDouble()
compute the reachability structure for a closed curve, based on a double-free-space-diagram.