Load local stl file from assets in react native

Hi, I am trying to load local stl files from the assets in my react native app. So far wouldn’t find any solution so if anyone can help then that would be great. :slight_smile:
@sebavan @DarraghBurke

The playground test loading a gltf should be similar, @DarraghBurke can confirm ?

@ryantrem has a post on this subject: Error: Cannot load cubemap because 6 files were not defined - #58 by ryantrem

The base64 method is the quick and dirty solution. Will that work for you? If you have small files, it probably will. If not, the location to put the files will be platform-specific.

Let us know if you have trouble figuring it out.

Hi @DarraghBurke first of all thanks for the response.

I tried the approach that @ryantrem suggested but I changed it a little bit.
Instead of creating a json file, I just read the stl file using react-native-fs with base64 encoding and then passed the contents to the scene loader import mesh function and used the @ryantrem approach of passing the data:base64,${content) to the function but when I see the log I get following error " … CXBR3RKwce8EUf6zC4Rp3RIv9hMEV/azCKU93RAAA: importMesh of undefined from undefined version: undefined, exporter version: undefinedimportMesh has failed JSON parse " ( its a very long string therefore have started it with the dots and since the last part is important )

Below is the code:

if (isiPhone) {
const pathS1 = RNFS.MainBundlePath + ‘/S1.stl’

    RNFS.readFile(pathS1, 'base64').then((contents) => {
      // console.log(`the contents of stl file: ${contents}`)
      SceneLoader.ImportMeshAsync("","",`data:base64,${contents}`).then((result)=>{
          console.log(`THE RESULT OF SCENE LOADER : ${result}`)
        }).catch((error)=> {
          console.log(`THE ERROR BY SCENE LOADER: ${error}`)
        })
      

    }).catch((error) => {
      console.log(`the error while reading file : ${error}`)
    })
  }

Moreover, I placed the local file in the iOS project and fetched it using MainBundlePath.

So still facing the issue and still need some guidance / help.

Are you able to share the exact text of the base64 encoded file? You could use something like Pastebin.com to share it. It’s a bit hard to debug without knowing what your file looks like.

Thanks for responding.

The pastebin.com was unable to handle the file size so I have placed the text of base64 encoded file in the github repository. You can access it here:
stl-babylon/stl-base64-file at e6954aefdf1e7767e142f136e8e47bcf5e79dd30 · AlanSmithGit/stl-babylon · GitHub
Let me know if it works.
Thanks

@DarraghBurke, any updates ?

I’ve never tried the RNFS approach, but if you are already embedding the original file into the app, then it seems like you should be able to just load a URI via app://. If you are trying to make this work for multiple platforms (e.g. iOS and Android), then this can be a hassle because the paths can be different.

Another option as @DarraghBurke pointed out is to embed the base64 encoded model as a .json file. This will for sure work, the downside is the extra file size and loading cost dealing with the base64 decoding. If people use this approach frequently, we could perhaps make it easier by exposing a Babylon React Native NPM script to do the encoding for you using the Buffer class from Node.js (so you could run a command like npx @babylonjs/react-native base64Encode SomeModel.stl).

Another option yet would be to rely on the React Native method of embedding asset files in the app via require. You can see an example of this here: importing a .glb file fails if only local path is provided and not served through HTTP · Issue #165 · BabylonJS/BabylonReactNative · GitHub. In this example, expo-asset is used, but you should be able to achieve the same thing without taking a dependency on Expo by doing this:

import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource';
const stlUri = resolveAssetSource(require('./SomeModel.stl')).uri;
SceneLoader.ImportMeshAsync('', stlUri);

Whether you use expo-asset or the React Native libs directly, you will need to tell the metro bundler to bundle .stl files as assets by modifying the metro.config.js file with these changes:

const defaultAssetExts = require("metro-config/src/defaults/defaults").assetExts;
...
module.exports = {
  ...
  assetExts: [...defaultAssetExts, 'stl'],
};

It would be great if someone could validate these steps and document them here: BabylonReactNative/README.md at master · BabylonJS/BabylonReactNative (github.com)

2 Likes