xeokit / xeokit-sdk

Open source JavaScript SDK for viewing high-detail, full-precision 3D BIM and AEC models in the Web browser.
https://xeokit.io
Other
729 stars 288 forks source link

[DISCUSSION] What are some ways to run xeokit apps offline? #958

Open xeolabs opened 2 years ago

xeolabs commented 2 years ago

What are some ways to run xeokit apps offline?

How to build a xeokit app for mobile devices, that can load models and save BCF viewpoints etc, at locations where a network is not available?

This is an open issue, where we might discuss techniques for building offline apps on xeokit.

Use Case

  1. Run a xeokit app in a browser on a tablet or phone, with no internet access (eg. on work site)
  2. Load large models (hundreds of MB) from the device's file system
  3. Save BCF JSON viewpoints to the device's file system

AFAIK I don't think we can use browser storage for (2) because the models will be too big. (3) could be done by running the JS in a container that provides file I/O hooks, or by serving HTTP pages locally and maybe feeding them data through a socket from a local file server process of some sort. Some thoughts below...

Limit of xeokit scope

Loading models with HTTP GETs is the only network activity that the xeokit SDK does. All other network activity (eg. loading and saving BCF viewpoints) is the responsibility of the application layer, which is outside the scope of xeokit. in other words, xeokit is a viewer SDK only, that only uses the network for loading models, using HTTP by default.

Accordingly, xeokit's BCFViewpointsPlugin, which captures and restores Viewer state to and from BCF JSON viewpoints, does not manage the actual persistence or transmission of those JSON viewpoints - it just transfers them in and out of the Viewer component.

The snippet below shows how we can inject custom data access objects into xeokit's loader plugins, which might be used to make a xeokit application load models off the file system and meet (2), if file system hooks were somehow available to the DAOs to use.

Run an example of custom loader DAOs here.

class MyDataSource {

    constructor() {
    }
    getXKT(src, ok, error) {
      // Fetch file from local database
    }
}

const xktLoader = new XKTLoaderPlugin(viewer, {
    dataSource: new MyDataSource()
});

That doesn't solve saving and loading BCF of course.

Some Possibilities

Electron

While Electron itself does not natively support iOS development, it can be used to create applications for macOS, Windows, and Linux. I'm not sure, but perhaps it could load XKT files from the iOS file system?

Chrome+Node Running Locally

We could run an app locally on the device using nodejs. The app would:

  1. run an HTTP server on the user's device, that serves the app client HTML pages,
  2. run a NodeJS server process on the device that fetches models and saves BCF viewpoints for the client pages, using the device's file system, maybe with websockets or GET/PUT
  3. open the app pages in a browser on the device, run the app in the browser without internet

Chrome Embedded Framework

CEF allows us to embed a xeokit viewer in an app built in (at least) Java, python, .Net and Go. Essentially it provides a Javascript execution container with most standard browser APIs, that runs inside the Java/python/Net/Go environment, with hooks into that environment for things like file I/O. The app layer would manage the I/O as mentioned earlier, while possibly configuring the xeokit loader plugins with a custom DAO that hooks into the container's I/O.

Perhaps just build a CEF container in python that provides the I/O hooks for loading the models and saving/loading BCF?

Resources

Amoki commented 1 year ago

We did a bit of offline at BIMData.

If we're in an environment allowing to run a local webserver (eg: Electron), running a web server serving files is easy. On iOS, we used createObjectURL to create a readable URL from binary data served by the application in the js context. On Android we used shouldInterceptRequest to catch the query with an interceptor and served local content instead.

We don't know well iOS and Android, there are probably many other (and better) possibilities.

assaad97 commented 1 year ago

i don't think, that its a good idea to define use cases or solutions depending on the used medium (chrome, pwa, etc). i think xeokit-sdk as a package should be take in considiration that it can be used in any framework/library (that uses js/ts). To illustrate what im trying to say, for example to load the viewer, xeokit awaits a canvas id or an html element, so in case im working with react-native for example it won't be possible since there is no html elements in react native. i think the issue to be resolved is a compatibility issue. xeokit as a package should not be limited to browser based apps or mediums. maybe all what i said doesn't make sense, and im open for any corrections.

tmarti commented 1 year ago

In our company, we consume xeokit-sdk in different ways: from a React Native app, from a Xamarin app, and from a React app.

The "classic approach" when consuming xeokit-sdk from native mobile apps (RN, Xamarin, whatever...) is to consume it from inside a WebView (how else would you run JS code from an Android or iOS project?), then mechanisms like what you @Amoki mention are the the way to go: you just intercept requests done by the JS side and serve them locally, even foward the requests to some other API.

As you tell @assaad97, xeokit-sdk is a component that can just be consumed in different ways, and you seem to suggest to have a "catalog" of best-practices when consuming it.

The use case that starts this thread refers to the fact that JS doesn't provide a "user defined storage", either for models or viewpoints. And this is just what depends heavily on the consuming side: xeokit-sdk provides the 3D viewing stuff, whereas the consuming part has control on how to serve and models and provide the persistent state used by xeokit-sdk 🙂

With all this, maybe a collection of sample projects using xeokit-sdk could be a good starting point, such as:

lindenthal commented 7 months ago

Hi @tmarti, Here at OpenProject we are currently building a spike for a mobile app with Flutter. @xeolabs told be about this discussion here. I am very interested in joining forces here to not re-invent the wheel. What are you experience with using xeokit on mobile devices so far? Are your apps publicly available? I guess it is not open source right? Best Niels

tmarti commented 7 months ago

Hello @lindenthal!

The experience is good so far. Some problems in the past with the VRAM usage but recent optimizations in xeokit made it much better.

Our apps are on the stores but you need some user account in Interaxo (a SaaS product line from Tribia AS company, where I work), so not “publicly usable”.

The considerations in the mobile are the ones described in this thread: stick to a webview and intercept certain custom-protocol URL’s for data passing between the native app code and the webview.