Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
VTK
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Uwe Siems
VTK
Commits
f9c0cd37
Commit
f9c0cd37
authored
1 year ago
by
Cory Quammen
Browse files
Options
Downloads
Patches
Plain Diff
Revert "vtkBlockSortHelper: Attempt to handle disconnected blocks"
This reverts commit
42c0d5c9
.
parent
a063925b
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Documentation/release/dev/fix-volume-rendering-disconnected-blocks.md
+0
-4
0 additions, 4 deletions
...n/release/dev/fix-volume-rendering-disconnected-blocks.md
Rendering/Volume/vtkBlockSortHelper.h
+75
-195
75 additions, 195 deletions
Rendering/Volume/vtkBlockSortHelper.h
with
75 additions
and
199 deletions
Documentation/release/dev/fix-volume-rendering-disconnected-blocks.md
deleted
100644 → 0
+
0
−
4
View file @
a063925b
# Fix volume rendering issues with disconnected grids in composite datasets
The multi-block volume mapper can now correctly sort and render composite datasets
which have gaps between adjacent grids.
This diff is collapsed.
Click to expand it.
Rendering/Volume/vtkBlockSortHelper.h
+
75
−
195
View file @
f9c0cd37
...
...
@@ -8,7 +8,6 @@
#ifndef vtkBlockSortHelper_h
#define vtkBlockSortHelper_h
#include
"vtkBoundingBox.h"
#include
"vtkCamera.h"
#include
"vtkDataSet.h"
#include
"vtkMatrix4x4.h"
...
...
@@ -17,8 +16,6 @@
#include
"vtkVector.h"
#include
"vtkVectorOperators.h"
#include
<set>
#include
<stack>
#include
<vector>
namespace
vtkBlockSortHelper
...
...
@@ -37,22 +34,6 @@ inline void GetBounds(vtkDataSet* first, double bds[6])
first
->
GetBounds
(
bds
);
}
template
<
typename
ValueT
>
struct
BlockGroup
:
public
std
::
vector
<
ValueT
>
{
void
GetBounds
(
double
bds
[
6
])
{
vtkBoundingBox
bbox
;
for
(
auto
it
=
this
->
begin
();
it
!=
this
->
end
();
++
it
)
{
double
localBds
[
6
];
vtkBlockSortHelper
::
GetBounds
(
*
it
,
localBds
);
bbox
.
AddBounds
(
localBds
);
}
bbox
.
GetBounds
(
bds
);
}
};
/**
* operator() for back-to-front sorting.
*
...
...
@@ -109,29 +90,22 @@ struct BackToFront
// -1 if first is closer than second
// 0 if unknown
// 1 if second is closer than first
// allowDisconnected is used to permit the comparisons of bounding boxes whose faces/edges do not
// touch at all.
// 1 if second is farther than first
template
<
typename
TT
>
inline
int
CompareOrderWithUncertainty
(
TT
&
first
,
TT
&
second
,
bool
allowDisconnected
=
false
)
inline
int
CompareOrderWithUncertainty
(
TT
&
first
,
TT
&
second
)
{
double
abounds
[
6
],
bbounds
[
6
];
vtkBlockSortHelper
::
GetBounds
<
TT
>
(
first
,
abounds
);
vtkBlockSortHelper
::
GetBounds
<
TT
>
(
second
,
bbounds
);
return
CompareBoundsOrderWithUncertainty
(
abounds
,
bbounds
,
allowDisconnected
);
return
CompareBoundsOrderWithUncertainty
(
abounds
,
bbounds
);
}
// -1 if first is closer than second
// 0 if unknown
// 1 if second is closer than first
// allowDisconnected is used to permit the comparisons of bounding boxes whose faces/edges do not
// touch at all.
inline
int
CompareBoundsOrderWithUncertainty
(
const
double
abounds
[
6
],
const
double
bbounds
[
6
],
bool
allowDisconnected
=
false
)
// 1 if second is farther than first
inline
int
CompareBoundsOrderWithUncertainty
(
const
double
abounds
[
6
],
const
double
bbounds
[
6
])
{
// bounds of the projection of block A onto block B
double
bboundsP
[
6
];
// bounds of the projection of block B onto block A
double
aboundsP
[
6
];
for
(
int
i
=
0
;
i
<
6
;
++
i
)
{
...
...
@@ -156,11 +130,6 @@ struct BackToFront
}
}
// Determine the dimensionality of the projection
/// dims == 3 | Overlap? Yes | Type: Volume
/// dims == 2 | Overlap? Yes | Type: Plane
/// dims == 1 | Overlap? Yes | Type: Line
/// dims == 0 | Overlap? No | Type: None
int
dims
=
0
;
int
degenDims
=
0
;
int
degenAxes
[
3
];
...
...
@@ -181,7 +150,6 @@ struct BackToFront
// overlapping volumes?
// in that case find the two largest dimensions
// the 3d overlap is collapsed down to a 2d overlap.
// geneally this should not happen
if
(
dims
==
3
)
{
...
...
@@ -218,8 +186,7 @@ struct BackToFront
double
atoblength
=
vtkMath
::
Normalize
(
atobdir
);
// no comment on blocks that do not touch
if
(
!
allowDisconnected
&&
(
fabs
(
aboundsP
[
degenAxes
[
0
]
*
2
]
-
bboundsP
[
degenAxes
[
0
]
*
2
])
>
0.01
*
atoblength
))
if
(
fabs
(
aboundsP
[
degenAxes
[
0
]
*
2
]
-
bboundsP
[
degenAxes
[
0
]
*
2
])
>
0.01
*
atoblength
)
{
return
0
;
}
...
...
@@ -260,24 +227,25 @@ struct BackToFront
}
};
template
<
typename
RandomIt
>
class
GraphNode
#ifdef MB_DEBUG
template
<
class
RandomIt
>
class
gnode
{
public:
RandomIt
Value
;
bool
Visited
=
false
;
std
::
set
<
GraphN
ode
<
RandomIt
>*>
Neighbors
;
std
::
vector
<
gn
ode
<
RandomIt
>*>
Closer
;
};
template
<
typename
RandomIt
>
bool
operator
==
(
GraphN
ode
<
RandomIt
>
const
&
lhs
,
GraphN
ode
<
RandomIt
>
const
&
rhs
)
template
<
class
RandomIt
>
bool
operator
==
(
gn
ode
<
RandomIt
>
const
&
lhs
,
gn
ode
<
RandomIt
>
const
&
rhs
)
{
return
lhs
.
Value
==
rhs
.
Value
&&
lhs
.
Neighbors
==
rhs
.
Neighbors
;
return
lhs
.
Value
==
rhs
.
Value
&&
lhs
.
Closer
==
rhs
.
Closer
;
}
template
<
typename
RandomIt
>
bool
findCycle
(
GraphN
ode
<
RandomIt
>&
start
,
std
::
vector
<
GraphN
ode
<
RandomIt
>>&
graph
,
std
::
vector
<
GraphN
ode
<
RandomIt
>>&
active
,
std
::
vector
<
GraphN
ode
<
RandomIt
>>&
loop
)
template
<
class
RandomIt
>
bool
findCycle
(
gn
ode
<
RandomIt
>&
start
,
std
::
vector
<
gn
ode
<
RandomIt
>>&
graph
,
std
::
vector
<
gn
ode
<
RandomIt
>>&
active
,
std
::
vector
<
gn
ode
<
RandomIt
>>&
loop
)
{
if
(
start
.
Visited
)
{
...
...
@@ -288,7 +256,7 @@ bool findCycle(GraphNode<RandomIt>& start, std::vector<GraphNode<RandomIt>>& gra
active
.
push_back
(
start
);
// traverse the closer nodes one by one depth first
for
(
auto
&
close
:
start
.
Neighbors
)
for
(
auto
&
close
:
start
.
Closer
)
{
if
(
close
->
Visited
)
{
...
...
@@ -317,158 +285,64 @@ bool findCycle(GraphNode<RandomIt>& start, std::vector<GraphNode<RandomIt>>& gra
start
.
Visited
=
true
;
return
false
;
}
#endif
template
<
typename
RandomIt
>
void
VisitNeighborsDFS
(
GraphNode
<
RandomIt
>&
start
,
std
::
set
<
RandomIt
>&
connected
)
template
<
class
RandomIt
,
typename
T
>
inline
void
Sort
(
RandomIt
bitr
,
RandomIt
eitr
,
BackToFront
<
T
>&
me
)
{
// use a stack instead of callstack for dfs
std
::
stack
<
GraphNode
<
RandomIt
>*>
nodeStack
;
nodeStack
.
push
(
&
start
);
while
(
!
nodeStack
.
empty
())
{
auto
node
=
nodeStack
.
top
();
nodeStack
.
pop
();
// insert into `connected` only if node was not visited.
if
(
!
node
->
Visited
)
{
node
->
Visited
=
true
;
connected
.
insert
(
node
->
Value
);
}
// push all unvisited neighbors onto the stack.
for
(
auto
&
neighbor
:
start
.
Neighbors
)
{
if
(
!
neighbor
->
Visited
)
{
nodeStack
.
push
(
neighbor
);
}
}
}
}
auto
start
=
bitr
;
template
<
typename
RandomIt
,
typename
BlockGroupType
=
typename
vtkBlockSortHelper
::
BlockGroup
<
typename
RandomIt
::
value_type
>
>
std
::
vector
<
BlockGroupType
>
FindConnectedBlocks
(
std
::
vector
<
GraphNode
<
RandomIt
>>&
graph
)
{
// unvisit all nodes.
for
(
auto
&
node
:
graph
)
{
node
.
Visited
=
false
;
}
std
::
vector
<
BlockGroupType
>
result
;
for
(
auto
&
node
:
graph
)
{
// skip if the node was visited.
if
(
node
.
Visited
)
{
continue
;
}
std
::
set
<
RandomIt
>
connected
;
VisitNeighborsDFS
(
node
,
connected
);
if
(
!
connected
.
empty
())
{
BlockGroupType
blocks
;
blocks
.
reserve
(
connected
.
size
());
for
(
auto
&
elem
:
connected
)
{
blocks
.
emplace_back
(
*
elem
);
}
result
.
emplace_back
(
blocks
);
}
}
return
result
;
}
// brute force for testing
template
<
typename
ValueType
,
typename
B2FType
>
/// Sorts `input` vector in-place from front-to-back.
inline
void
SortFrontToBackImplementation
(
std
::
vector
<
ValueType
>&
input
,
BackToFront
<
B2FType
>&
b2f
,
bool
allowDisconnected
=
false
)
{
std
::
vector
<
ValueType
>
result
;
const
std
::
size_t
numNodes
=
input
.
size
();
result
.
reserve
(
numNodes
);
// loop over the `input` vector in search of a block that is the front most.
// as we discover such blocks, they are moved from `input` to `result` and
// the `input` vector is shortened in length. Repeat this process until the
// last block in the `input` vector is reached.
for
(
auto
it
=
input
.
begin
();
it
!=
input
.
end
();)
std
::
vector
<
typename
RandomIt
::
value_type
>
working
;
std
::
vector
<
typename
RandomIt
::
value_type
>
result
;
working
.
assign
(
bitr
,
eitr
);
size_t
numNodes
=
working
.
size
();
#ifdef MB_DEBUG
// check for any short loops and debug
for
(
auto
it
=
working
.
begin
();
it
!=
working
.
end
();
++
it
)
{
auto
it2
=
input
.
begin
();
for
(;
it2
!=
input
.
end
();
++
it2
)
auto
it2
=
it
;
it2
++
;
for
(;
it2
!=
working
.
end
();
++
it2
)
{
// if `it2` is closer than `it`, then `it` is not the closest block,
// so break and try the next block from `input` vector.
if
(
it
!=
it2
&&
b2f
.
CompareOrderWithUncertainty
(
*
it
,
*
it2
,
allowDisconnected
)
>
0
)
int
comp1
=
me
.
CompareOrderWithUncertainty
(
*
it
,
*
it2
);
int
comp2
=
me
.
CompareOrderWithUncertainty
(
*
it2
,
*
it
);
if
(
comp1
*
comp2
>
0
)
{
// not a winner
break
;
me
.
CompareOrderWithUncertainty
(
*
it
,
*
it2
);
me
.
CompareOrderWithUncertainty
(
*
it2
,
*
it
)
;
}
}
if
(
it2
==
input
.
end
())
{
// found a winner, add it to the `result`, remove from the input set and then restart
result
.
push_back
(
*
it
);
input
.
erase
(
it
);
it
=
input
.
begin
();
}
else
{
++
it
;
}
}
if
(
result
.
size
()
!=
numNodes
)
{
vtkGenericWarningMacro
(
<<
"SortFrontToBackImplementation failed with allowDisconnected="
<<
allowDisconnected
);
// do not modify input vector.
return
;
}
input
.
assign
(
result
.
begin
(),
result
.
end
());
}
template
<
typename
RandomIt
,
typename
T
>
inline
void
Sort
(
RandomIt
bitr
,
RandomIt
eitr
,
BackToFront
<
T
>&
me
)
{
auto
start
=
bitr
;
// brute force for testing
using
ElementType
=
typename
RandomIt
::
value_type
;
std
::
vector
<
ElementType
>
working
;
std
::
vector
<
ElementType
>
result
;
working
.
assign
(
bitr
,
eitr
);
const
size_t
numNodes
=
working
.
size
();
// build a graph that describes neighbors of each block.
std
::
vector
<
GraphNode
<
RandomIt
>>
graph
;
graph
.
reserve
(
numNodes
);
// build the graph
std
::
vector
<
gnode
<
RandomIt
>>
graph
;
for
(
auto
it
=
working
.
begin
();
it
!=
working
.
end
();
++
it
)
{
GraphN
ode
<
RandomIt
>
anode
;
gn
ode
<
RandomIt
>
anode
;
anode
.
Value
=
it
;
graph
.
emplace
_back
(
anode
);
graph
.
push
_back
(
anode
);
}
for
(
auto
&
node1
:
graph
)
for
(
auto
&
git
:
graph
)
{
for
(
auto
&
n
ode2
:
graph
)
for
(
auto
&
n
ext
:
graph
)
{
if
(
node1
.
Value
!=
node2
.
Value
&&
me
.
CompareOrderWithUncertainty
(
*
node1
.
Value
,
*
node2
.
Value
)
!=
0
)
if
(
git
.
Value
!=
next
.
Value
&&
me
.
CompareOrderWithUncertainty
(
*
git
.
Value
,
*
next
.
Value
)
>
0
)
{
// node2 is a face/line neighbor of node1
node1
.
Neighbors
.
insert
(
&
node2
);
git
.
Closer
.
push_back
(
&
next
);
}
}
}
#ifdef MB_DEBUG
// graph constructed, now look for a loop
std
::
vector
<
GraphN
ode
<
RandomIt
>>
active
;
std
::
vector
<
GraphN
ode
<
RandomIt
>>
loop
;
for
(
auto
&
node
:
graph
)
std
::
vector
<
gn
ode
<
RandomIt
>>
active
;
std
::
vector
<
gn
ode
<
RandomIt
>>
loop
;
for
(
auto
&
gval
:
graph
)
{
loop
.
clear
();
if
(
findCycle
(
node
,
graph
,
active
,
loop
))
if
(
findCycle
(
gval
,
graph
,
active
,
loop
))
{
vtkVector3d
dir
=
me
.
CameraViewDirection
;
dir
.
Normalize
();
...
...
@@ -484,35 +358,41 @@ inline void Sort(RandomIt bitr, RandomIt eitr, BackToFront<T>& me)
}
#endif
// break graph into groups of blocks which are connected by face/line
// The blocks inside the group are all connected.
using
BlockGroupType
=
BlockGroup
<
ElementType
>
;
std
::
vector
<
BlockGroupType
>
blockGroups
=
vtkBlockSortHelper
::
FindConnectedBlocks
(
graph
);
// sort elements inside each of the block group.
for
(
auto
&
blockGroup
:
blockGroups
)
// loop over items and find the first that is not in front of any others
for
(
auto
it
=
working
.
begin
();
it
!=
working
.
end
();)
{
vtkBlockSortHelper
::
SortFrontToBackImplementation
(
blockGroup
,
me
,
/*allowDisconnected=*/
false
);
}
// now sort the overall blockGroup(s).
vtkBlockSortHelper
::
SortFrontToBackImplementation
(
blockGroups
,
me
,
/*allowDisconnected=*/
true
);
// collect all blocks in the back-to-front sorted order.
result
.
reserve
(
numNodes
);
for
(
const
BlockGroupType
&
blocks
:
blockGroups
)
{
for
(
const
ElementType
&
block
:
blocks
)
auto
it2
=
working
.
begin
();
for
(;
it2
!=
working
.
end
();
++
it2
)
{
result
.
push_back
(
block
);
// if another block is in front of this block then this is not the
// closest block
if
(
it
!=
it2
&&
me
.
CompareOrderWithUncertainty
(
*
it
,
*
it2
)
>
0
)
{
// not a winner
break
;
}
}
if
(
it2
==
working
.
end
())
{
// found a winner, add it to the results, remove from the working set and then restart
result
.
push_back
(
*
it
);
working
.
erase
(
it
);
it
=
working
.
begin
();
}
else
{
++
it
;
}
}
if
(
result
.
size
()
!=
numNodes
)
{
vtkGenericWarningMacro
(
"sorting failed"
);
// for whatever reason, sorting failed, return without modifying `start`
return
;
}
// copy results to original container
std
::
reverse_copy
(
result
.
begin
(),
result
.
end
(),
start
);
}
}
;
VTK_ABI_NAMESPACE_END
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment