1
votes

I'm rendering a complex 3D mesh with Three.js (an iliac bone). Then I'm rendering some simple spheres along with this mesh to mark certain points on the surface (where muscles would attach):

       front of the bone; the markers should be visible here       back of the bone; the markers should NOT be visible here

The problem is, the mesh is quite thin in some areas, and the markers will stick out the back.

Assume that the marker coordinates are always closer to the front face of the mesh than the back face, and that the spheres always show more surface area / volume on the front of the mesh than on the back:

How could I hide the parts that extrude out the back without manually intervening for specific markers?

Edit: Here's a (naive?) way of how I might do it. I would like feedback on the feasibility of the idea, and (some pointers to writing) actual code to do it:

  • for each marker sphere:
    • find all faces of the mesh that intersect with the sphere
    • compute all outward-facing normal vectors of those faces (vertex-normals? face-normals?)
    • compute all distances from the center of the face to the center of the sphere
    • add all those normal vectors, weighed by their respective distances
    • given the (normalized?) result vector, hide the hemisphere pointing in that direction

I'm not sure how to code any of those steps. Nor am I sure if this is even a sensible approach.

1
Idea 1: Draw hemispheres instead of spheres (phiStart and phiLength params: threejs.org/docs/#Reference/Extras.Geometries/SphereGeometry). Idea 2: Set an offset of the spheres on the normal depending on the sphere radius and bone thickness (you'll need that info) in the point where the sphere should be placed so it will not be visible on the other side.B0Andrew
@B0Andrew: Both fine ideas, but the most difficult part for both is: how to detect in which direction visibility should be restricted (by removing a hemisphere, or by moving the sphere in the other direction). Ideally this would be done automatically somehow by analyzing the geometry of the bone around those coordinates.mhelvens
You should be able to access bone faces with bone.geometry.faces. Then each face should have vertexNormals. Take a look in VertexNormalsHelper code. This should give you a good start: github.com/mrdoob/three.js/blob/master/src/extras/helpers/…B0Andrew
The problem with Three.js code is that it is poorly documented --- in this case, not documented. And I am far from an expert in geometry and 3D modeling. A piece of example code targeted at my specific problem would be useful. Nonetheless, I'll definitely have a look at the VertexNormalsHelper to see what I can make of it. Thanks!mhelvens
@B0Andrew: Based on your link, I've written down how I might approach the problem, and added it to my original question. Feedback would be much appreciated!mhelvens

1 Answers

1
votes

Draw hemispheres instead of full spheres. Use phiStart and phiLength parameters of the SphereGeometry constructor.

The centers of the spheres will still be on the surface of the bone (a vertex).

The orientation of one sphere will be given by the normal calculated in the sphere origin.

Three.js already calculates the normals for a mesh in order to determine how light will bounce from the mesh. You can use the VertexNormalsHelper to display normals for your mesh:

var bone = ...; // bone mesh
var scene = ...; //your THREE.Scene
scene.add(new THREE.VertexNormalsHelper(bone));

The source code for VertexNormalsHelper can be found here:VertexNormalsHelper

You have to calculate the difference angles between the normal vector and oZ axis so you obtain difX and difY. These are the ammounts you must rotate your sphere in the X and Y directions to make it perpendicular on the local surface of the bone.