fruitflybrain / neu3d

A javascript 3D visualization engine for neural data in SWC format
7 stars 8 forks source link

Update to rendering #37

Closed yiyin closed 2 years ago

yiyin commented 2 years ago

This PR includes the following changes:

  1. Removed neuron3d toggle, now have 7 different modes for neuron visualization. mode 0: default mode (light), renders a neuron in their approximate branch width. mode 1: skeleton mode (very light), renders a neuron with lines, was the previous default mode. mode 2: thick line mode (light), render similarly to mode 0 but radii of each segment is the same and defined by setting, can change width from setting and takes immediate effect. mode 3: sphere mode (medium), renders each point on the skeleton as a sphere and connected by a line. mode 4: cylinder mode (heavy), renders a neuron with cylinders. mode 5: cylinder+sphere mode (heavy), renders a neuron with cylinders and spheres. mode 6: cylinder+tube (very heavy), renders a neuron with cylinders and tubes as joints.
  2. Changing neuron3dMode now takes immediate effect (a mechanism to prevent rendering a large number of neurons in mode 4, 5, 6 is not yet in place, so use with caution).
  3. More synapses can be rendered without crashing browser tab - can handle most jobs with default chrome tab memory limit.

Technical aspects:

  1. Updated to use the latest three.js version.
  2. Introduced RenderObj and subclasses in render.js to handle data and rendering configurations for different objects including mesh, neuron, synapses. Neu3D no longer directly change attributes of three.js objects, but by calling methods of RenderObj.
  3. Rendering of neurons and synapses uses instancing where available to make rendering more memory efficient.
  4. Changed internal representation of neuron and synapse.
    • Mesh still requires faces and vertices as before.
    • Neuron is now represented by an arbitrary graph-like representation with vertices and segments. SWC, which is essentially a representation of acyclic graphs, cannot fully capture loops seen in reconstruction, e.g., ring neurons in the central complex. vertices[nodeIndex] = {'type': , 'x': , 'y': , 'z': , 'radius': } segments[segmentIndex] = {'start': , 'end': } heads = [nodeIndex1, nodeIndex2, ...] where heads lists all the nodeIndices chosen to be the head of each disconnected subgraph.
    • Synapses is now represented by a list location = [{'pre_x': , 'pre_y': , 'pre_z': , 'pre_radius': , 'post_x': , 'post_y': , 'post_z': , 'post_radius': ,}, {...}, ...] where post_ attributes are optional.
    • Converters from previous SWC representation of neurons and SWC-like representation of synapses are provided for backward compatibility.
TK-21st commented 2 years ago

Thanks for the PR. Can you elaborate on the schema for meshDict[key]? I saw the renderObj comment above but not sure about the others.

I've seen in the changed code the following:

meshDict[key] = {
    object: {object: something...},
    renderObj: something,
    threeObj: something.
}

Is this exhaustive and what are those attributes pointing to?

yiyin commented 2 years ago

meshDict[key] is a PropertyManager object that have the following attributes:

meshDict[key] = {
    boundingBox: { 'maxX': number, 'minX': number, 
                             'maxY': number, 'minY': number,
                             'maxZ': number, 'minZ': number},
    background: bool,
    class: string,
    uname: string,
    name: string,
    label: string,
    highlight: bool,
    opacity: [0-1],
    visibility: bool,
    color: THREE.color,
    morph_type: string,
    rid: string,
    orid: string,
    pinned: bool,
    position: THREE.Vector3,
    ---------below is the new attribute-------
    renderObj: RenderObj,
}

There maybe some other attributes inherited from the input to addJson which are not needed for the subsequent functionality.

RenderObj has the following attributes exposed: boundingBox, threeObj (which holds the THREE MESH object), and mode (NeuronSkeleton only for storing neuron3dMode when creating mesh.)

TK-21st commented 2 years ago

meshDict[key] is a PropertyManager object that have the following attributes:

meshDict[key] = {
    boundingBox: { 'maxX': number, 'minX': number, 
                             'maxY': number, 'minY': number,
                             'maxZ': number, 'minZ': number},
    background: bool,
    class: string,
    uname: string,
    name: string,
    label: string,
    highlight: bool,
    opacity: [0-1],
    visibility: bool,
    color: THREE.color,
    morph_type: string,
    rid: string,
    orid: string,
    pinned: bool,
    position: THREE.Vector3,
    ---------below is the new attribute-------
    renderObj: RenderObj,
}

There maybe some other attributes inherited from the input to addJson which are not needed for the subsequent functionality.

RenderObj has the following attributes exposed: boundingBox, threeObj (which holds the THREE MESH object), and mode (NeuronSkeleton only for storing neuron3dMode when creating mesh.)

Thanks, makes sense. What's this object.object in this line? https://github.com/fruitflybrain/neu3d/blob/3811f4ec42cc41fbd73f3011ea3e7f2f37870be2/src/import_export.js#L64

yiyin commented 2 years ago

fixed above.

TK-21st commented 2 years ago

@yiyin Some issues I noticed when playing with visualizations, once fixed this PR is ready to merge:

Neuron Modes

neu3d_vis_modes

  1. Mode 4: somas are gone
  2. Mode 6: I can't really make out the neurons anymore, they look like point clouds.

Neuron Mesh

This is probably an old issue, but I just noticed it today. neu3d_vis_wireframe

Upon closer inspection it looks like the wireframe is always present and the show wireframe option doesn't do anything. Maybe we can rename show wireframe to show brain mesh? This would toggle the mesh itself on/off but the wireframe is always present. I feel like this is the behavior we had before.

It looks like the show wireframe option on the

TK-21st commented 2 years ago

Looks like Show Wireframe toggles the settings.meshWireframe boolean which is only used here https://github.com/yiyin/neu3d/blob/b7176528bf366bb3bd74bb0cfa966a2cf6ac726c/src/render.js#L312-L314

yiyin commented 2 years ago

All fixed. The check box in settings menu for Wireframe does not respond very well. Sometime when clicked, the check is still there but takes effect on the visualized.

mkturkcan commented 2 years ago

Some notes:

yiyin commented 2 years ago

Mode is stored on individual neuron, so in principle they are not tied. Added in 970d4a2 a button to indicate if changing mode takes effect on workspace. Changing each neuron separately would probably need some right-click menu or from a neuron list.

  • I suggest that neuron3dMode setting be editable on a per-neuron basis, since certain visualizations require >1000 neurons but only a few neurons of them will be of interest, so only they need to be shown in full detail.