Importing Blender Model into a Vaadin Flow project using Three.js

I’m using Vaadin Flow version 24.7 and Three.js version 0.176.0. I used template for Vaadin Flow with Three.js from this source: GitHub - Artur-/threejs-vaadin: Simple example of using three.js and Vaadin 14. I wanted to import a Blender .obj file with the Three.js OBJLoader. When I try to do this Vaadin overwrites my .obj file with auto-generated HTML code. I’ve different locations for the file. I’ve tried to set

vaadin.exclude-urls=/folder_name/**

and more I don’t remember anymore but nothing works.

JS file for Three.js

import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';

class ThreejsTest {
    init(element) {
        this.element = element;
        this.camera = new THREE.PerspectiveCamera(
            70,
            window.innerWidth / window.innerHeight,
            0.01,
            10
        );
        this.camera.position.z = 1;

        this.scene = new THREE.Scene();

        // this.geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
        // this.material = new THREE.MeshNormalMaterial();

        // this.mesh = new THREE.Mesh(this.geometry, this.material);
        // this.scene.add(this.mesh);

        // this.renderer = new THREE.WebGLRenderer({
        // antialias: true,
        // canvas: element
        // });

        // // Use a random spinning direction
        // this.xIncrement = (Math.random() - 0.5) / 10;
        // this.yIncrement = (Math.random() - 0.5) / 10;

        
        this.material = new THREE.MeshNormalMaterial();

        const objLoader = new OBJLoader();
        objLoader.load("6SidedDice.obj", (object) => {
            object.traverse( (child) => {
                if ( child instanceof THREE.Mesh ) {
                    child.material = this.material;
                }
            });

            let bbox = new THREE.Box3().setFromObject(object);

            const center = new THREE.Vector3();
            bbox.getCenter(center);

            
            let bsphere = bbox.getBoundingSphere(new THREE.Sphere(center));
            let m = new THREE.MeshStandardMaterial({
                color: 0xffffff,
                opacity: 0.3,
                transparent: true
            });

            var geometry = new THREE.SphereGeometry(bsphere.radius, 32, 32);
            let sMesh = new THREE.Mesh(geometry, m);
            this.scene.add(sMesh);
            const box = new THREE.Box3().setFromObject(root);
            const boxSize = box.getSize(new THREE.Vector3()).length();
            const boxCenter = box.getCenter(new THREE.Vector3());
            console.log(boxSize);
            console.log(boxCenter);
        });

        //objLoader.setMaterials(this.material);

        this.renderer = new THREE.WebGLRenderer({
            antialias: true,
            canvas: element
        });
    }

    render() {
        this.renderer.render(this.scene, this.camera);
    }

    animate() {
        requestAnimationFrame(this.animate.bind(this));
        this.render();
    }
}

window.initThree = function(element) {
    const threejsTest = new ThreejsTest();
    threejsTest.init(element);
    threejsTest.animate();
}

I don’t think Vaadin directly overwrites the files, but rather that your file is not in in a location that the static resource handler looks at. As a consequence of that, there’s instead some default fallback content served for that request.

The default location for static resources is src/main/resources/META-INF/resources. If you deploy as a .war, then src/main/webapp will also work but that’s not the case with the default Spring Boot setup that is based on .jar deployment.

See also the docs for a handy table: How to load resources dynamically in Vaadin

I have changed it so it matches your recommendations and now it dosn’t have the auto-generated HTML code anymore. Instead I get the content of the .obj file but encoded as base64:

I have no idea for why anything from Vaadin would automatically apply base64 encoding for static resources. Are you sure the original file isn’t also in base64 format? I found some references to that being used if exporting from Blender using GLTF.

I exported the model from Blender as .obj file directly. Here is part of the file:

I don’t know why this is happening but in my project folder the file content isn’t encoded. But when i run the Application.java file from Vaadin Flow and open the site on a browser, go into dev tools and go to the answer tab of the request for the file in the network analysis it shows it as base64 encoded. And the object won’t load in the Three.js canvas area.

I wonder if that might be related to the x-tgif content type that is probably applied automatically based on the .obj extension. You could try renaming the file to have a .txt extension and changing the reference in the JS file accordingly.

If that helps, then you could try changing the default mime mappings. Assuming you’re using Spring Boot, then you can follow the example for Spring Boot 2 in https://stackoverflow.com/a/47263286/2376954 (the same should also apply for Spring Boot 3).