Giter VIP home page Giter VIP logo

assimpjs's Introduction

assimpjs

The emscripten interface for the assimp library. It runs entirely in the browser, and allows you to import 40+ 3D file formats and access the result in JSON or glTF format. This is not a full port of assimp, but an easy to use interface to access it's functionality.

How to install?

You can get assimpjs from npm:

npm install assimpjs

How to use?

The library runs in the browser and as a node.js module as well.

You will need two files from the dist folder: assimpjs.js and assimpjs.wasm. The wasm file is loaded runtime by the js file.

Given that browsers don't access the file system, you should provide all the files needed for import. Some 3D formats are coming in multiple files, so you should list all of them to import the model properly.

You should provide two things for every file:

  • name: The name of the file. It's used if files are referring to each other.
  • content: The content of the file as an Uint8Array object.

The supported target formats are: assjson, gltf, gltf2, glb, and glb2. The number of result files depends on the format.

Use from the browser

First, include the assimpjs.js file in your website.

<script type="text/javascript" src="assimpjs.js"></script>

After that, download the model files, and pass them to assimpjs.

assimpjs ().then (function (ajs) {
    // fetch the files to import
    let files = [
        'testfiles/cube_with_materials.obj',
        'testfiles/cube_with_materials.mtl'
    ];
    Promise.all (files.map ((file) => fetch (file))).then ((responses) => {
        return Promise.all (responses.map ((res) => res.arrayBuffer ()));
    }).then ((arrayBuffers) => {
        // create new file list object, and add the files
        let fileList = new ajs.FileList ();
        for (let i = 0; i < files.length; i++) {
            fileList.AddFile (files[i], new Uint8Array (arrayBuffers[i]));
        }
        
        // convert file list to assimp json
        let result = ajs.ConvertFileList (fileList, 'assjson');
        
        // check if the conversion succeeded
        if (!result.IsSuccess () || result.FileCount () == 0) {
            resultDiv.innerHTML = result.GetErrorCode ();
            return;
        }

        // get the result file, and convert to string
        let resultFile = result.GetFile (0);
        let jsonContent = new TextDecoder ().decode (resultFile.GetContent ());

        // parse the result json
        let resultJson = JSON.parse (jsonContent);
        
        resultDiv.innerHTML = JSON.stringify (resultJson, null, 4);
    });
});

Use as a node.js module

You should require the assimpjs module in your script. In node.js you can use the file system module to get the buffer of each file.

let fs = require ('fs');
const assimpjs = require ('assimpjs')();

assimpjs.then ((ajs) => {
    // create new file list object
    let fileList = new ajs.FileList ();
    
    // add model files
    fileList.AddFile (
        'cube_with_materials.obj',
        fs.readFileSync ('testfiles/cube_with_materials.obj')
    );
    fileList.AddFile (
        'cube_with_materials.mtl',
        fs.readFileSync ('testfiles/cube_with_materials.mtl')
    );
    
    // convert file list to assimp json
    let result = ajs.ConvertFileList (fileList, 'assjson');

    // check if the conversion succeeded
    if (!result.IsSuccess () || result.FileCount () == 0) {
        console.log (result.GetErrorCode ());
        return;
    }

    // get the result file, and convert to string
    let resultFile = result.GetFile (0);
    let jsonContent = new TextDecoder ().decode (resultFile.GetContent ());

    // parse the result json
    let resultJson = JSON.parse (jsonContent);
});

It's also possible to delay load the required files so they have to be loaded only when the importer needs them. In this case you have to provide only the name and content of the main file, and implement callbacks to provide additional files.

let fs = require ('fs');
const assimpjs = require ('assimpjs')();

assimpjs.then ((ajs) => {
    // convert model
    let result = ajs.ConvertFile (
        // file name
        'cube_with_materials.obj',
        // file format
        'assjson',
        // file content as arraybuffer
        fs.readFileSync ('testfiles/cube_with_materials.obj'),
        // check if file exists by name
        function (fileName) {
            return fs.existsSync ('testfiles/' + fileName);
        },
        // get file content as arraybuffer by name
        function (fileName) {
            return fs.readFileSync ('testfiles/' + fileName);
        }
    );
    
    // check if the conversion succeeded
    if (!result.IsSuccess () || result.FileCount () == 0) {
        console.log (result.GetErrorCode ());
        return;
    }

    // get the result file, and convert to string
    let resultFile = result.GetFile (0);
    let jsonContent = new TextDecoder ().decode (resultFile.GetContent ());

    // parse the result json
    let resultJson = JSON.parse (jsonContent);
});

How to build on Windows?

A set of batch scripts are prepared for building on Windows.

1. Install Prerequisites

Install CMake (3.6 minimum version is needed). Make sure that the cmake executable is in the PATH.

2. Install Emscripten SDK

Run the Emscripten setup script.

tools\setup_emscripten_win.bat

3. Compile the WASM library

Run the release build script.

tools\build_wasm_win_release.bat

4. Build the native project (optional)

If you want to debug the code, it's useful to build a native project. To do that, just use cmake to generate the project of your choice.

How to run locally?

To run the demo and the examples locally, you have to start a web server. Run npm install from the root directory, then run npm start and visit http://localhost:8080.

assimpjs's People

Contributors

dotblack avatar kovacsv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

assimpjs's Issues

Question: Have you tried to couple this with Threee.js

Hi,
I am the maintainer of the Asset-Importer-Lib Repo. Thanks for all your great work here. I am impressed that you have addressed the wasm issue already.
I am currently thinking about integrating a js-based renderer to our model repo. Rendering the stuff would be easy by using trree.js. But I need to intregrate omehow the aiScene intermedfiate format to three.js.

So here somes my question: Have you alreasy some experiences with this approach?

Thanks in advance!
Kim Kulling

How to convert step model to glb?this is a quession

How to convert step model to glb? I try to convert a CAD model to .glb model ,eg: I convert a .step model to .glb model,but show "import error",why?No support?
let result = ajs.ConvertFileList (fileList, 'glb2');

ASSIMP in the browser with ASSIMPJS and three.js

This is intended for those who would like to see ASSIMP(JS) working in the browser.

The ASSIMP Viewer, which is a part of my repository, is sort of a hybrid between ASSIMPJS and three.js and can show a multitude of different 3D models (see the description in the repository).

Probably the best choice for the models would be the test folder from the ASSIMP repository, either downloaded to the computer for a local access or used remotely for example with a URL like this: https://raw.githubusercontent.com/assimp/assimp/master/test/models/IQM/mrfixit.iqm.

If Viktor ever finds a time to update this repository then that my fix some issues that are present currently with a small number of 3D formats. Not all the models in the ASSIMP repository are perfect either and my viewer probably has bugs.

Ability to export an scene

Hello, it would be good if the library can export an scene, either created or imported from a file, to another format. For example import an fbx file and export it to glb.

The documentation states this can be done as follows:

bool exporterTest() override {
    ::Assimp::Importer importer;
    ::Assimp::Exporter exporter;
    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", aiProcess_ValidateDataStructure);
    exporter.Export(scene, "obj", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_out.obj");
    return true;
}

I have tried it

static bool exporterTest(const aiScene* scene) {
	Assimp::Exporter exporter;
	try {
		if (AI_SUCCESS == exporter.Export(scene, "glb", "spider_out.glb")) {
				std::cout << "Exporting file...";
			};
			return true;
	} catch (const std::exception& e) {
		std::cout << e.what();
		return false;
	}
}

However it is not writing the file to the filesystem.

I call this function from the ImportFileListByMainFile for the sake of testing.

Hopefully this can be done.

Thank you very much!

Set specific format as primary file - IRR for example

Hi Viktor.

Just to ask if your code could be adjusted to deal with a specific format as a primary format?

For example, IRR files appear to be a scene that can contain other file formats (like X or IRRMESH) and this PR in the ASSIMP repository shows what an IRR scene would look like.

As per the mentioned example, if I try to use my viewer with it then it's a hit and miss of which file format is to be treated as primary, the following are the examples:

  • scenegraphAnimMod.irr file all by itself will show the shapes from the scene
  • scenegraphAnimMod.irr + dwarf.x files will show the dwarf
  • scenegraphAnimMod.irr + cellar.irrmesh files will show the cellar
  • scenegraphAnimMod.irr + dwarf.x + cellar.irrmesh files will show the cellar
  • scenegraphAnimMod.irr + dwarf.x + cellar.irrmesh + textures will show textured cellar

Loading the WASM file question

First, thanks Viktor, for creating this extremely useful library! I've found it to work much better on my .obj files than the built-in loaders for three.js and babylonjs.

My question: I'm writing a browser app that needs to load very quickly so I'm caching all my resources in IndexedDB on the client side so only the very first load needs to read the source files and other resources (it only loads a package list and verifies the hashes of the cached files). This works well, but assimpjs's loading of its WASM file doesn't work this way. Is there a way I can just hand assimpjs an Blob or ArrayBuffer for the WASM file instead of assimpjs trying to do a request for it?

Supported File Formats

Good day. The Readme states that only the .gltf format is currently supported. I have tried uploading .fbx and .obj files and they also work correctly. Do you plan to disable support for other formats other than .gltf in the future?

Coverting gltf2 files

Hi,
I am trying to convert a gltf2 file into glb2 by adding all the files to the filelist. But the resultant "glb" file still has uri's to texture files.

I used http://3dviewer.net/index.html to visualize the models.

GLTF2 view of model

gltf_view

converted the gltf2 file with the following code.
`assimpjs.then ((ajs) => {
let fileList = new ajs.FileList ();
fileList.AddFile (
'scene.gltf',
fs.readFileSync ("/home/3d-viewer/Microservice-Template/testFiles/breakfast_gltf/scene.gltf")
);

fileList.AddFile (
    'scene.bin',
    fs.readFileSync ("/home/3d-viewer/Microservice-Template/testFiles/breakfast_gltf/scene.bin")
);

fileList.AddFile (
    'lambert1_baseColor.png',
    fs.readFileSync ("/home/3d-viewer/Microservice-Template/testFiles/breakfast_gltf/textures/lambert1_baseColor.png")
);

fileList.AddFile (
    'lambert1_metallicRoughness.png',
    fs.readFileSync ("/home/3d-viewer/Microservice-Template/testFiles/breakfast_gltf/textures/lambert1_metallicRoughness.png")
);

fileList.AddFile (
    'lambert1_normal.png',
    fs.readFileSync ("/home/3d-viewer/Microservice-Template/testFiles/breakfast_gltf/textures/lambert1_normal.png")
);

// convert file list to assimp json
let result = ajs.ConvertFileList (fileList, 'glb2');

// check if the conversion succeeded
if (!result.IsSuccess () || result.FileCount () == 0) {
    const errorCode = result.GetErrorCode ()
    console.log("errorCode", errorCode)
    return
}

// get the result file, and convert to string
let resultFile = result.GetFile (0);
    fs.writeFile(`breakfastTestGltf.glb`, resultFile.GetContent(), (e) => {
        if (e) {
            const errorCode = result.GetErrorCode ()
            console.log("error", e, errorCode);
        } else {
            console.log("success");
        }
    })

});`

The generated glb file gave the following view. It missed the texture files. 3dViewer mentioned regarding the missing files and glb file still had some urls of texture files.

breakfast_gltf

Is this not the right way to do it?

How does the material system work ?

Hi, I've been trying to understand for the past couple of days how the material system works in this port.
Yes, the resulting JSON has a material property, but it is basically unusable due to the lack of information around it.

It would be very helpful if there was some pathway to understanding it.

Thanks in advance.

Add TypeScript/JSDoc types

I mainly code in TypeScript, and it would be beneficial to have compile-time type checking for this library, both in debugging and in production. I noticed the relevant issue in emscripten's repo was closed, and support for it was implemented, so maybe we could use that?

Add download link to the demo page

Hi Viktor.

Just to ask if it would be possible to add a download link to your demo page so the created JSON file could be downloaded as a file.

Since you already have a demo page setup then it would be only for convenience and nothing else.

This topic can be closed at any time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.