ziguri

[solved] Use ArcRotateCamera with imported STL file

Recommended Posts

Hi,

i am loading a STL file as described in https://doc.babylonjs.com/extensions/stl

My aim is to use the ArcRotateCamera to view, rotate, zoom the 3D Modell.

Is based my code on this example (http://www.babylonjs-playground.com/#1GM4YQ) and replaced the Import Mesh part with the STL import. Therefore hand.js and babylon.stlFileLoader.js are imported. The STL files are in binary and ascii (i tried both). Please find the example STL files (just a cube) attached.

Here the code:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

        <title>Babylon.js sample code</title>
        <!-- Babylon.js -->
		<script src="lib/dist/babylon.js"></script>
		<script src="lib/dist/loaders/babylon.stlFileLoader.js"></script>
        <script src="handjs/bin/hand.js"></script>
		
		<script src="https://preview.babylonjs.com/cannon.js"></script>
        <script src="https://preview.babylonjs.com/oimo.js"></script>	
        
        <style> 
            html, body {
                overflow: hidden;
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }

            #renderCanvas {
                width: 100%;
                height: 100%;
                touch-action: none;
            }
        </style>
    </head>
<body>
    <div id="canvasZone">
        <canvas id="renderCanvas"></canvas>
    </div>
    <script>
        var canvas = document.getElementById("renderCanvas");
        var engine = new BABYLON.Engine(canvas, true);

        var createScene = function () {
            var scene = new BABYLON.Scene(engine);
			

        
            //Adding a light
            var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 20, 100), scene);
        
            //Adding an Arc Rotate Camera
            var camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, BABYLON.Vector3.Zero(), scene);
            camera.attachControl(canvas, false);
        
            // The first parameter can be used to specify which mesh to import. Here we import all meshes
            //BABYLON.SceneLoader.ImportMesh("", "scenes/", "skull.babylon", scene, function (newMeshes) {
                // Set the target of the camera to the first imported mesh
            //    camera.target = newMeshes[0];
            //});
			
			BABYLON.SceneLoader.Load("stlfiles/", "blockstla.stl", engine, function (newScene) {
					newScene.activeCamera.attachControl(canvas, false);
					engine.runRenderLoop(function () {
						newScene.render();
					});
				});
				
        
            // Move the light with the camera
            scene.registerBeforeRender(function () {
                light.position = camera.position;
            });
        
            return scene;
        }
        
        var scene = createScene();

        engine.runRenderLoop(function () {
            scene.render();
        });

        // Resize
        window.addEventListener("resize", function () {
            engine.resize();
        });
    </script>
</body>
</html>

The STL model is loading as expected but the ArcRotateCamera is not working as expected. I have the feeling that I only have the functionalities of the FreeCamera.

Please find the result here: http://www.ferrisol.com/apo/stl3.html

Are there any known incompatibilities with the STL Loader and the ArcRotateCamera?

Did i make a mistake?

Thx for your help

blockstl.stl

blockstla.stl

Share this post


Link to post
Share on other sites

Hi @ziguri and welcome to forum,

You need set active camera. :)

newScene.activeCamera=camera;

All code:

<script>
    var camera;
    var canvas = document.getElementById("renderCanvas");
    var engine = new BABYLON.Engine(canvas, true);

    var createScene = function () {
        var scene = new BABYLON.Scene(engine);
        var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(20, 20, 100), scene);

        //Adding an Arc Rotate Camera
        camera = new BABYLON.ArcRotateCamera("Camera", 0, 0.8, 100, BABYLON.Vector3.Zero(), scene);
        camera.attachControl(canvas, false);

        BABYLON.SceneLoader.Load("lib/test/", "blockstla.stl", engine, function (newScene) {
            camera.setPosition(new BABYLON.Vector3(-25,10,-50));
            newScene.activeCamera=camera;

            engine.runRenderLoop(function () {
                newScene.render();
            });
        });
        return scene;
    }

    var scene = createScene();

    // Resize
    window.addEventListener("resize", function () {
        engine.resize();
    });
</script>

Share this post


Link to post
Share on other sites

Hi @Arte

Thank you for the warm welcome and your help. This fixed my initial problem. I am now able to use the ArcRotateCamera.

But loading another bigger STL shape I have the problem that parts of the STL are cut and kind of hiding behind the background. Please find the STL as well as a screenshot to document the issue attached. 

Here the code snippet:

var createScene = function () {
	var scene = new BABYLON.Scene(engine);

	//Adding a light
    var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

	//Adding an Arc Rotate Camera
	var camera = new BABYLON.ArcRotateCamera("Camera",0, 0, 0, BABYLON.Vector3.Zero(), scene);
	camera.attachControl(canvas, false);

	BABYLON.SceneLoader.Load("", "shape.stl", engine, function (newScene) {
		camera.wheelPrecision = 0.2; //Zoom Speed Desktop
		camera.pinchPrecision = 1.7; //Zoom Speed Mobile
		camera.angularSensibilityX = 2500;
		camera.angularSensibilityY = 2000;
		camera.setPosition(new BABYLON.Vector3(-0.5,1.3,-10000));
		newScene.activeCamera = camera;

		engine.runRenderLoop(function () {
			newScene.render(); 
		});
	});
										
	// Move the light with the camera
	scene.registerBeforeRender(function () {
		light.position = camera.position;
	});
	return scene;
}

I guess its a reposition problem of the camera. How do I find the correct camera position if I don't know the size of the STL object to load?

Second issue: Is there a way to scale a loaded STL? I tried to

newScene.scaling = new BABYLON.Vector3(0.5,0.5,0.5);  

which is not working.

Can you give me a short hint?

cutted_shape.PNG

shape.stl

Share this post


Link to post
Share on other sites

Hi @Arte

You are great. Thx for the hint. That helps a lot.

I now have the issue that a loaded object is visible and solid if I look to in from the BOTTOM OUTSIDE.bottom_outside.thumb.PNG.ad5952f42658953d24211a8ad7fc9c15.PNG

But if I take a look from the TOP to the INSIDE (it's not a closed mesh) some parts become invisible.

top_inside.thumb.PNG.97ad42f8bf898e85d53cd74ee1d6347f.PNG

Ideally, i want to have everything visible. If that's not possible the view from the TOP to the INSIDE is more important than the BOTTOM OUTSIDE view.

Is that a light position issue? Or something else?
If you have another hint would be great.

Thx in advance

Share this post


Link to post
Share on other sites

Hi @Deltakosh

Yes i tried the backFaceCulling but i probably applied it wrong?!

Heres the code:

var createScene = function () {
	var scene = new BABYLON.Scene(engine);

	//Adding a light
        var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

	//Adding an Arc Rotate Camera
	var camera = new BABYLON.ArcRotateCamera("Camera",0, 0, 0, BABYLON.Vector3.Zero(), scene);
	camera.attachControl(canvas, false);

        var model = BABYLON.SceneLoader.Load("stlfiles/", "2037009_2_highRes.stl", engine, function (newScene) {
			camera.target = new BABYLON.Vector3(0, -2000, 0);
			camera.lowerBetaLimit = NaN;
			camera.upperBetaLimit = NaN;
			camera.wheelPrecision = 0.1; //Zoom Speed Desktop
			camera.pinchPrecision = 0.2; //Zoom Speed Mobile
			camera.angularSensibilityX = 2500;
			camera.angularSensibilityY = 2000;
			camera.maxZ = 50000;

			camera.setPosition(new BABYLON.Vector3(6635,-6550,-9130));

			newScene.activeCamera = camera;

			engine.runRenderLoop(function () {
				newScene.render();
				});
		});
        model.backFaceCulling = false;

										
	// Move the light with the camera
	scene.registerBeforeRender(function () {
		light.position = camera.position;
	});
	return scene;
}

How can i apply stuff like that to something loaded from STL?

Share this post


Link to post
Share on other sites

Just my 2 cents here - ImportMesh would be better than an entire scene load. ImportMesh only import meshes, whereas Load is creating a whole new scene (hence the need to render the scene using the engine.

Here is a quick example:

https://www.babylonjs-playground.com/#T7ED1A#2

Share this post


Link to post
Share on other sites
On 9/22/2017 at 4:10 PM, RaananW said:

Just my 2 cents here - ImportMesh would be better than an entire scene load. ImportMesh only import meshes, whereas Load is creating a whole new scene (hence the need to render the scene using the engine.

Here is a quick example:

https://www.babylonjs-playground.com/#T7ED1A#2

1

@RaananW Thx for your 2 cents.

I just tried to use ImportMesh. It's much faster in terms of FPS on mobile devices - but it does not look as accurate as the STL File.

Is there a way to let the imported mesh look like the imported STL? 

Is there a way to increase the number of triangles in the mesh to increase accuracy

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.