# Language Bindings

## C

If the C bindings have been generated using the `F3D_BINDINGS_C` CMake option, the libf3d can be used directly from C.
If you want to use CMake, make sure to install not only f3d but also the `sdk` component using `cmake --install <build_dir> --component sdk`

Here is an example showing how to use libf3d c bindings:

```c
  f3d_engine_autoload_plugins();
  f3d_engine_t* engine = f3d_engine_create(0);
  f3d_options_t* options = f3d_engine_get_options(engine);

  f3d_options_set_as_bool(options, "render.grid.enable", 1);
  f3d_options_set_as_bool(options, "render.show_edges", 1);
  f3d_options_set_as_bool(options, "ui.axis", 1);
  f3d_options_set_as_bool(options, "ui.fps", 1);
  f3d_options_set_as_bool(options, "ui.animation_progress", 1);
  f3d_options_set_as_bool(options, "ui.filename", 1);

  f3d_scene_t* scene = f3d_engine_get_scene(engine);
  f3d_scene_add(scene, "f3d/testing/data/dragon.vtu");

  f3d_interactor_t* interactor = f3d_engine_get_interactor(engine);
  f3d_interactor_start(interactor, 1.0 / 30.0);

  // ...

  f3d_engine_delete(engine);
```

```cmake
cmake_minimum_required(VERSION 3.10)
project(f3d-example-c)
find_package(f3d REQUIRED COMPONENTS c_api)
add_executable(f3d-example-c main.c)
target_link_libraries(f3d-example-c
  PRIVATE
  f3d::c_api
)
```

You can see more examples using c bindings in the dedicated example directory [here](https://github.com/f3d-app/f3d/tree/master/examples/libf3d/c).

## Python

If the python bindings have been generated using the `F3D_BINDINGS_PYTHON` CMake option, the libf3d can be used directly from python.
Make sure to set `PYTHONPATH` to path where the python module is built.
Here is an example showing how to use libf3d python bindings:

```python
import f3d

eng = f3d.Engine.create(False)
eng.options.update({
  "model.scivis.array-name": "Normals",
  "model.scivis.component": 0,
  "ui.bar": True,
  "render.grid.enable": True,
  })

eng.scene.add("f3d/testing/data/dragon.vtu")
eng.interactor.start()
```

You can see more examples using python bindings in the dedicated example directory [here](https://github.com/f3d-app/f3d/tree/master/examples/libf3d/python).

### Stubs

It's also possible to generate Python stubs automatically by enabling the CMake option `F3D_BINDINGS_PYTHON_GENERATE_STUBS`.
Python stubs are `.pyi` files defining the public interface, allowing IDEs to auto-complete and do static analysis.

## Javascript

If the Javascript bindings have been generated by building F3D with webassembly and emscriptem, the libf3d can be used directly from a browser.

You can see a simple but complete example web application [here](https://github.com/f3d-app/f3d/blob/master/examples/libf3d/web).

The package can be installed using npm, by running the following command:

```bash
npm install f3d
```

Create the target DOM element `<canvas id="canvas"></canvas>` in your app, then use the following javascript code:

```javascript
// import the module
import f3d from "f3d";

// setup a setting object
const settings = {
  canvas: document.getElementById("canvas"),
  setupOptions: (options) => {
    // background must be set to black for proper blending with transparent canvas
    options.setAsString("render.background.color", "#000000");

    // make it look nice
    options.toggle("render.effect.antialiasing.enable");
    options.toggle("render.effect.tone_mapping");
    options.toggle("render.effect.ambient_occlusion");
    options.toggle("render.hdri.ambient");

    // display widgets
    options.toggle("ui.axis");
    options.toggle("render.grid.enable");
  },
};

f3d(settings)
  .then(async (Module) => {
    // write a 3D file located on the server to the internal filesystem
    const modelFile = await fetch("/assets/example.obj").then((b) =>
      b.arrayBuffer(),
    );
    Module.FS.writeFile("example.obj", new Uint8Array(modelFile));

    // automatically load all supported file format readers
    Module.Engine.autoloadPlugins();

    // create an engine
    Module.engineInstance = Module.Engine.create();

    Module.setupOptions(Module.engineInstance.getOptions());

    // setup the window size based on the canvas size
    const scale = window.devicePixelRatio;
    Module.engineInstance
      .getWindow()
      .setSize(Module.canvas.clientWidth, scale * Module.canvas.clientHeight);

    const scene = Module.engineInstance.getScene();
    scene.add("/example.obj");

    // do a first render and start the interactor
    Module.engineInstance.getWindow().render();
    Module.engineInstance.getInteractor().start();
  })
  .catch((error) => {
    console.error("Internal exception: " + error);
  });
```

Some advanced libf3d API are not bound yet, here's the exhaustive list:

- `f3d::scene`: light related functions
- `f3d::scene`: `scene& add(const mesh_t& mesh)`
- `f3d::camera`: state management
- `f3d::interactor`: bindings related functions
- `f3d::interactor`: `playInteraction` and `recordInteraction`

## Java

If the Java bindings have been generated using the `F3D_BINDINGS_JAVA` CMake option, the libf3d can be used directly from Java >= 17.
You can import the `f3d.jar` package and use the provided Java classes directly.
Make sure to set `java.library.path` to the path where the JNI library is built.
Here is an example showing how to use libf3d Java bindings:

```java
import app.f3d.F3D.*;

public class F3DExample {
  public static void main(String[] args) {

    Engine.autoloadPlugins();

    // Always use try-with-resources idiom to ensure the native engine is released
    try (Engine engine = new Engine(Window.Type.NATIVE)) {
      Scene scene = engine.getScene();
      scene.add("f3d/testing/data/dragon.vtu");

      engine.getWindow().render();
    }
  }
}
```
