1

I'm creating a 3D model editor application using THREE.js where you can load a CAD model and have it display on the screen. You can pan, zoom, rotate the camera anywhere around in the scene to view the CAD model from any angle.

I want to add support to be able to draw an arbitrary rectangle on the screen (marquee select box) and anything inside this box I'd like to become selected.

What is a good algorithm to use for this operation?

My first thought was to take every loaded CAD part (that can be selected), and project its bounding box onto the screen. Then test each of these projected bounding boxes to the selection box drawn on the screen for matches. This should work, however I'm worried it would be very slow for large CAD models with 1000's of selectable parts.

Is there a better way to do marquee selections in 3D? Can raycasting somehow be used to speed up the selections?

Marek Krzeminski
  • 1,308
  • 3
  • 15
  • 40
  • 1
    Are you looking for something like that: https://threejs.org/examples/?q=selection#misc_boxselection ? – prisoner849 Jan 11 '19 at 05:57
  • @prisoner849 Oh, ha, that's new! It looks like that example also projects the box selection into a frustum as I suggested to detect the selection (https://github.com/mrdoob/three.js/blob/master/examples/js/interactive/SelectionBox.js#L30). This code coupled with a an acceleration structure like an oct tree should be able to speed the searching up. – Garrett Johnson Jan 12 '19 at 03:14

1 Answers1

0

Without knowing more details about your cad models it'll be a bit hard to give exactly relevant suggestions but I can suggest a few things I might try.

Use Hierarchical Bounding Boxes

If you have a multi-level tree of meshes you can generate bounding boxes for the non-leaf nodes of the tree. This isn't supported directly in THREE but you can manually create and check against these objects before checking if the child objects are within the marquee.

If your tree isn't spatially organized very well or is very flat then you can build an oct-tree and traverse the oct-tree nodes before checking the meshes.

Of course these data structures have to be updated whenever meshes move in your CAD model.

Cache World Bounds

If you cache versions of the bounding boxes on all the meshes in world space then instead of projecting the bounds into screen space you can create a frustum from the marquee in world space and check the all the mesh bounds without having to do any transformation of those boxes.

Asynchronous Checking

Instead of gathering all the intersected bounds on a single frame you could gather them up over multiple frames if it is taking a long time.

Unfortunately I don't think raycasting can do a whole lot for you here.

Hopefully that helps!

Garrett Johnson
  • 2,413
  • 9
  • 17
  • after a CAD model is loaded, the tree structure is static. The structure itself is deeply nested with meshes located anywhere, so I will have to create an oct-tree to be able to traverse it quickly. What I'm not sure about is how to create this 'search' tree. With a 2D marquee selection, I don't know how I would select objects from within an oct-tree. Alternatively, how would you transform an oct-tree to the 2D screen space to search in 2D (rather than 3D) for matches? – Marek Krzeminski Jan 11 '19 at 14:23
  • Oct-tree nodes are just cubes so you'd project the vertices of the cube into screen space just like any other bounds and if that 2d shape overlaps with your marquee then you know to continue traversing and checking the children. To do that you should be able to look into detecting intersections between 2d objects (the projected faces from your cube and the marquee). "separating axis theorem" should be helpful there. – Garrett Johnson Jan 12 '19 at 03:09