diff --git a/Sofa/framework/Core/src/sofa/core/visual/DrawMesh.h b/Sofa/framework/Core/src/sofa/core/visual/DrawMesh.h index 3e1d321cf3e..22281f97af2 100644 --- a/Sofa/framework/Core/src/sofa/core/visual/DrawMesh.h +++ b/Sofa/framework/Core/src/sofa/core/visual/DrawMesh.h @@ -141,6 +141,58 @@ struct BaseDrawMesh template struct DrawElementMesh{}; +template<> +struct SOFA_CORE_API DrawElementMesh + : public BaseDrawMesh, 2> +{ + using ElementType = sofa::geometry::Edge; + friend BaseDrawMesh; + static constexpr ColorContainer defaultColors { + sofa::type::RGBAColor::lime(), + sofa::type::RGBAColor::silver() + }; + +private: + template + void doDraw( + sofa::helper::visual::DrawTool* drawTool, + const PositionContainer& position, + sofa::core::topology::BaseMeshTopology* topology, + const IndicesContainer& elementIndices, + const ColorContainer& colors) + { + if (!topology) + return; + + const auto& elements = topology->getEdges(); + + const auto size = elementIndices.size() * sofa::geometry::Edge::NumberOfNodes; + for ( auto& p : renderedPoints) + { + p.resize(size); + } + + std::array renderedPointId {}; + for (auto i : elementIndices) + { + const auto& element = elements[i]; + + const auto center = this->elementCenter(position, element); + + for (std::size_t j = 0; j < sofa::geometry::Edge::NumberOfNodes; ++j) + { + const auto p = this->applyElementSpace(position[element[j]], center); + renderedPoints[i % NumberColors][renderedPointId[i%NumberColors]++] = sofa::type::toVec3(p); + } + } + + for (std::size_t j = 0; j < NumberColors; ++j) + { + drawTool->drawLines(renderedPoints[j], 2.f, colors[j]); + } + } +}; + template<> struct SOFA_CORE_API DrawElementMesh : public BaseDrawMesh, 3> @@ -194,6 +246,59 @@ struct SOFA_CORE_API DrawElementMesh } }; + +template<> +struct SOFA_CORE_API DrawElementMesh + : public BaseDrawMesh, 2> +{ + using ElementType = sofa::geometry::Quad; + friend BaseDrawMesh; + static constexpr ColorContainer defaultColors { + sofa::type::RGBAColor::green(), + sofa::type::RGBAColor::orange() + }; + +private: + template + void doDraw( + sofa::helper::visual::DrawTool* drawTool, + const PositionContainer& position, + sofa::core::topology::BaseMeshTopology* topology, + const IndicesContainer& elementIndices, + const ColorContainer& colors) + { + if (!topology) + return; + + const auto& elements = topology->getQuads(); + + const auto size = elementIndices.size() * sofa::geometry::Quad::NumberOfNodes; + for ( auto& p : renderedPoints) + { + p.resize(size); + } + + std::array renderedPointId {}; + for (auto i : elementIndices) + { + const auto& element = elements[i]; + + const auto center = this->elementCenter(position, element); + + for (std::size_t j = 0; j < sofa::geometry::Quad::NumberOfNodes; ++j) + { + const auto p = this->applyElementSpace(position[element[j]], center); + renderedPoints[i % NumberColors][renderedPointId[i%NumberColors]++] = sofa::type::toVec3(p); + } + } + + for (std::size_t j = 0; j < NumberColors; ++j) + { + drawTool->drawQuads(renderedPoints[j], colors[j]); + } + } +}; + template<> struct SOFA_CORE_API DrawElementMesh : public BaseDrawMesh, 4> @@ -338,10 +443,17 @@ class SOFA_CORE_API DrawMesh void setElementSpace(SReal elementSpace); + template + void drawLine(sofa::helper::visual::DrawTool* drawTool, const PositionContainer& position, sofa::core::topology::BaseMeshTopology* topology) + { + drawElements(drawTool, position, topology); + } + template void drawSurface(sofa::helper::visual::DrawTool* drawTool, const PositionContainer& position, sofa::core::topology::BaseMeshTopology* topology) { drawElements(drawTool, position, topology); + drawElements(drawTool, position, topology); } template @@ -359,19 +471,38 @@ class SOFA_CORE_API DrawMesh return; } - const auto hasTetra = topology && !topology->getTetrahedra().empty(); - const auto hasHexa = topology && !topology->getHexahedra().empty(); + const auto hasTriangles = !topology->getTriangles().empty(); + const auto hasQuads = !topology->getQuads().empty(); + + const auto hasSurfaceElements = hasTriangles || hasQuads; + + const auto hasTetra = !topology->getTetrahedra().empty(); + const auto hasHexa = !topology->getHexahedra().empty(); + + const bool hasVolumeElements = hasTetra || hasHexa; - if (!hasTetra && !hasHexa) + if (!hasSurfaceElements && !hasVolumeElements) { - drawSurface(drawTool, position, topology); + drawLine(drawTool, position, topology); + } + else + { + if (!hasVolumeElements) + { + drawSurface(drawTool, position, topology); + } + else + { + drawVolume(drawTool, position, topology); + } } - drawVolume(drawTool, position, topology); } private: std::tuple< + DrawElementMesh, DrawElementMesh, + DrawElementMesh, DrawElementMesh, DrawElementMesh > m_meshes;