@@ -277,4 +277,129 @@ void BaseViewer::fitObjectBBox(sofa::core::objectmodel::BaseObject * object)
277277 redraw ();
278278}
279279
280+ void BaseViewer::drawSelection (sofa::core::visual::VisualParams* vparams)
281+ {
282+ assert (vparams && " call of drawSelection without a valid visual param is not allowed" );
283+
284+ auto drawTool = vparams->drawTool ();
285+
286+ if (currentSelection.empty ())
287+ return ;
288+
289+ drawTool->setPolygonMode (0 , false );
290+ float screenHeight = vparams->viewport ()[4 ];
291+
292+ for (auto current : currentSelection)
293+ {
294+ using sofa::type::Vec3;
295+ using sofa::type::RGBAColor;
296+ using sofa::defaulttype::RigidCoord;
297+ using sofa::defaulttype::Rigid3Types;
298+
299+ // //////////////////// Render when the selection is a Node ///////////////////////////////
300+ auto node = castTo<sofa::simulation::Node*>(current.get ());
301+ if (node && m_showSelectedNodeBoundingBox)
302+ {
303+ auto box = node->f_bbox .getValue ();
304+ drawTool->drawBoundingBox (box.minBBox (), box.maxBBox (), 2.0 );
305+
306+ // If it is a node... it is not a BaseObject, so we can continue.
307+ continue ;
308+ }
309+
310+ // //////////////////// Render when the selection is a BaseObject //////////////////////////
311+ auto object = castTo<sofa::core::objectmodel::BaseObject*>(current.get ());
312+ if (object)
313+ {
314+ sofa::type::BoundingBox box;
315+ auto ownerNode = dynamic_cast <sofa::simulation::Node*>(object->getContext ());
316+ if (ownerNode)
317+ {
318+ box = ownerNode->f_bbox .getValue ();
319+ }
320+
321+ if (m_showSelectedObjectBoundingBox)
322+ {
323+ drawTool->drawBoundingBox (box.minBBox (), box.maxBBox (), 2.0 );
324+ }
325+
326+ std::vector<Vec3> positions;
327+ auto position = object->findData (" position" );
328+ if (position)
329+ {
330+ auto positionsData = dynamic_cast <Data<sofa::type::vector<Vec3>>*>(position);
331+ if (positionsData)
332+ {
333+ positions = positionsData->getValue ();
334+ if (m_showSelectedObjectBoundingBox){
335+ drawTool->drawPoints (positions, 2.0 , RGBAColor::yellow ());
336+ }
337+ }
338+ else
339+ {
340+ auto rigidPositions = dynamic_cast <Data<sofa::type::vector<RigidCoord<3 , SReal>>>*>(position);
341+ if (rigidPositions)
342+ {
343+ for (auto frame : rigidPositions->getValue ())
344+ {
345+ float targetScreenSize = 50.0 ;
346+ float distance = (currentCamera->getPosition () - Rigid3Types::getCPos (frame)).norm ();
347+ SReal scale = distance * tan (currentCamera->getFieldOfView () / 2 .0f ) * targetScreenSize / screenHeight;
348+ drawTool->drawFrame (Rigid3Types::getCPos (frame), Rigid3Types::getCRot (frame), {scale, scale,scale});
349+ positions.push_back (Rigid3Types::getCPos (frame));
350+ }
351+ }
352+ }
353+ }
354+
355+ if (m_showSelectedObjectSurfaces && !positions.empty ())
356+ {
357+ auto triangles = object->findData (" triangles" );
358+ if (triangles)
359+ {
360+ auto d_triangles = dynamic_cast <Data<sofa::type::vector<core::topology::Topology::Triangle>>*>(triangles);
361+ if (d_triangles)
362+ {
363+ std::vector<Vec3> tripoints;
364+ for (auto indices : d_triangles->getValue ())
365+ {
366+ if (indices[0 ] < positions.size () &&
367+ indices[1 ] < positions.size () &&
368+ indices[2 ] < positions.size ())
369+ {
370+ tripoints.push_back (positions[indices[0 ]]);
371+ tripoints.push_back (positions[indices[1 ]]);
372+ tripoints.push_back (positions[indices[1 ]]);
373+ tripoints.push_back (positions[indices[2 ]]);
374+ tripoints.push_back (positions[indices[2 ]]);
375+ tripoints.push_back (positions[indices[0 ]]);
376+ }
377+ }
378+ drawTool->drawLines (tripoints, 1.5 , RGBAColor::fromFloat (1.0 ,1.0 ,1.0 ,0.7 ));
379+ }
380+ }
381+ }
382+
383+ if (!positions.empty () && m_showSelectedObjectIndices)
384+ {
385+ const float scale = (box.maxBBox () - box.minBBox ()).norm () * m_visualScaling;
386+ drawTool->draw3DText_Indices (positions, scale, RGBAColor::white ());
387+ }
388+
389+ continue ;
390+ }
391+ msg_error (" BaseViewer" ) << " Only node and object can be selected, if you see this line please report to sofa-developement team" ;
392+ }
393+ }
394+
395+ void BaseViewer::setCurrentSelection (const std::set<sofa::core::objectmodel::Base::SPtr>& selection)
396+ {
397+ currentSelection = selection;
398+ }
399+
400+ const std::set<core::objectmodel::Base::SPtr> &BaseViewer::getCurrentSelection () const
401+ {
402+ return currentSelection;
403+ }
404+
280405} // namespace sofa::gui::common
0 commit comments