refactoredCPPNeuronMesher
swc_viewer.cpp File Reference
#include <GLFW/glfw3.h>
#include <GL/glu.h>
#include "tinyfiledialogs.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <map>
#include <array>
#include <tuple>
Include dependency graph for swc_viewer.cpp:

Classes

struct  SWCNode
 Structure representing a single node in an SWC neuron morphology. More...
 

Functions

void printHelpText ()
 Prints keyboard and mouse controls to the console. More...
 
std::vector< SWCNodeloadSWC (const std::string &filename)
 Loads neuron data from an SWC file. More...
 
void computeBounds (const std::vector< SWCNode > &nodes, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ, float &centerX, float &centerY, float &centerZ, float &radius)
 
void openNeuronFile (std::vector< SWCNode > &nodes, float &minX, float &maxX, float &minY, float &maxY, float &minZ, float &maxZ, float &centerX, float &centerY, float &centerZ, float &radius)
 
void setColorByType (int type)
 Sets the OpenGL color based on SWC node type. More...
 
void drawSimpleSphere (const SWCNode &node, float size=0.5f)
 
void drawSimpleLine (const SWCNode &a, const SWCNode &b)
 Draws a simple line between two nodes. More...
 
void drawSphere (const SWCNode &node, int slices=6, int stacks=6)
 Draws a sphere with specified geometric detail. More...
 
void drawCylinder (const SWCNode &a, const SWCNode &b, int segments=6)
 Draws a cylinder connecting two nodes. More...
 
void drawBoundingBox (float minX, float maxX, float minY, float maxY, float minZ, float maxZ)
 
void renderSWC (const std::vector< SWCNode > &nodes)
 Renders a complete SWC neuron morphology. More...
 
void keyCallback (GLFWwindow *window, int key, int scancode, int action, int mods)
 Handles keyboard input events. More...
 
void mouseButtonCallback (GLFWwindow *window, int button, int action, int mods)
 Handles mouse button input events. More...
 
void cursorPosCallback (GLFWwindow *window, double xpos, double ypos)
 Handles mouse cursor movement. More...
 
void scrollCallback (GLFWwindow *window, double xoffset, double yoffset)
 Handles mouse scroll events. More...
 
void setupLighting ()
 
void setupCamera (float cx, float cy, float cz, float radius, int width, int height)
 
int main (int argc, char **argv)
 

Variables

int renderMode = 1
 Current rendering mode (1-5) More...
 
float rotateX = 0.0f
 Camera rotation around X and Y axes (in degrees) More...
 
float rotateY = 0.0f
 
float zoom = 1.0f
 Camera zoom factor (higher values = more zoomed in) More...
 
float panX = 0.0f
 Camera pan offset in X and Y directions. More...
 
float panY = 0.0f
 
bool dragging = false
 Mouse drag state flags. More...
 
bool rightDragging = false
 
double lastX
 Last recorded mouse cursor position. More...
 
double lastY
 

Function Documentation

◆ computeBounds()

void computeBounds ( const std::vector< SWCNode > &  nodes,
float &  minX,
float &  maxX,
float &  minY,
float &  maxY,
float &  minZ,
float &  maxZ,
float &  centerX,
float &  centerY,
float &  centerZ,
float &  radius 
)
Here is the caller graph for this function:

◆ cursorPosCallback()

void cursorPosCallback ( GLFWwindow *  window,
double  xpos,
double  ypos 
)

Handles mouse cursor movement.

Updates camera orientation or position based on mouse movement when:

  • Left button is held: Rotate view
  • Right button is held: Pan view
  • Middle button is held: Zoom view
Parameters
windowThe GLFW window that received the event
xposThe new cursor x-coordinate, relative to the left edge of the content area
yposThe new cursor y-coordinate, relative to the top edge of the content area

Handles mouse cursor movement.

Parameters
[in]windowThe GLFW window that received the event
[in]xposThe new x-coordinate of the cursor, in screen coordinates
[in]yposThe new y-coordinate of the cursor, in screen coordinates

This callback function processes mouse movement to implement interactive 3D view manipulation. It provides the following functionality:

  • Left-drag: Rotates the view around the X and Y axes
  • Right-drag: Pans the view in the X and Y directions

The function uses the difference between the current and last cursor positions to calculate the amount of rotation or panning to apply. The actual view transformation is applied in the main rendering loop using the global state variables modified by this function.

Note
The function updates the lastX and lastY variables to track cursor movement between frames
Rotation and panning speeds are scaled by constant factors (0.3f and 1.5f)
See also
mouseButtonCallback() for enabling/disabling rotation and panning
GLFW cursor position documentation: https://www.glfw.org/docs/latest/input_guide.html#cursor_pos
Here is the caller graph for this function:

◆ drawBoundingBox()

void drawBoundingBox ( float  minX,
float  maxX,
float  minY,
float  maxY,
float  minZ,
float  maxZ 
)
Here is the caller graph for this function:

◆ drawCylinder()

void drawCylinder ( const SWCNode a,
const SWCNode b,
int  segments = 6 
)

Draws a cylinder connecting two nodes.

Parameters
aFirst node (start of cylinder)
bSecond node (end of cylinder)
segmentsNumber of radial segments for the cylinder [default: 6]

Renders a tapered cylinder that connects two nodes, with the radius at each end determined by the nodes' radii. The cylinder is colored according to the first node's type.

Draws a cylinder connecting two nodes.

Parameters
[in]aThe starting node of the cylinder
[in]bThe ending node of the cylinder
[in]segmentsThe number of sides around the cylinder

This function draws a tapered cylinder connecting two nodes in 3D space. The cylinder's radius at each end is determined by the radius property of the corresponding node, allowing for smooth tapering of neurites.

The function handles the necessary coordinate system transformations to orient the cylinder correctly between the two points in 3D space. It uses OpenGL's matrix stack to ensure the transformations don't affect subsequent rendering operations.

Note
The cylinder is drawn with smooth normals for proper lighting
If the nodes are coincident (distance = 0), the function returns early
The 57.2957795f constant converts radians to degrees (180/π)
Uses legacy OpenGL immediate mode rendering
See also
gluCylinder() for details on the underlying GLU primitive
Here is the caller graph for this function:

◆ drawSimpleLine()

void drawSimpleLine ( const SWCNode a,
const SWCNode b 
)

Draws a simple line between two nodes.

Parameters
aFirst node (start point)
bSecond node (end point)

Renders a line in 3D space between two nodes using immediate mode OpenGL. The line width is determined by the nodes' radii.

Draws a simple line between two nodes.

Parameters
[in]aThe starting node of the line
[in]bThe ending node of the line

This function renders a simple line segment between two nodes in 3D space using OpenGL's immediate mode line rendering. The line is drawn with the current OpenGL color and line width settings.

The function is typically used for wireframe representations of neuron morphologies or for debug visualization.

Note
The line is drawn with the current OpenGL color
Uses legacy OpenGL immediate mode rendering (glBegin/glEnd)
For more complex line rendering (e.g., with thickness), consider using geometry shaders or other modern OpenGL techniques
Here is the caller graph for this function:

◆ drawSimpleSphere()

void drawSimpleSphere ( const SWCNode node,
float  size = 0.5f 
)
Here is the caller graph for this function:

◆ drawSphere()

void drawSphere ( const SWCNode node,
int  slices = 6,
int  stacks = 6 
)

Draws a sphere with specified geometric detail.

Parameters
nodeThe SWC node to draw
slicesNumber of subdivisions around the z-axis (longitude) [default: 6]
stacksNumber of subdivisions along the z-axis (latitude) [default: 6]

Uses GLU quadric objects to render a sphere with the specified level of detail. The sphere is colored according to the node's type.

Draws a sphere with specified geometric detail.

Parameters
[in]nodeThe SWCNode containing the position and radius for the sphere
[in]slicesThe number of subdivisions around the Z axis (longitude)
[in]stacksThe number of subdivisions along the Z axis (latitude)

This function draws a sphere using OpenGL's GLU quadric primitives with smooth normal vectors for proper lighting calculations. The sphere's radius is taken from the node's radius property, and its position is set to the node's coordinates.

The function handles the OpenGL matrix stack appropriately and uses the current OpenGL color for rendering. The resolution of the sphere can be controlled through the slices and stacks parameters.

Note
The sphere is drawn with smooth shading (GLU_SMOOTH)
Uses legacy OpenGL immediate mode rendering
For high-quality rendering, use at least 16 slices and stacks
See also
drawSimpleSphere() for a faster, lower-quality alternative
gluQuadricNormals() for details on normal generation
Here is the caller graph for this function:

◆ keyCallback()

void keyCallback ( GLFWwindow *  window,
int  key,
int  scancode,
int  action,
int  mods 
)

Handles keyboard input events.

Processes key presses and releases to control the visualization:

  • WASD: Move camera left/right/forward/backward
  • QE: Move camera up/down
  • Arrow keys: Rotate view
  • R: Reset view
  • Space: Toggle auto-rotation
  • 1-5: Switch between rendering modes
  • +/-: Adjust rendering parameters
  • ESC: Close window
  • H: Toggle help text
Parameters
windowThe GLFW window that received the event
keyThe keyboard key that was pressed or released
scancodeThe system-specific scancode of the key
actionGLFW_PRESS, GLFW_RELEASE or GLFW_REPEAT
modsBit field describing which modifier keys were held down

Handles keyboard input events.

Parameters
[in]windowThe GLFW window that received the event
[in]keyThe keyboard key that was pressed or released
[in]scancodeThe system-specific scancode of the key
[in]actionThe key action (GLFW_PRESS, GLFW_RELEASE, or GLFW_REPEAT)
[in]modsBit field describing which modifier keys were held down

This callback function processes keyboard input for controlling the neuron viewer. It implements the following keyboard shortcuts:

  • F: Refine neuron geometry (halve delta)
  • Ctrl+F: Coarsen neuron geometry (double delta)
  • 1-6: Switch between different render modes
  • O: Open a neuron file dialog
  • R: Reset camera view
  • H: Show/hide help window
  • S: Save the current neuron data to file

The function modifies global state for view parameters and triggers updates to the neuron visualization when geometry is refined or coarsened.

Note
The function only processes key press events (GLFW_PRESS)
Modifier keys (Ctrl, Shift, Alt) are checked using the mods parameter
See also
GLFW key documentation: https://www.glfw.org/docs/latest/input_guide.html#input_key
Here is the call graph for this function:
Here is the caller graph for this function:

◆ loadSWC()

std::vector<SWCNode> loadSWC ( const std::string &  filename)

Loads neuron data from an SWC file.

Parses an SWC (Standardized Waveform Container) file containing neuron morphology data and returns a vector of SWCNode objects.

Parameters
filenamePath to the SWC file to load
Returns
std::vector<SWCNode> Vector of nodes representing the neuron morphology
Exceptions
std::runtime_errorIf the file cannot be opened or is malformed
Note
The SWC format is a standard format for representing neuron morphologies. Each line in the file represents a point in the neuron structure.
See also
http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html

Loads neuron data from an SWC file.

Parameters
[in]filenamePath to the SWC or UGX file to load
Returns
std::vector<SWCNode> Vector of SWC nodes representing the neuron

This function loads a neuron morphology from the specified file and returns its nodes as a vector of SWCNode objects. It supports both SWC and UGX file formats and performs preprocessing on the loaded data.

The function:

  1. Reads the neuron data using NeuronGraph's readFromFileUGXorSWC()
  2. Applies preprocessing to the loaded nodes
  3. Converts the node map to a vector for rendering
Note
The function modifies the global graph object
Preprocessing includes validation and cleanup of the neuron structure
Exceptions
std::runtime_errorif the file cannot be read or parsed
See also
NeuronGraph::readFromFileUGXorSWC()
NeuronGraph::preprocess()
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char **  argv 
)
Here is the call graph for this function:

◆ mouseButtonCallback()

void mouseButtonCallback ( GLFWwindow *  window,
int  button,
int  action,
int  mods 
)

Handles mouse button input events.

Processes mouse button presses and releases for:

  • Left button: Start/end rotation
  • Right button: Start/end panning
  • Middle button: Start/end zooming
Parameters
windowThe GLFW window that received the event
buttonThe mouse button that was pressed or released
actionGLFW_PRESS or GLFW_RELEASE
modsBit field describing which modifier keys were held down

Handles mouse button input events.

Parameters
[in]windowThe GLFW window that received the event
[in]buttonThe mouse button that was pressed or released
[in]actionThe button action (GLFW_PRESS or GLFW_RELEASE)
[in]modsBit field describing which modifier keys were held down

This callback function processes mouse button events to enable interactive 3D view manipulation. It tracks the following interactions:

  • Left mouse button: Enables view rotation when dragged
  • Right mouse button: Enables view panning when dragged

The function updates global state variables (dragging, rightDragging) that are used by cursorPosCallback to implement the actual view transformations.

Note
The function tracks both press and release events for smooth interaction
The cursor position is captured on button press for relative movement
See also
cursorPosCallback() for the implementation of the actual view transformations
GLFW mouse button documentation: https://www.glfw.org/docs/latest/input_guide.html#input_mouse_button
Here is the caller graph for this function:

◆ openNeuronFile()

void openNeuronFile ( std::vector< SWCNode > &  nodes,
float &  minX,
float &  maxX,
float &  minY,
float &  maxY,
float &  minZ,
float &  maxZ,
float &  centerX,
float &  centerY,
float &  centerZ,
float &  radius 
)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ printHelpText()

void printHelpText ( )

Prints keyboard and mouse controls to the console.

Displays a help message listing all available keyboard shortcuts and mouse controls for the neuron viewer application.

Note
This function is typically called when the application starts or when the user presses the 'H' key.

Prints keyboard and mouse controls to the console.

Displays the application's keyboard and mouse controls to the console. The help text is defined as a global string constant in globals.h.

Note
The help text includes controls for view manipulation, file operations, and rendering modes.
See also
globals.h for the help text definition
Here is the caller graph for this function:

◆ renderSWC()

void renderSWC ( const std::vector< SWCNode > &  nodes)

Renders a complete SWC neuron morphology.

Parameters
nodesVector of SWC nodes to render

This is the main rendering function that draws an entire neuron morphology. It handles the display of all nodes and connections between them, with appropriate coloring based on node types. The function respects the current rendering mode and visualization settings from globals.h.

Renders a complete SWC neuron morphology.

Parameters
[in]nodesA vector of SWCNode objects representing the neuron morphology

This function renders a complete neuron morphology from SWC node data using different rendering modes controlled by the global renderMode variable. The function handles both the rendering of nodes (soma, branch points, etc.) and the connections between them (dendrites, axons).

Supported render modes:

  • Mode 1: White wireframe lines between nodes
  • Mode 2: Colored spheres at nodes with white wireframe connections
  • Mode 3: Yellow simple spheres at node positions
  • Mode 4: Purple detailed spheres at node positions
  • Mode 5: Colored tapered cylinders between nodes (no spheres)
  • Mode 6: Colored detailed spheres with colored tapered cylinders

The function first renders all nodes according to the current render mode, then renders the connections between nodes. Node colors are determined by their SWC type using the setColorByType() function.

Note
The function uses the global renderMode variable to determine rendering style
Parent-child relationships are determined by the node.pid field
The function skips rendering of invalid parent references (pid = -1)
See also
setColorByType() for information about color mapping
drawSphere(), drawCylinder() for the actual rendering primitives
Here is the call graph for this function:
Here is the caller graph for this function:

◆ scrollCallback()

void scrollCallback ( GLFWwindow *  window,
double  xoffset,
double  yoffset 
)

Handles mouse scroll events.

Zooms the view in/out based on vertical scroll input.

Parameters
windowThe GLFW window that received the event
xoffsetThe scroll offset along the x-axis (unused)
yoffsetThe scroll offset along the y-axis (positive = scroll up, negative = scroll down)

Handles mouse scroll events.

Parameters
[in]windowThe GLFW window that received the event
[in]xoffsetThe scroll offset along the x-axis (unused in this implementation)
[in]yoffsetThe scroll offset along the y-axis (positive for scroll up, negative for scroll down)

This callback function processes mouse scroll wheel input to implement smooth zooming of the 3D view. It modifies the global zoom factor based on the vertical scroll amount.

The zoom factor is adjusted using an exponential scale (1.1^yoffset) to provide natural-feeling zoom behavior. The zoom level is clamped between 0.05 and 10.0 to prevent extreme zoom levels that might cause rendering issues or numerical instability.

Note
The xoffset parameter is currently unused but included for future compatibility
Zooming is centered on the current view (no focal point adjustment)
The 1.1 base value provides a good balance between precision and responsiveness
See also
GLFW scroll documentation: https://www.glfw.org/docs/latest/input_guide.html#scrolling
Here is the caller graph for this function:

◆ setColorByType()

void setColorByType ( int  type)

Sets the OpenGL color based on SWC node type.

Parameters
typeSWC node type identifier (1-7)

Maps standard SWC node types to distinct colors for visualization. The color mapping follows the standard SWC color scheme:

  • 1 (Soma): Red
  • 2 (Axon): Blue
  • 3 (Dendrite): Yellow
  • 4 (Apical dendrite): Purple
  • 5-7: Other standard SWC types
Parameters
[in]typeThe SWC node type identifier

This function maps standard SWC node types to specific colors for visualization. The color mapping is as follows:

  • Type 1: Red (soma)
  • Type 2: Green (axon)
  • Type 3: Blue (basal dendrite)
  • Type 4: Yellow (apical dendrite)
  • Type 5: Magenta
  • Type 6: Cyan
  • Type 7: Orange
  • Default: White (for any other type)

The function uses a static map for efficient type-to-color lookup and modifies the current OpenGL color state.

Note
The function modifies the OpenGL current color state
The color map is static and shared across all instances
For custom color schemes, modify the colorMap variable
See also
http://www.neuronland.org/NLMorphologyConverter/MorphologyFormats/SWC/Spec.html for SWC format specification
Here is the caller graph for this function:

◆ setupCamera()

void setupCamera ( float  cx,
float  cy,
float  cz,
float  radius,
int  width,
int  height 
)
Here is the caller graph for this function:

◆ setupLighting()

void setupLighting ( )
Here is the caller graph for this function:

Variable Documentation

◆ dragging

bool dragging = false

Mouse drag state flags.

These track the current drag operation:

  • dragging: True during left-button rotation
  • rightDragging: True during right-button panning

Mouse drag state flags.

◆ lastX

double lastX

Last recorded mouse cursor position.

Used to calculate mouse movement deltas for smooth camera control.

Last recorded mouse cursor position.

◆ lastY

double lastY

◆ panX

float panX = 0.0f

Camera pan offset in X and Y directions.

These values control the 2D panning of the view:

  • panX: Horizontal pan (positive = right)
  • panY: Vertical pan (positive = up)

Camera pan offset in X and Y directions.

◆ panY

float panY = 0.0f

◆ renderMode

int renderMode = 1

Current rendering mode (1-5)

Controls how the neuron is rendered:

  • 1: Basic line rendering
  • 2: Cylinder rendering
  • 3: Spheres at nodes
  • 4: Full 3D rendering
  • 5: Debug rendering mode

Current rendering mode (1-5)

◆ rightDragging

bool rightDragging = false

◆ rotateX

float rotateX = 0.0f

Camera rotation around X and Y axes (in degrees)

These angles control the 3D view orientation:

  • rotateX: Rotation around the X-axis (vertical rotation)
  • rotateY: Rotation around the Y-axis (horizontal rotation)

Camera rotation around X and Y axes (in degrees)

◆ rotateY

float rotateY = 0.0f

◆ zoom

float zoom = 1.0f

Camera zoom factor (higher values = more zoomed in)

Camera zoom factor (higher values = more zoomed in)