I have issue importing a .OBJ file to Angular 8 Application,

Hi ,

   I am Bhanu, I have issue importing a .OBJ file into Angular 8 Project . The Normal Babylon js works but importing 

`import ‘babylonjs-loaders’ is causing some issues

Can some one provide an example to Import and OBJ file to Angular 8 application
I have tried using the following code

  import { Component, OnInit } from '@angular/core';
//import * as babylon from 'babylonjs';
//import { Scene, Engine } from 'babylonjs';
import * as BABYLON from 'babylonjs';
//import '../../assets/js/babylon.loader.js'
//import '../../assets/js/babylon.js'
//import { SceneLoader } from "@babylonjs/core/Loading/sceneLoader";

//import 'babylonjs-loaders';
//import { GLTFLoader} from "@babylonjs/loaders/glTF";
//import "@babylonjs/loaders/OBJ";

//


@Component({
  selector: 'app-babylon',
  templateUrl: './babylon.component.html',
  styleUrls: ['./babylon.component.scss']
})
export class BabylonComponent implements OnInit {
  y: number = 1;
  lightX: number = 0;
  red: number = 0.7;
  canvas: any;
  engine: any;
  world: any;

  sphere: any;
  skybox: any;

  ngOnInit() {
    this.canvas = document.getElementById('renderCanvas');
    this.engine = new BABYLON.Engine(this.canvas, true, { preserveDrawingBuffer: true, stencil: true });
    var createScene = function () {
      var scene = new BABYLON.Scene(this.engine);
      var camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, -10), scene);
      camera.setTarget(BABYLON.Vector3.Zero());
      camera.attachControl(this.canvas, false);
      var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(this.lightX, 1, 0), scene);

     /* this.skybox = BABYLON.Mesh.CreateBox('skyBox', 100, scene, true);
      var skyboxMaterial = new BABYLON.StandardMaterial("skyBox", scene);
      skyboxMaterial.backFaceCulling = false;
      skyboxMaterial.reflectionTexture = new BABYLON.CubeTexture("https://www.tonytextures.com/free-texture-gallery/sky/Sky_Clouds_Photo_Texture_A_P4192452", scene);
      skyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
      skyboxMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0);
      skyboxMaterial.specularColor = new BABYLON.Color3(0, 0, 0);
      this.skybox.material = skyboxMaterial;*/

      this.sphere = BABYLON.Mesh.CreateSphere('sphere1', 16, 2, scene, false, BABYLON.Mesh.FRONTSIDE);

      var myMaterial = new BABYLON.StandardMaterial("blue", scene);
      myMaterial.diffuseColor = new BABYLON.Color3(.5, 0, 1);
      myMaterial.specularColor = new BABYLON.Color3(this.red, 0.6, 0.87);
      this.sphere.material = myMaterial;
      this.sphere.position.y = this.y;

//-----------------------------------------------------------
      //Added box for testing
      /*var myBox = BABYLON.MeshBuilder.CreateBox("myBox", {height: 5, width: 2, depth: 0.5}, scene);
      var myMaterial = new BABYLON.StandardMaterial("blue", scene);
      myMaterial.diffuseColor = new BABYLON.Color3(.5, 0, 1);
      myMaterial.specularColor = new BABYLON.Color3(this.red, 0.6, 0.87);
      myBox.material = myMaterial;
      myBox.position.y = 3;*/


  //Here try to import 3d model

  BABYLON.SceneLoader.ImportMesh(
    "",
    "https://models.babylonjs.com/Marble/marble/",
    "marble.gltf",
    this.scene,
    function(m) {
      console.log(m);
    }
  );
  
 /* var loader = new BABYLON.AssetsManager(scene);
  var pile = loader.addMeshTask("pile", "", "http://development.stockpilereports.com:3000/public/assets/", "1.obj");
*/
//this.
BABYLON.SceneLoader.ImportMesh(
  '',
  'http://development.stockpilereports.com:3000/public/assets/',
  '1.obj',
  scene,
  (meshes)=> { 
    console.log(meshes)
  
  }
);

//-----------------------------------------------------------------

      var ground = BABYLON.Mesh.CreateGround('ground1', 6, 6, 2, scene, false);
      var myMaterial = new BABYLON.StandardMaterial("green", scene);
      myMaterial.diffuseColor = new BABYLON.Color3(0, .8, 0);
      myMaterial.specularColor = new BABYLON.Color3(0.7, 0.6, 0.87);
      ground.material = myMaterial;
      // Return the created scene
      return scene;
    }.bind(this);

    var scene = createScene();
    this.world = scene;
    // run the render loop
    this.engine.runRenderLoop(function () {
      scene.render();
    });
    window.addEventListener('resize', function () {
      scene.resize();
    });
  }


 
  
}

//// ENd of Code

This is my console.

First you need to chose between ES6 and ES5 version of the library and then use only one strategy here so either babylonjs or @babylonjs/

Then here it looks like the loaders are not present so you would need smthg like:

import * as LOADERS from “babylonjs/loaders”

Thank you very much @sebavan for quick response.
the import is successful.

Here is the Code. I am getting error Unhandled expression at line

import * as BABYLON from ‘@babylonjs/core’;
import * as LOADERS from ‘@babylonjs/loaders/OBJ’
const obj_loader = new LOADERS.OBJFileLoader();
var promise_aft = obj_loader.importMeshAsync( ‘’,scene, ‘http://development.stockpilereports.com/sprdata/646/2019_04/UAV-175410B2-other-20190419124935-29397-2/find_toe/Subtracted.obj’,’’).then(

    (value) => {

        console.log('I passed!');

        console.log(value);

},(error) => { console.log(‘I failed :(’);
console.log(error);
}

);

This error is poppping up in console. Thank you.

I think you want:
obj_loader.importMeshAsync(undefined, scene, undefined, http://.../find_toe, undefined, ‘Subtracted.obj’).then(…)

The argument you are using for url looks like the one for data. If you use the regular loader, it will detect the model type automatically from the extension. Then you pass in the rootUrl and the meshName.

2 Likes

Thanks for Response, the warning msg is gone :grinning:. But i could not see the model in the scene . Please help thank you. This is the code I have use for Importing Model into scene.

I am using the following code:-

ngOnInit() {

    this.canvas = document.getElementById('renderCanvas');

    this.engine = new BABYLON.Engine(this.canvas, true, { preserveDrawingBuffer: true, stencil: true });

    var createScene = function () {

      var scene = new BABYLON.Scene(this.engine);

      var camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, -10), scene);

      camera.setTarget(BABYLON.Vector3.Zero());

      camera.attachControl(this.canvas, false);

      var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(this.lightX, 1, 0), scene);

  //Here try to import 3d model

      const obj_loader = new LOADERS.OBJFileLoader();

      var promise_aft = obj_loader.importMeshAsync(

        '',

       scene, '',

       'http://development.stockpilereports.com/sprdata/646/2019_04/UAV-175410B2-other-20190419124935-29397-2/find_toe/Subtracted.obj',

       undefined).then(

        (value) => {

            console.log('I passed!');

           console.log(value);

            console.log(value.meshes)

        },

        (error) => {

            console.log('I failed :(');

            console.log(error);

        }

    );

    console.log(promise_aft);

    return scene;

    }.bind(this);

    var scene = createScene();

    this.world = scene;

    

    // run the render loop

    this.engine.runRenderLoop(function () {

      scene.render();

    });

    window.addEventListener('resize', function () {

      scene.resize();

    });

  }

Assuming that if you added a regular mesh like box/sphere that you could see it then maybe your model is too large and you need to zoom out more? You would need to share your model, if you need more help.

Hi @brianzinn , thanks for reply , i have tried uploading the OBJ file , but i dont have access to upload the file or .zip file. I am attaching the URL of the file. Thank you.
http://development.stockpilereports.com/sprdata/646/2019_04/UAV-175410B2-other-20190419124935-29397-2/find_toe/Subtracted.obj

I am getting 2 different network errors in the playground. First one is mixed content (you have an http link and the playground switches to https) and the second one is ERR_CERT_COMMON_NAME_INVALID, because your SSL isn’t setup.

Did you try running an HTTP server if you are working locally? Also, your mesh is only visible from one side - in the scene that I loaded it in all the normals were facing away from the camera…

Hi @brianzinn, we are using the same obj file types in our website.

(this was done in html,js).

Now coming to Angular 8 Case I have tried loading the obj file locally, still couldn’t see the obj. This is the code i have tried. Is the below code right ??

import { Component, OnInit } from '@angular/core';

import * as BABYLON from '@babylonjs/core';

import * as LOADERS from '@babylonjs/loaders'

@Component({

  selector: 'app-babylon',

  templateUrl: './babylon.component.html',

  styleUrls: ['./babylon.component.scss']

})

export class BabylonComponent implements OnInit {

  y: number = 1;

  lightX: number = 0;

  red: number = 0.7;

  canvas: any;

  engine: any;

  world: any;

  sphere: any;

  skybox: any;

  async ngOnInit() {

    this.canvas = document.getElementById('renderCanvas');

    this.engine = new BABYLON.Engine(this.canvas, true, { preserveDrawingBuffer: true, stencil: true });

    var createScene =  function () {

    var scene = new BABYLON.Scene(this.engine);

    var camera = new BABYLON.ArcRotateCamera("ArcRotatecamera", 0, 0, 5, new BABYLON.Vector3(0, 3, 0), scene);

     camera.setTarget(BABYLON.Vector3.Zero());

      camera.attachControl(this.canvas, false);

      var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(this.lightX, 1, 0), scene);

    const obj_loader = new LOADERS.OBJFileLoader();

      var promise_aft =   obj_loader.importMeshAsync(

        '',

       scene, '',

       'assets/1.obj',

       undefined).then(

        (value) => {

            console.log('I passed!');

           console.log(value);

        },

        (error) => {

            console.log('I failed :(');

            console.log(error);

        }

    );

    return scene;

    }.bind(this);

    var scene = createScene();

    this.world = scene;

    

    // run the render loop

    this.engine.runRenderLoop(function () {

      scene.render();

    });

    window.addEventListener('resize', function () {

      scene.resize();

    });

  }

}

No that does not look correct, you need to follow the API documentation for calling object methods:
https://doc.babylonjs.com/api/classes/babylon.objfileloader#importmeshasync

importMeshAsync(meshesNames: any, scene: [Scene] (https://doc.babylonjs.com/api/classes/babylon.scene), data: any, rootUrl: string, onProgress?: function, fileName?: string): Promise<object>

Becomes:
obj_loader.importMeshAsync(
‘’,
scene,
‘’,
‘assets/’,
undefined,
‘1.obj’
)

Look in your network tab to make sure you are getting a model.

For OBJ files you need to split the rootUrl and fileName - that’s how MTL files are loaded (if applicable).

If you follow the ES6 guidelines also another way is to import for side-effects and use the regular scene loader. It will detect the ‘.obj’ file extension and choose the appropriate loader.
https://doc.babylonjs.com/features/es6_support#loaders