25 #define _USE_MATH_DEFINES
33 #include "WAngleHelper.h"
34 #include "WConnectorData.h"
35 #include "WFiberHandler.h"
36 #include "WKeyboardHandler.h"
37 #include "WMPointConnector.h"
39 static const osg::Vec4 COLOR_SEL_POINT( 255.0 / 255.0, 190.0 / 255.0, 7.0 / 255.0, 1.0 );
40 static const osg::Vec4 COLOR_SEL_FIBER( 30.0 / 255.0, 136.0 / 255.0, 229.0 / 255.0, 1.0 );
41 static const osg::Vec4 COLOR_PRE_POINT( 255.0 / 255.0, 0.0 / 255.0, 0.0 / 255.0, 1.0 );
71 return "Point Connector";
76 return "Allows user to manually connect points to fibers.";
93 auto updateFunction = [
this]( auto )
100 m_enableSAPT = assistanceGroup->addProperty(
"Enable SAPT ",
"Enable Semi-Automatic-Particle-Tracking",
true );
101 m_enablePrediction = assistanceGroup->addProperty(
"Enable prediction",
"Enables the prediction of tracks",
true, updateFunction );
102 m_enableSizes = assistanceGroup->addProperty(
"Enable sizes",
"Enables the point size based on the cluster size",
false,
104 m_enableAdaptiveVisibility = assistanceGroup->addProperty(
"Enable adaptive visibility",
"Enable adaptive visibility using a cone",
true,
106 m_adaptiveVisibilityAngle = assistanceGroup->addProperty(
"Adaptive visibility angle",
"Adaptive visibility angle", 10.0, updateFunction );
110 m_hiddenOpacity = assistanceGroup->addProperty(
"Hidden point opacity",
"Changes the opacity of the hidden points", 0.1, updateFunction );
114 m_scaling = assistanceGroup->addProperty(
"Scaling",
"Changes the scaling",
WPosition( 1.0, 1.0, 1.0 ), updateFunction );
125 boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3 ) );
146 std::shared_ptr< WProgress > progressBar(
new WProgress(
"Work event queue..." ) );
153 std::vector< std::function< void() > > qu(
m_eventQueue );
165 progressBar->finish();
192 pointGroup->addProperty(
"Activate",
"Activates the point renderer",
true,
195 pointGroup->addProperty(
m_pointRenderer->getProperties()->getProperty(
"Point size" ) );
206 fiberGroup->addProperty(
"Activate",
"Activates the fiber display",
true,
209 fiberGroup->addProperty(
m_fiberDisplay->getProperties()->getProperty(
"Line Rendering" )->toPropGroup()->getProperty(
"Line width" ) );
214 WPropBool active = mod->getProperties()->getProperty(
"active" )->toPropBool();
215 active->set( !active->get() );
231 debugLog() <<
"Invalid Data. Break.";
237 std::shared_ptr< WValueSet< float > > clusterSizes;
239 if( points->getData().type() ==
typeid( std::tuple< SPFloatVector > ) )
241 edeps = std::get< 0 >( std::any_cast< std::tuple< SPFloatVector > >( points->getData() ) );
243 else if( points->getData().type() ==
typeid( std::tuple< SPSizeVector > ) )
245 eventIDs = std::get< 0 >( std::any_cast< std::tuple< SPSizeVector > >( points->getData() ) );
247 else if( points->getData().type() ==
typeid( std::tuple< SPFloatVector, SPSizeVector > ) )
249 edeps = std::get< 0 >( std::any_cast< std::tuple< SPFloatVector, SPSizeVector > >( points->getData() ) );
250 eventIDs = std::get< 1 >( std::any_cast< std::tuple< SPFloatVector, SPSizeVector > >( points->getData() ) );
252 else if( points->getData().type() ==
typeid( std::shared_ptr<
WValueSet< float > > ) )
254 clusterSizes = std::any_cast< std::shared_ptr< WValueSet< float > > >( points->getData() );
263 for(
size_t pointIdx = 0; pointIdx < points->size(); ++pointIdx )
265 osg::Vec3 vertex = points->operator[]( pointIdx );
267 points->getColor( pointIdx ),
268 edeps ? edeps->at( pointIdx ) : 0.0,
269 clusterSizes ? clusterSizes->getScalar( pointIdx ) : 0.0 );
273 size_t eventID = eventIDs->at( pointIdx );
275 while( fibers->size() <= eventID )
277 m_fiberHandler->addFiber(
"Track " + boost::lexical_cast< std::string >( fibers->size() ),
true,
false );
280 ( fibers->begin() + eventID )->push_back( vertex );
284 for(
size_t idx = fibers->size() - 1; idx > 0; idx-- )
286 if( fibers->at( idx ).size() <= 1 )
321 if( fiber.size() < 2 )
326 for(
size_t idx = 0; idx <
m_connectorData->getVertices()->size(); idx++ )
329 double layerDiffFront = ( fiber.front().z() - vertex.z() ) / 5.5;
330 double layerDiffBack = ( vertex.z() - fiber.back().z() ) / 5.5;
332 if( ( ( layerDiffFront <= 3 && layerDiffFront > 0 && !
isAdaptivelyHidden( vertex, &fiber.front() ) )
333 || ( layerDiffBack <= 3 && layerDiffBack > 0 && !
isAdaptivelyHidden( vertex, &fiber.back() ) ) )
366 for(
size_t idx = 0; idx <
m_connectorData->getVertices()->size(); idx++ )
369 osg::Vec4 color( 1.0, 1.0, 1.0, 1.0 );
371 vertices->push_back( vertex.x() *
m_scaling->get().x() );
372 vertices->push_back( vertex.y() *
m_scaling->get().y() );
373 vertices->push_back( vertex.z() *
m_scaling->get().z() );
378 color = COLOR_SEL_POINT;
382 color = COLOR_SEL_FIBER;
386 color = COLOR_PRE_POINT;
393 colors->push_back( color.x() );
394 colors->push_back( color.y() );
395 colors->push_back( color.z() );
396 colors->push_back( color.w() );
399 std::any data = NULL;
433 if( fiber.size() < 2 )
438 auto it = std::find( fiber.begin(), fiber.end(), selected );
439 osg::Vec3 before = osg::Vec3( 0.0, 0.0, 1.0 );
440 if( it != fiber.end() && it != fiber.begin() )
447 double layerDiff = abs( selected.z() - vertex.z() ) / 5.5;
451 return angle > checkAngle && angle < ( 180.0 - checkAngle );
498 float size =
m_pointRenderer->getProperties()->getProperty(
"Point size" )->toPropDouble()->get();
499 for(
size_t idx = 0; idx <
m_connectorData->getVertices()->size(); idx++ )
503 float localSize = size;
509 float hit =
hitVertex( cameraPosition, direction, vertex, localSize );
512 float dis = ( vertex - cameraPosition ).length2();
519 else if( dis < distance )
532 osg::Vec3 oc = rayStart - vertex;
533 float a = rayDir * rayDir;
534 float b = 2.0 * ( oc * rayDir );
535 float c = ( oc * oc ) - radius * radius;
536 float discriminant = b * b - 4 * a * c;
538 if( discriminant < 0.0 )
542 else if( discriminant == 0.0 )
548 float sqrtDis = sqrt( discriminant );
549 float numerator = -b - sqrtDis;
550 if( numerator > 0.0 )
552 return numerator / ( 2.0 * a );
555 numerator = -b + sqrtDis;
556 if( numerator > 0.0 )
558 return numerator / ( 2.0 * a );
574 std::shared_ptr< std::vector< float > > vertices = std::shared_ptr< std::vector< float > >(
new std::vector< float >() );
575 std::shared_ptr< std::vector< float > > colors = std::shared_ptr< std::vector< float > >(
new std::vector< float >() );
576 std::shared_ptr< std::vector< size_t > > lineStartIndexes = std::shared_ptr< std::vector< size_t > >(
new std::vector< size_t >() );
577 std::shared_ptr< std::vector< size_t > > lineLength = std::shared_ptr< std::vector< size_t > >(
new std::vector< size_t >() );
578 std::shared_ptr< std::vector< size_t > > verticesReverse = std::shared_ptr< std::vector< size_t > >(
new std::vector< size_t >() );
580 for(
size_t idx = 0; idx <
m_fiberHandler->getFibers()->size(); idx++ )
583 if( fiber.size() < 2 )
588 lineStartIndexes->push_back( vertices->size() / 3 );
589 lineLength->push_back( fiber.size() );
591 osg::Vec4 color( 0.0, 0.0, 0.0, 1.0 );
594 color = COLOR_SEL_FIBER;
602 for(
size_t vIdx = 0; vIdx < fiber.size(); vIdx++ )
604 osg::Vec3 vertex = fiber[vIdx];
605 vertices->push_back( vertex.x() *
m_scaling->get().x() );
606 vertices->push_back( vertex.y() *
m_scaling->get().y() );
607 vertices->push_back( vertex.z() *
m_scaling->get().z() );
609 colors->push_back( color.x() );
610 colors->push_back( color.y() );
611 colors->push_back( color.z() );
612 colors->push_back( color.w() );
614 verticesReverse->push_back( idx );
627 if( vertices->size() == 0 )
633 fibers->addColorScheme( colors,
"Connection",
"Color fibers based on their connection." );
634 fibers->setSelectedColorScheme( 3 );
659 osg::Matrix VP = camera->getViewMatrix() * camera->getProjectionMatrix();
661 osg::Matrix inverseVP;
662 inverseVP.invert( VP );
664 osg::Vec3 nearPoint( x, y, -1.0f );
665 osg::Vec3 farPoint( x, y, 1.0f );
666 nearPoint = nearPoint * inverseVP;
667 farPoint = farPoint * inverseVP;
669 osg::Vec3 direction = farPoint - nearPoint;
670 direction.normalize();
684 for(
auto vertex = positions.begin(); vertex != positions.end(); )
688 positions.erase( vertex );
697 auto start = std::chrono::high_resolution_clock::now();
698 size_t amount = positions.size();
702 auto end = std::chrono::high_resolution_clock::now();
703 std::chrono::duration< double > elapsed = end - start;
704 wlog::debug(
"PointConnector" ) <<
"SAPT " << amount <<
" points in " << elapsed.count() <<
" seconds";
707 if( positions.empty() )
712 m_fiberHandler->addVerticesToFiber( std::vector< osg::Vec3 >( positions.begin(), positions.end() ),
m_fiberHandler->getSelectedFiber() );
721 for(
auto vertex = positions.begin(); vertex != positions.end(); )
723 if(
m_fiberHandler->getFiberOfPoint( *vertex, &idx ) && idx == fibIdx )
729 positions.erase( vertex );
733 if( positions.empty() )
738 m_fiberHandler->removeVerticesFromFiber( std::vector< osg::Vec3 >( positions.begin(), positions.end() ), fibIdx );
748 float mouseX = x * 2.0 - 1.0;
749 float mouseY = y * 2.0 - 1.0;
755 std::vector< WPosition > toCheck;
756 for(
size_t idx = 0; idx <
m_connectorData->getVertices()->size(); idx++ )
763 if( toCheck.empty() )
768 std::vector< WPosition > positions;
769 for(
size_t idx = 0; idx < toCheck.size(); idx++ )
773 positions.push_back( vertex );
virtual void wait() const
Wait for the condition.
void setResetable(bool resetable=true, bool autoReset=true)
Sets the resetable flag.
virtual void add(std::shared_ptr< WCondition > condition)
Adds another condition to the set of conditions to wait for.
Class to encapsulate boost::condition_variable_any.
std::shared_ptr< WCondition > SPtr
Shared pointer type for WCondition.
Holds the data of the WMPointConnector.
std::shared_ptr< WConnectorData > SPtr
A shared_ptr to this class.
Represents a simple set of WFibers.
std::shared_ptr< WDataSetFibers > SPtr
Pointer to dataset.
Dataset to store a bunch of points without order or topology.
std::shared_ptr< WDataSetPoints > SPtr
Pointer to dataset.
std::shared_ptr< std::vector< float > > VertexArray
List of vertex coordinates in term of components of vertices.
Handles the fibers of the WMPointsConnector.
std::vector< osg::Vec3 > PCFiber
Vector of 3D vectors, representing points.
std::shared_ptr< PCFiberList > PCFiberListSPtr
Shared pointer to fibers-vector.
std::shared_ptr< WFiberHandler > SPtr
A shared_ptr to this class.
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
std::shared_ptr< WGraphicsEngine > getGraphicsEngine() const
Returns pointer to currently running instance of graphics engine.
The keyboard handler for the keyboard events of WMPointConnector.
This module connects the points in a point dataset.
WModule::SPtr m_fiberDisplay
The WMFiberDisplay associated with this module.
std::shared_ptr< std::vector< size_t > > SPSizeVector
represents a std::shared_ptr to a vector containing a vector of size_t.
virtual void activate()
Deactivates or activates the inner modules when active changes.
WPropDouble m_adaptiveVisibilityAngle
Property to set the angle for the adaptive visibility.
bool isAdaptivelyHidden(osg::Vec3 vertex, osg::Vec3 *from=NULL)
Checks whether a vertex is adaptively hidden.
virtual void properties()
Initialize the properties for this module.
std::shared_ptr< WConnectorData > m_connectorData
The data of this module.
void updateAll()
Updates all.
WPropDouble m_hiddenOpacity
Property to set the opacity of the hidden points.
WPropPosition m_scaling
Property for the scaling as Vector.
WMPointConnector()
Constructor.
std::vector< std::function< void() > > m_eventQueue
A vector for the events.
virtual ~WMPointConnector()
Destructor.
std::shared_ptr< WOnscreenSelection > getOnscreenSelection()
float hitVertex(osg::Vec3 rayStart, osg::Vec3 rayDir, osg::Vec3 vertex, float radius)
Checks if a vertex with a certain radius is hit by a ray.
WPropBool m_enableAdaptiveVisibility
Property to enable adaptive visibility.
WPropPosition getScaling()
void handleInput()
Handles the input of this module.
bool findClickedPoint(osg::Vec3 cameraPosition, osg::Vec3 direction, size_t *hitIdx)
Finds the point that was clicked and writes it into hitIdx, while return whether a point was hit.
void pushEventQueue(std::function< void() > func)
Pushes a function to the selection queue.
void createHandler()
Creates the WKeyboardHandler and registers them.
std::shared_ptr< WModuleOutputData< WDataSetFibers > > m_fiberOutput
An output connector used to provide fibers to other modules.
void handleRightSelection(std::vector< WPosition > positions)
Handles the selection of a right click.
std::mutex m_eventMutex
A mutex for the vector to make it thread-safe.
virtual void connectors()
Initialize the connectors this module is using.
std::shared_ptr< WFiberHandler > getFiberHandler()
WModule::SPtr m_pointRenderer
The WMPointRenderer associated with this module.
void acceptPrediction()
Accepts the current prediction.
std::shared_ptr< WConnectorData > getConnectorData()
WPropBool m_enableSizes
Property to enable the sizes.
virtual void moduleMain()
Entry point after loading the module.
osg::ref_ptr< WKeyboardHandler > m_keyboardHandler
The keyboard handler for this point connector.
virtual const std::string getDescription() const
Gives back a description of this module.
std::shared_ptr< std::vector< float > > SPFloatVector
represents a std::shared_ptr to a vector containing a vector of floats.
std::vector< WPosition > m_prediction
The current prediction.
std::shared_ptr< WModuleInputData< WDataSetPoints > > m_pointInput
An input connector used to get points from other modules.
void createPrediction()
Creates a track continuation prediction.
void toggleActivationOfModule(WModule::SPtr mod)
Toggles the activation of a module.
void handleClickSelection(bool clickType, double x, double y)
Handles a selection with only one click.
virtual std::shared_ptr< WModule > factory() const
Due to the prototype design pattern used to build modules, this method returns a new instance of this...
void selectionEnd(WOnscreenSelection::WSelectionType type, float x, float y)
The end callback of m_onscreenSelection.
virtual const char ** getXPMIcon() const
Get the icon for this module in XPM format.
void createFiberDisplay()
Creates the WMFiberDisplay and runs it.
void updateOutput()
Updates the fiber output.
std::shared_ptr< WModuleOutputData< WDataSetPoints > > m_pointOutput
The internal pointOutput to pass data to the WMPointRenderer.
std::shared_ptr< WFiberHandler > m_fiberHandler
The WFiberHandler of this module.
WCondition::SPtr m_eventCondition
A condition notifying when something was added to the event queue.
void updatePoints()
Redraws the current vertices with their colors.
WPropBool m_enableSAPT
Property to enable the adjusted dijkstra.
void handleLeftSelection(std::vector< WPosition > positions)
Handles the selection of a left click.
virtual const std::string getName() const
Gives back the name of this module.
void handleClick(osg::Vec3 cameraPosition, osg::Vec3 direction, bool isLeftClick)
Handles a click on the drawing area.
void createPointRenderer()
Creates the WMPointRenderer and runs it.
std::shared_ptr< WOnscreenSelection > m_onscreenSelection
Enables possibility for multiselection of points.
WPropBool m_enablePrediction
Enables the prediction.
Class able to contain other modules.
virtual WModule::SPtr createAndAdd(std::string name)
Convenience method to create a module instance with a given name and automatically add it to the cont...
virtual void stop()
Stops all modules inside this container.
static PtrType createAndAdd(std::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this out data connector with proper type and add it to...
static PtrType create(std::shared_ptr< WModule > module, std::string name="", std::string description="")
Convenience method to create a new instance of this out data connector with proper type.
std::shared_ptr< WModule > SPtr
Shared pointer to a WModule.
virtual void properties()
Initialize properties in this function.
wlog::WStreamedLogger debugLog() const
Logger instance for comfortable debug logging.
void removeConnectors()
Removes all connectors properly.
std::shared_ptr< WProperties > m_properties
The property object for the module.
void ready()
Call this whenever your module is ready and can react on property changes.
WConditionSet m_moduleState
The internal state of the module.
WPropBool m_active
True whenever the module should be active.
std::shared_ptr< WProgressCombiner > m_progress
Progress indicator used as parent for all progress' of this module.
virtual void connectors()
Initialize connectors in this function.
Manages different types of selection.
WSelectionType
The different types of selection.
This only is a 3d double vector.
Class managing progress inside of modules.
std::shared_ptr< WPropertyGroup > SPtr
shared pointer to object of this type
WBoolFlag m_shutdownFlag
Condition getting fired whenever the thread should quit.
Base Class for all value set types.
std::vector< WPosition > findSmoothestPath(std::vector< WPosition > positions)
Determines the path with the smallest angle change.
double calculateAngle(WPosition a, WPosition b)
Calculates the angle between two positions.
WStreamedLogger debug(const std::string &source)
Logging a debug message.