Skip to content

mesh_view c api#3229

Open
joa-quim wants to merge 6 commits into
f3d-app:masterfrom
joa-quim:feature/mesh-view-c-api
Open

mesh_view c api#3229
joa-quim wants to merge 6 commits into
f3d-app:masterfrom
joa-quim:feature/mesh-view-c-api

Conversation

@joa-quim

Copy link
Copy Markdown

Describe your changes

Issue ticket number and link if any

Checklist for finalizing the PR

  • I have performed a self-review of my code
  • I have added tests for new features and bugfixes
  • I have added documentation for new features
  • If it is a modifying the libf3d API, I have updated bindings
  • If it is a modifying the .github/workflows/versions.json, I have updated docker_timestamp

AI Disclosure

  • I did not use AI to generate any of the content of that pull request
  • I used AI to generate code in that pull request, if yes please disclose which part of the code was generated and with which model.
  • Claude Opus 4.8 was used in this work

Continuous integration

Please write a comment to run CI, eg: \ci fast.
See here for more info.

joa-quim added 2 commits June 8, 2026 19:05
Expose the zero-copy f3d::mesh_view path through the C API so bindings can
show in-memory meshes (geometry, point/cell scalars, animation) without
copying arrays into libf3d:

- c/types_c_api.h: enum f3d_mesh_data_type_t; structs f3d_data_array_t,
  f3d_cell_array_t, f3d_memory_view_t.
- c/scene_c_api.{h,cxx}: f3d_scene_add_mesh_view() with to_cpp_* converters
  and a concrete c_mesh_view keeping the caller's data pointers.

Also add an optional in-memory base-color (and optional emissive) texture
carried on the mesh_view itself, so a textured/draped mesh needs no temp
image file:

- library/public/mesh_view.h: texture_t {width,height,components,data,
  emissive} + texture_t baseColorTexture in memory_view_t.
- library/src/scene_impl.cxx: build a vtkImageData+vtkTexture (sRGB) from
  baseColorTexture and hand it to the importer.
- vtkext vtkF3DGenericImporter: SetBaseColorTexture(vtkTexture*, bool
  emissive), applied per block in CreateActorForBlock.
- vtkext vtkF3DRenderer: the rendered coloring actor is a clone of the
  importer's OriginalActor; propagate albedoTex/emissiveTex from the source
  actor to the clone when no global texture override is set (RGBA forces
  translucent). Without this an actor-level texture renders blank.

All additive (336 insertions, no deletions).
Smoke test for the zero-copy mesh_view C binding: builds a small in-memory
mesh (a triangle with a per-point scalar) via f3d_memory_view_t and adds it
to the scene with f3d_scene_add_mesh_view. Gated on the same VTK version as
the other zero-copy tests (stride arrays).
@joa-quim joa-quim requested a review from a team as a code owner June 10, 2026 12:52
@github-actions

Copy link
Copy Markdown

You are modifying libf3d public API! ⚠️Please update bindings accordingly⚠️!
You can find them in their respective directories: c, python, java, webassembly.

@Meakk Meakk added the ci:fast label Jun 10, 2026
@Meakk Meakk changed the title Feature/mesh view c api \ci fast Feature/mesh view c api Jun 10, 2026
@Meakk Meakk changed the title Feature/mesh view c api mesh_view c api Jun 10, 2026
@Meakk Meakk self-requested a review June 10, 2026 13:11
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

Style Checks CI failed:

diff --git a/c/scene_c_api.cxx b/c/scene_c_api.cxx
index 4b0a6b1..d792994 100644
--- a/c/scene_c_api.cxx
+++ b/c/scene_c_api.cxx
@@ -179,7 +179,8 @@ f3d::mesh_view::memory_view_t to_cpp_memory_view(const f3d_memory_view_t* c)
     const unsigned int comps = static_cast<unsigned int>(
       c->base_color_texture_components ? c->base_color_texture_components : 3);
     f3d::image img(static_cast<unsigned int>(c->base_color_texture_width),
-      static_cast<unsigned int>(c->base_color_texture_height), comps, f3d::image::ChannelType::BYTE);
+      static_cast<unsigned int>(c->base_color_texture_height), comps,
+      f3d::image::ChannelType::BYTE);
     // setContent deep-copies, so the caller's buffer need not outlive this call
     img.setContent(const_cast<void*>(c->base_color_texture));
     v.baseColorTexture = std::move(img);
diff --git a/c/scene_c_api.h b/c/scene_c_api.h
index 12cf969..0593c7f 100644
--- a/c/scene_c_api.h
+++ b/c/scene_c_api.h
@@ -64,8 +64,8 @@ extern "C"
    * @param t_max Animation time range maximum.
    * @return 1 on success, 0 on failure.
    */
-  F3D_EXPORT int f3d_scene_add_mesh_view(
-    f3d_scene_t* scene, const f3d_memory_view_t* view, const char* name, double t_min, double t_max);
+  F3D_EXPORT int f3d_scene_add_mesh_view(f3d_scene_t* scene, const f3d_memory_view_t* view,
+    const char* name, double t_min, double t_max);
 
   /**
    * @brief Add and load a memory buffer into the scene.
diff --git a/library/src/scene_impl.cxx b/library/src/scene_impl.cxx
index 624c341..b19eb5d 100644
--- a/library/src/scene_impl.cxx
+++ b/library/src/scene_impl.cxx
@@ -19,12 +19,12 @@
 #include <vtkCellArray.h>
 #include <vtkCellData.h>
 #include <vtkFloatArray.h>
+#include <vtkImageData.h>
 #include <vtkLightCollection.h>
 #include <vtkMemoryResourceStream.h>
 #include <vtkPointData.h>
 #include <vtkPoints.h>
 #include <vtkPolyData.h>
-#include <vtkImageData.h>
 #include <vtkProgressBarRepresentation.h>
 #include <vtkProgressBarWidget.h>
 #include <vtkTexture.h>
diff --git a/python/F3DPythonBindings.cxx b/python/F3DPythonBindings.cxx
index b264993..d5200a2 100644
--- a/python/F3DPythonBindings.cxx
+++ b/python/F3DPythonBindings.cxx
@@ -636,8 +636,8 @@ PYBIND11_MODULE(pyf3d, module)
     // base_color_texture_emissive is true the same image is also installed as the emissive map
     // (flat / full-strength display).
     .def_readwrite("base_color_texture", &f3d::mesh_view::memory_view_t::baseColorTexture)
-    .def_readwrite("base_color_texture_emissive",
-                   &f3d::mesh_view::memory_view_t::baseColorTextureEmissive);
+    .def_readwrite(
+      "base_color_texture_emissive", &f3d::mesh_view::memory_view_t::baseColorTextureEmissive);
 
   class PyMesh
     : public f3d::mesh_view
diff --git a/vtkext/private/module/vtkF3DRenderer.cxx b/vtkext/private/module/vtkF3DRenderer.cxx
index 1553ff1..0b067f4 100644
--- a/vtkext/private/module/vtkF3DRenderer.cxx
+++ b/vtkext/private/module/vtkF3DRenderer.cxx
@@ -2599,7 +2599,8 @@ void vtkF3DRenderer::ConfigureActorsProperties()
         coloring.OriginalActor->ForceTranslucentOn();
       }
     }
-    else if (vtkTexture* origAlbedo = coloring.OriginalActor->GetProperty()->GetTexture("albedoTex"))
+    else if (vtkTexture* origAlbedo =
+               coloring.OriginalActor->GetProperty()->GetTexture("albedoTex"))
     {
       // No global override: honour a base-color texture carried by the source actor (e.g.
       // f3d::mesh_view::memory_view_t::baseColorTexture), propagating it to the rendered
@@ -2626,7 +2627,8 @@ void vtkF3DRenderer::ConfigureActorsProperties()
       coloring.Actor->GetProperty()->SetEmissiveTexture(emissTex);
       coloring.OriginalActor->GetProperty()->SetEmissiveTexture(emissTex);
     }
-    else if (vtkTexture* origEmis = coloring.OriginalActor->GetProperty()->GetTexture("emissiveTex"))
+    else if (vtkTexture* origEmis =
+               coloring.OriginalActor->GetProperty()->GetTexture("emissiveTex"))
     {
       // No global override: honour an emissive texture carried by the source actor (e.g.
       // f3d::mesh_view::memory_view_t::baseColorTexture with emissive=true).

Comment thread c/testing/CMakeLists.txt Outdated
Comment thread library/public/mesh_view.h Outdated
std::vector<data_array_t> pointScalars;
std::vector<data_array_t> cellScalars;

// optional in-memory base-color texture (sampled via textureCoordinates)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what makes this optional ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR update has now a longer comments about this

Comment thread c/scene_c_api.cxx

@Meakk Meakk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall it makes sense now, but some improvements needed.
Also I don't think it will pass the coverage requirement.

Comment thread library/public/mesh_view.h Outdated
* must remain valid until the mesh is removed from the scene. When `emissive` is true the
* same image is additionally installed as the emissive texture (for unlit/flat display).
*/
struct texture_t

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as pointed in Discord, I still think we should use f3d::image here and add support for non-owning buffers in f3d::image later.
Since it's public API, it's important to make sure the design is future proof.

Comment thread library/public/mesh_view.h Outdated
size_t height = 0;
size_t components = 3;
const void* data = nullptr;
bool emissive = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why emissive is needed here?
Are you using it? I think what you want is unlit option https://f3d.app/docs/libf3d/OPTIONS#model.unlit

Comment thread library/public/mesh_view.h Outdated
* same image is additionally installed as the emissive texture (for unlit/flat display).
*/
struct texture_t
{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

texture_t C/Python bindings missing and not tested

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in the PR update

@joa-quim

Copy link
Copy Markdown
Author

I am so sorry but somehow the changes involving the using of f3d::image had not left my local copy of the fork and hence had not made it into the PR. Now they do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants