30 #include "core/common/math/linearAlgebra/WPosition.h"
31 #include "core/common/WAssert.h"
33 #include <boost/graph/graph_traits.hpp>
34 #include <boost/graph/adjacency_list.hpp>
35 #include <boost/graph/dijkstra_shortest_paths.hpp>
36 #include <boost/property_map/property_map.hpp>
38 #include "WVisiTrace.h"
41 m_candidatePositions(),
44 m_dataChanged( false )
61 std::vector< double > opacityJumps( 0 );
62 std::vector< WPosition > positions( 0 );
64 for(
size_t id = 0;
id < candidates.size(); ++id )
66 opacityJumps.push_back( candidates[
id].first );
67 positions.push_back( candidates[
id].second );
78 std::vector< std::pair< int, int > > nodeRefs( 0 );
83 nodeRefs.push_back( std::make_pair( outerId, innerId ) );
91 std::vector< std::vector< int > > inverseRefs( 0 );
95 inverseRefs.push_back( std::vector< int >( 0 ) );
98 inverseRefs[outerId].push_back( counter );
113 typedef boost::adjacency_list< boost::listS, boost::vecS, boost::directedS,
114 boost::no_property, boost::property< boost::edge_weight_t, double > > graph_t;
115 typedef boost::graph_traits< graph_t >::vertex_descriptor vertex_descriptor;
116 typedef std::pair<int, int> Edge;
121 const int numVirtNodes = 2;
122 const int startNodeId = 0;
123 const int endNodeId = 1;
125 const int num_nodes = linearized.size() + numVirtNodes;
127 std::vector< std::string > name( 0 );
128 name.push_back(
"Start" );
129 name.push_back(
"End" );
130 for(
int id = 0;
id < num_nodes; ++id )
132 name.push_back( std::to_string(
id + numVirtNodes ) );
135 std::vector< Edge > edgeVector( 0 );
136 std::vector< double > distanceWeights( 0 );
137 std::vector< double > opacityWeights( 0 );
140 for(
auto candi : linearizedInverse[0] )
142 edgeVector.push_back( Edge( startNodeId, candi + numVirtNodes ) );
143 distanceWeights.push_back( 1 );
144 opacityWeights.push_back( 1 );
148 for(
size_t rayId = 0; rayId < linearizedInverse.size() - 1; ++rayId )
150 for(
size_t firstId = 0; firstId < linearizedInverse[rayId].size(); ++firstId )
152 for(
size_t secondId = 0; secondId < linearizedInverse[rayId+1].size(); ++secondId )
154 edgeVector.push_back( Edge( linearizedInverse[rayId][firstId] + numVirtNodes,
155 linearizedInverse[rayId+1][secondId] + numVirtNodes ) );
158 double distance = length( firstPos - secondPos );
159 distanceWeights.push_back( distance );
167 double maxDistance = 0;
168 for(
auto distance : distanceWeights )
170 if( distance > maxDistance )
172 maxDistance = distance;
175 for(
double& weight : distanceWeights )
177 weight /= maxDistance;
182 for(
auto candi : linearizedInverse[linearizedInverse.size()-1] )
184 edgeVector.push_back( Edge( candi + numVirtNodes, endNodeId ) );
185 distanceWeights.push_back( 1 );
186 opacityWeights.push_back( 1 );
189 WAssert( distanceWeights.size() == opacityWeights.size(),
"Internal error: Need as many opacities as positions." );
190 std::vector< double > overallWeights( distanceWeights.size() );
191 for(
size_t weightId = 0; weightId < overallWeights.size(); ++weightId )
193 overallWeights[weightId] = opacityWeights[weightId] * distanceWeights[weightId] * distanceWeights[weightId];
196 Edge* edge_array = &edgeVector[0];
197 double* weights = &overallWeights[0];
198 int num_arcs = edgeVector.size();
200 graph_t g( edge_array, edge_array + num_arcs, weights, num_nodes );
202 std::vector<vertex_descriptor> p( num_vertices( g ) );
203 std::vector<double> distResult( num_vertices( g ) );
204 vertex_descriptor s = vertex( startNodeId, g );
206 dijkstra_shortest_paths( g,
208 predecessor_map( boost::make_iterator_property_map( p.begin(), get( boost::vertex_index, g ) ) ).
209 distance_map( boost::make_iterator_property_map( distResult.begin(), get( boost::vertex_index, g ) ) ) );
211 std::vector< int > shortestPathIds( 0 );
213 int parentId = endNodeId;
214 shortestPathIds.push_back( parentId );
215 while( parentId != startNodeId )
217 parentId = p[parentId];
218 shortestPathIds.push_back( parentId );
220 std::reverse( shortestPathIds.begin(), shortestPathIds.end() );
222 for(
size_t id = 1;
id < shortestPathIds.size() - 1; ++id )
224 int rayId = linearized[shortestPathIds[id]-numVirtNodes].first;
225 int candidateId = linearized[shortestPathIds[id]-numVirtNodes].second;
This only is a 3d double vector.
std::vector< std::vector< WPosition > > m_candidatePositions
The candidate positions for all rays.
std::vector< std::vector< double > > m_candidateJumps
The opacity jumps belonging to the intervals of the candidate positions.
void performVisiTrace()
Optimization resulting in the desired 3D curve (m_curve3D).
std::vector< std::vector< int > > getInverseLinearizedNodesRefs() const
Get ids in the vector of getLinearizedNodesRefs from structure of m_candidatePositions.
std::vector< WPosition > getLine()
Get the final 3D line a vector of WPosition.
void addCandidatesForRay(const std::vector< std::pair< double, WPosition > > candidates)
Add candidate positions and corresponding opacity jump values for one viewing ray.
void reset()
Erases all data to be able to start a new VisiTrace computation.
std::vector< std::pair< int, int > > getLinearizedNodesRefs() const
Get an vector with reference ids for all nodes.
WVisiTrace()
Simple constructor performing initializations.
bool m_dataChanged
Indicates whether new data has been added since last VisiTrace computation.
std::vector< WPosition > m_curve3D
The 3D curve computed by VisiTrace.
void performDijkstra()
Create weighted graph and find shortest path from according to VisiTrace.