Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
4782a9e
[render] add CrossSectionUniforms class
alemuntoni Mar 31, 2026
73726c7
[render] add CrossSectionUniforms shader header
alemuntoni Mar 31, 2026
45d28b3
[render] Add cross-section uniforms and controls to drawable mesh cla…
alemuntoni Mar 31, 2026
9409624
[render] per vertex and per fragment cross section
alemuntoni Mar 31, 2026
9207f49
[render] implement cross section for drawable mesh surface
alemuntoni Mar 31, 2026
16622eb
[render] Refactor cross section settings into CrossSectionSettings cl…
alemuntoni Apr 1, 2026
ca6a604
[render] Fix input on surface fragment shaders
alemuntoni Apr 2, 2026
907d79f
[render] Rename settingsUpdated signal to meshRenderSettingsUpdated t…
alemuntoni Apr 2, 2026
6462ce1
[render] CrossSectionSettingsFrame class
alemuntoni Apr 2, 2026
aba1c42
[render] Add cross-section controls and signal handlers to settings f…
alemuntoni Apr 2, 2026
b0ecf72
[render] add X slider to CrossSectionFrame
alemuntoni Apr 2, 2026
1d11f09
[render] CrossSectionFrame x slider working as expected
alemuntoni Apr 2, 2026
5720c7d
[render] CrossSectionSettingsFrame working
alemuntoni Apr 2, 2026
b886a33
Merge branch 'main' into cross_section
alemuntoni Apr 3, 2026
d7a0b96
Merge branch 'main' into cross_section
alemuntoni Apr 3, 2026
efdaa00
[render] Refactor cross-section discard logic into reusable shader ma…
alemuntoni Apr 10, 2026
e6e2f7b
[render] Add cross-section clipping to mesh surface pbr and surface I…
alemuntoni Apr 10, 2026
cbf32a3
[render] DrawableMesh: Refactor cross-section uniform updates into up…
alemuntoni Apr 10, 2026
c468fbd
[render] Add cross-section clipping support to points_instance shaders
alemuntoni Apr 10, 2026
94ea469
Merge branch 'main' into cross_section
alemuntoni Apr 13, 2026
72739a0
[render] Move CrossSectionSettings from drawable/mesh to render/setti…
alemuntoni Apr 13, 2026
81802a2
[render] Add CrossSection clipping to lines
alemuntoni Apr 13, 2026
42cb29b
[render] Move CrossSectionSettingsFrame to tab widget and update UI s…
alemuntoni Apr 13, 2026
88eb967
[render] separate cross section inputs/outputs in all the shaders
alemuntoni Apr 13, 2026
1f13489
[render] varying.def indent fixes
alemuntoni Apr 13, 2026
7cb33ad
Merge branch 'main' into cross_section
alemuntoni Apr 15, 2026
74d8efe
[render] cross section on primitve points shader
alemuntoni Apr 15, 2026
8203e19
[render] cross section on primitive lines
alemuntoni Apr 15, 2026
4b4d736
[render] small fixes
alemuntoni Apr 15, 2026
6e5c88a
[render] enable cross section for all remaining surface shaders
alemuntoni Apr 15, 2026
5519c74
[space] add isStrictlyBelow and isStrictlyAbove member functions to P…
alemuntoni Apr 17, 2026
e969dfb
[render] Add bounds checks and signal blocking to cross-section UI se…
alemuntoni Apr 17, 2026
5d7b8b5
[render] Improve cross section settings handling and UI state synchro…
alemuntoni Apr 17, 2026
2a75ff4
[space] isStrictly[Below/Above] member functions renamed to all[Less/…
alemuntoni Apr 17, 2026
b6fb4d6
[render] Refactor CrossSectionSettings bbox logic and fix UI checkbox…
alemuntoni Apr 17, 2026
5f14a15
[render] Add per-fragment flag to uniforms and handle null bounding b…
alemuntoni Apr 17, 2026
3dae7d0
[render] Initialize mCrossSectionFrame to nullptr and update frame on…
alemuntoni Apr 17, 2026
4b59cfe
[render] cpu lines - Apply near-plane clipping to v_worldPos0 and v_w…
alemuntoni Apr 18, 2026
7e8e197
Merge branch 'main' into cross_section
alemuntoni Apr 29, 2026
6b83ef3
Merge branch 'main' into cross_section
alemuntoni May 4, 2026
f24f616
Merge branch 'main' into cross_section
alemuntoni May 14, 2026
570839a
Merge branch 'main' into cross_section
alemuntoni May 19, 2026
7066ed2
Merge branch 'main' into cross_section
alemuntoni Jun 6, 2026
943c1bc
[render] fix dx build error
alemuntoni Jun 7, 2026
f03ff10
[render] fix CrossSectionSettings lower and upper reset when bbox set
alemuntoni Jun 7, 2026
dd8dd52
Merge branch 'main' into cross_section
alemuntoni Jun 22, 2026
55453aa
Merge branch 'main' into cross_section
alemuntoni Jun 29, 2026
a8bd1d9
[render] fix msvc build error
alemuntoni Jun 29, 2026
eef66d4
Merge branch 'main' into cross_section
alemuntoni Jun 29, 2026
7ad34a9
Merge branch 'main' into cross_section
alemuntoni Jun 30, 2026
40aaf45
[render] fix not renamed settings updated signal
alemuntoni Jul 1, 2026
587f82c
Merge branch 'main' into cross_section
alemuntoni Jul 1, 2026
d36a567
Merge branch 'main' into cross_section
alemuntoni Jul 1, 2026
f53ae04
[render] Add section-enabled surface shading options and update shade…
alemuntoni Jul 1, 2026
eea2629
[render] fix dx error: initialize unused varying variables with defau…
alemuntoni Jul 1, 2026
fbf66a4
Merge branch 'main' into cross_section
alemuntoni Jul 1, 2026
f9f7325
Merge branch 'main' into cross_section
alemuntoni Jul 2, 2026
d99b605
Merge branch 'main' into cross_section
alemuntoni Jul 2, 2026
b7ba307
[render] Rename SECTION dimension from ENABLED/DISABLED to ON/OFF in …
alemuntoni Jul 2, 2026
b73a1c6
Merge branch 'main' into cross_section
alemuntoni Jul 7, 2026
fe6445e
Merge branch 'main' into cross_section
alemuntoni Jul 9, 2026
ef19c89
Merge branch 'main' into cross_section
alemuntoni Jul 15, 2026
115faa8
[render] Synchronize cross section settings and bounding boxes in app…
alemuntoni Jul 15, 2026
9473b29
Merge branch 'main' into cross_section
alemuntoni Jul 15, 2026
2ad6421
[render] Add step size control for cross section precision with spin …
alemuntoni Jul 15, 2026
6c7e156
Merge branch 'main' into cross_section
alemuntoni Jul 16, 2026
a45b883
Merge branch 'main' into cross_section
alemuntoni Jul 17, 2026
e012b80
Merge branch 'main' into cross_section
alemuntoni Jul 17, 2026
f7debb6
[render] Add cross section support to point rendering and relevant sh…
alemuntoni Jul 17, 2026
87de1b0
Merge branch 'main' into cross_section
alemuntoni Jul 17, 2026
64985ec
Merge branch 'main' into cross_section
alemuntoni Jul 24, 2026
6e56429
Merge branch 'main' into cross_section
alemuntoni Jul 31, 2026
1e82844
[tests] add cross section tests
alemuntoni Jul 31, 2026
eaf80f2
Merge branch 'main' into cross_section
alemuntoni Aug 1, 2026
44c4da5
Merge branch 'main' into cross_section
alemuntoni Aug 2, 2026
8f628fd
[render] using StaticUniforms for CrossSectionSettings
alemuntoni Aug 2, 2026
37c8cdd
Merge branch 'main' into cross_section
alemuntoni Aug 4, 2026
28bbd62
[render] cross section working on new primitive lines
alemuntoni Aug 4, 2026
f29e548
[tests] wireframe cross section test
alemuntoni Aug 4, 2026
dca96b8
Merge branch 'main' into cross_section
alemuntoni Aug 9, 2026
c95ce12
[tests] fix build error
alemuntoni Aug 9, 2026
a5d1e7e
Merge branch 'main' into cross_section
alemuntoni Aug 22, 2026
f41f7ed
Merge branch 'main' into cross_section
alemuntoni Aug 22, 2026
2b1a1b8
Merge branch 'main' into cross_section
alemuntoni Sep 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
48 changes: 48 additions & 0 deletions tests/render/002-mesh-surface-headless/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,51 @@ TEST_CASE("Mesh Surface Selection")
1.57079632679f);
}
}

TEST_CASE("Mesh Surface Cross Section")
{
SECTION("Vertex Cross Section")
{
runRenderTest(
TEST_NAME, "cross_section_vertex", [](vcl::HeadlessMeshViewer& mv) {
auto mesh = getDrawableMesh<vcl::TriMesh>("bimba.obj");

vcl::CrossSectionSettings css(mesh);
css.type() =
vcl::CrossSectionSettings::CrossSectionType::PER_VERTEX;

vcl::Point3f min = css.boundingBox().min();
vcl::Point3f max = css.boundingBox().max();
css.setLowerUpper(
min + (max - min) * 0.25f, max - (max - min) * 0.25f);

mesh.setCrossSectionSettings(css);

mv.pushDrawableObject(std::move(mesh));
});
}

SECTION("Fragment Cross Section")
{
runRenderTest(
TEST_NAME,
"cross_section_fragment",
[](vcl::HeadlessMeshViewer& mv) {
auto mesh = getDrawableMesh<vcl::TriMesh>("bimba.obj");

vcl::CrossSectionSettings css(mesh);
css.type() =
vcl::CrossSectionSettings::CrossSectionType::PER_FRAGMENT;

vcl::Point3f min = css.boundingBox().min();
vcl::Point3f max = css.boundingBox().max();
css.setLowerUpper(
min + (max - min) * 0.25f, max - (max - min) * 0.25f);

mesh.setCrossSectionSettings(css);

mv.pushDrawableObject(std::move(mesh));
});
}
}

71 changes: 71 additions & 0 deletions tests/render/005-mesh-wireframe-headless/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,74 @@ TEST_CASE("Wireframe Depth Offset")
-150.f);
}
}

TEST_CASE("Wireframe Cross Section")
{
SECTION("Vertex Cross Section")
{
runRenderTest(
TEST_NAME,
"cross_section_vertex",
[](vcl::HeadlessMeshViewer& mv) {
auto mesh =
getDrawableMesh<vcl::TriMesh>("bunny_simplified.obj");

auto settings = mesh.renderSettings();
settings.setSurface(
vcl::MeshRenderInfo::Surface::VISIBLE, false);
settings.setWireframe(
vcl::MeshRenderInfo::Wireframe::VISIBLE, true);
settings.setWireframeWidth(3);
mesh.setRenderSettings(settings);

vcl::CrossSectionSettings css(mesh);
css.type() =
vcl::CrossSectionSettings::CrossSectionType::PER_VERTEX;

vcl::Point3f min = css.boundingBox().min();
vcl::Point3f max = css.boundingBox().max();
css.setLowerUpper(
min + (max - min) * 0.25f, max - (max - min) * 0.25f);

mesh.setCrossSectionSettings(css);

mv.pushDrawableObject(std::move(mesh));
},
0.f,
-150.f);
}

SECTION("Fragment Cross Section")
{
runRenderTest(
TEST_NAME,
"cross_section_fragment",
[](vcl::HeadlessMeshViewer& mv) {
auto mesh =
getDrawableMesh<vcl::TriMesh>("bunny_simplified.obj");

auto settings = mesh.renderSettings();
settings.setSurface(
vcl::MeshRenderInfo::Surface::VISIBLE, false);
settings.setWireframe(
vcl::MeshRenderInfo::Wireframe::VISIBLE, true);
settings.setWireframeWidth(3);
mesh.setRenderSettings(settings);

vcl::CrossSectionSettings css(mesh);
css.type() =
vcl::CrossSectionSettings::CrossSectionType::PER_FRAGMENT;

vcl::Point3f min = css.boundingBox().min();
vcl::Point3f max = css.boundingBox().max();
css.setLowerUpper(
min + (max - min) * 0.25f, max - (max - min) * 0.25f);

mesh.setCrossSectionSettings(css);

mv.pushDrawableObject(std::move(mesh));
},
0.f,
-150.f);
}
}
64 changes: 64 additions & 0 deletions vclib/core/include/vclib/space/core/point.h
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,70 @@ class Point : public Eigen::Matrix<Scalar, N, 1>
at(i) = args[i];
}

/**
* @brief Returns true if all the components of this point are strictly less
* than the corresponding components of another point p1.
*
* @param[in] p1: The Point object to compare with.
* @return true if this point is strictly below p1, false otherwise.
*/
bool allLessThan(const Point& p1) const
{
for (uint i = 0; i < N; i++) {
if (at(i) >= p1(i))
return false;
}
return true;
}

/**
* @brief Returns true if all the components of this point are less than or
* equal to the corresponding components of another point p1.
*
* @param[in] p1: The Point object to compare with.
* @return true if this point is below or equal to p1, false otherwise.
*/
bool allLessEqualThan(const Point& p1) const
{
for (uint i = 0; i < N; i++) {
if (at(i) > p1(i))
return false;
}
return true;
}

/**
* @brief Returns true if all the components of this point are strictly
* greater than the corresponding components of another point p1.
*
* @param[in] p1: The Point object to compare with.
* @return true if this point is strictly above p1, false otherwise.
*/
bool allGreaterThan(const Point& p1) const
{
for (uint i = 0; i < N; i++) {
if (at(i) <= p1(i))
return false;
}
return true;
}

/**
* @brief Returns true if all the components of this point are greater than
* or equal to the corresponding components of another point p1.
*
* @param[in] p1: The Point object to compare with.
* @return true if this point is above or equal to p1, false otherwise.
*/
bool allGreaterEqualThan(const Point& p1) const
{
for (uint i = 0; i < N; i++) {
if (at(i) < p1(i))
return false;
}
return true;
}

/**
* @brief Returns the outer product between this point p and p1, which is
* p * p1^T
Expand Down
41 changes: 39 additions & 2 deletions vclib/render/include/vclib/bgfx/drawable/drawable_mesh_bgfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <vclib/bgfx/context.h>
#include <vclib/bgfx/drawable/drawable_environment.h>
#include <vclib/bgfx/drawable/mesh/mesh_render_buffers.h>
#include <vclib/bgfx/drawable/uniforms/cross_section_uniforms.h>
#include <vclib/bgfx/drawable/uniforms/mesh_render_settings_uniforms.h>

#include <bgfx/bgfx.h>
Expand Down Expand Up @@ -94,6 +95,9 @@ class DrawableMeshBGFX : public AbstractDrawableMesh, public MeshType
mMRB.update(*this, buffersToUpdate);
mMRS.setRenderCapabilityFrom(*this);
setRenderSettings(mMRS);

mCSS.setBoundingBox(*this);
mMRB.updateCrossSectionSettings(mCSS);
}

void updateRenderSettingsCapabilities() override
Expand All @@ -109,6 +113,12 @@ class DrawableMeshBGFX : public AbstractDrawableMesh, public MeshType
mMRB.updatePointsSettings(rs);
}

void setCrossSectionSettings(const CrossSectionSettings& css) override
{
AbstractDrawableMesh::setCrossSectionSettings(css);
mMRB.updateCrossSectionSettings(css);
}

const AbstractMeshProvider& meshProvider() const override
{
return mProvider;
Expand Down Expand Up @@ -205,6 +215,8 @@ class DrawableMeshBGFX : public AbstractDrawableMesh, public MeshType
DrawableMeshUniforms::setColor(*this);
MeshRenderSettingsUniforms::set(mMRS);

updateCrossSectionUniforms();

if (mMRS.isSurface(MRI::Surface::VISIBLE)) {
const DrawableEnvironment* env = settings.environment;

Expand Down Expand Up @@ -314,6 +326,8 @@ class DrawableMeshBGFX : public AbstractDrawableMesh, public MeshType
model = MeshType::transformMatrix().template cast<float>();
}

updateCrossSectionUniforms();

if (mMRS.isSurface(MRI::Surface::VISIBLE)) {
mMRB.bindVertexBuffers(mMRS);
mMRB.bindIndexBuffers(mMRS);
Expand Down Expand Up @@ -349,6 +363,21 @@ class DrawableMeshBGFX : public AbstractDrawableMesh, public MeshType
{
MeshRenderSettingsUniforms::bind();
DrawableMeshUniforms::bind();
CrossSectionUniforms::bind();
}

void updateCrossSectionUniforms() const
{
if (AbstractDrawableMesh::mCSS.isEnabled()) {
using enum CrossSectionSettings::CrossSectionType;
CrossSectionUniforms::set(
AbstractDrawableMesh::mCSS.lower(),
AbstractDrawableMesh::mCSS.upper(),
AbstractDrawableMesh::mCSS.type() == PER_FRAGMENT);
}
else {
CrossSectionUniforms::set();
}
}

/**
Expand Down Expand Up @@ -400,12 +429,17 @@ class DrawableMeshBGFX : public AbstractDrawableMesh, public MeshType
{
using enum MeshRenderInfo::Surface;

uint section = 0;
uint shading = 0;
uint color = 0;
uint selection = 0;
uint backFace = 0;
uint specular = 0;

if (!mCSS.isEnabled()) {
section = 1;
}

if (mMRS.isSurface(SHADING_FLAT)) {
shading = 0;
}
Expand Down Expand Up @@ -455,18 +489,21 @@ class DrawableMeshBGFX : public AbstractDrawableMesh, public MeshType
constexpr uint N_SELECTION_MODES = 2;
constexpr uint N_BACK_FACE_MODES = 2;
constexpr uint N_SPECULAR_MODES = 2;
constexpr uint N_SECTION_MODES = 2;

// the first shader of all the combinations
uint base = toUnderlying(
VertFragProgram::
DRAWABLE_MESH_SURFACE_SHADING_FLAT_COLOR_FACE_SELECTION_ON_BACK_FACE_DOUBLE_OFF_SPECULAR_OFF);
DRAWABLE_MESH_SURFACE_SECTION_ON_SHADING_FLAT_COLOR_FACE_SELECTION_ON_BACK_FACE_DOUBLE_OFF_SPECULAR_OFF);

uint offset = linearizeIndex<
N_SECTION_MODES,
N_SHADING_MODES,
N_COLOR_MODES,
N_SELECTION_MODES,
N_BACK_FACE_MODES,
N_SPECULAR_MODES>(shading, color, selection, backFace, specular);
N_SPECULAR_MODES>(
section, shading, color, selection, backFace, specular);

uint program = base + offset;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,13 @@ class MeshRenderBuffers : public MeshRenderData<MeshRenderBuffers<Mesh>>
mPoints.setSelectionColor(mrs.pointSelectionColor());
}

void updateCrossSectionSettings(const CrossSectionSettings& css)
{
mEdgeLines.setCrossSectionSettings(css);
mWireframeLines.setCrossSectionSettings(css);
mPoints.setCrossSectionSettings(css);
}

private:
void setVertexPositionsBuffer(const MeshType& mesh) // override
{
Expand Down
Loading
Loading