diff --git a/packages/data/src/Data.ts b/packages/data/src/Data.ts
index 5fb3ec946..70333af51 100755
--- a/packages/data/src/Data.ts
+++ b/packages/data/src/Data.ts
@@ -10,6 +10,10 @@ import type {SearchParams} from "./SearchParams";
/**
* An entity-relationship semantic data model.
*
+ * A Data is a container of {@link @xeokit/data!DataModel | DataModels}, {@link @xeokit/data!DataObject | DataObjects},
+ * {@link @xeokit/data!Relationship | Relationships}, {@link @xeokit/data!PropertySet | PropertySets}
+ * and {@link @xeokit/data!Properties | Properties}.
+ *
* See {@link "@xeokit/data" | @xeokit/data} for usage.
*/
export class Data extends Component {
@@ -107,7 +111,7 @@ export class Data extends Component {
* fire events via {@link @xeokit/data!Data.onModelCreated | Data.onModelCreated} and {@link @xeokit/data!DataModel.onBuilt | DataModel.onBuilt}, to
* indicate to any subscribers that the DataModel is built and ready for use.
*
- * Note that while we're building/loading the SceneModel, each call that we make to {@link @xeokit/data!DataModel.createObject | DataModel.createObject}
+ * Note that while we're building/loading the DataModel, each call that we make to {@link @xeokit/data!DataModel.createObject | DataModel.createObject}
* will create a new {@link @xeokit/data!DataObject | DataObject}
* in {@link @xeokit/data!Data.objects | Data.objects} and {@link @xeokit/data!DataModel.objects | DataModel.objects}, and will also fire an event
* via {@link @xeokit/data!Data.onObjectCreated | Data.onObjectCreated}. However,
diff --git a/packages/data/src/index.ts b/packages/data/src/index.ts
index 03aded75c..1d7d10835 100755
--- a/packages/data/src/index.ts
+++ b/packages/data/src/index.ts
@@ -8,10 +8,12 @@
*
* ---
*
- * ### *The SDK's buildable, queryable, importable and exportable semantic data model*
+ * ***The SDK's buildable, queryable, importable and exportable semantic data model***
*
* ---
*
+ * # Overview
+ *
* The xeokit SDK uses a generic entity-relationship data graph to manage model semantics. This graph includes entities,
* properties, and relationships and is compatible with both the browser and NodeJS. It serves as a versatile tool for generating
* models, converting between model formats, and navigating content within the model viewer.
@@ -41,20 +43,21 @@
* on the Data. Additionally, DataModels automatically reuse DataObjects and PropertySets wherever they're already
* created by other DataModels. Finally, DataObjects can have Relationships with other DataObjects in different DataModels.
*
- * ## Installation
+ *
+ *
+ * # Installation
*
* ````bash
* npm install @xeokit/data
* ````
*
- * ## Usage
+ *
*
- * * [Creating a DataModel from JSON](#creating-a-scenemodel)
- * * [Creating a DataModel using Builder Methods](#creating-a-scenemodel)
- * * [Reading DataObjects](#reading-dataobjects)
- * * [Searching DataObjects](#searching-dataobjects)
+ * # Usage
*
- * ### Creating a DataModel from JSON
+ *
+ *
+ * ## Creating a DataModel from JSON
*
* We will start with an example where we create a {@link @xeokit/data!DataModel | DataModel} using a single parameter
* object of type {@link @xeokit/data!DataModelParams | DataModelParams}.
@@ -67,12 +70,12 @@
* DataObjects to give them attributes such as height and weight.
*
* To give the DataObjects and {@link @xeokit/data!Relationship | Relationships} semantic meaning, we will assign
- * them types from one of the SDK's bundled data type sets, basicTypes. This set of types classifies each DataObject
+ * them types from one of the SDK's bundled data type sets, {@link "@xeokit/basictypes" | @xeokit/basictypes}. This set of types classifies each DataObject
* as a {@link @xeokit/basictypes!BasicEntity | BasicEntity} and each Relationship as
* a {@link @xeokit/basictypes!BasicAggregation | BasicAggregation}.
*
* It's worth noting that in a real-world scenario, we would likely use a more complex set of data types, such as
- * {@link @xeokit/ifctypes}. However, we cannot mix different sets of data types within our {@link @xeokit/data!Data | Data},
+ * {@link "@xeokit/ifctypes" | @xeokit/ifctypes}. However, we cannot mix different sets of data types within our {@link @xeokit/data!Data | Data},
* as traversals of the DataObjects with {@link @xeokit/data!Data.searchObjects | Data.searchObjects } must be
* guided uniformly by the same set of types across all the DataObjects and Relationships in the graph.
*
@@ -209,7 +212,9 @@
* }
* ````
*
- * ### Creating a DataModel using Builder Methods
+ *
+ *
+ * ## Creating a DataModel using Builder Methods
*
* In our second example, we'll create our {@link @xeokit/data!DataModel | DataModel} again, this time instantiating
* each {@link @xeokit/data!PropertySet | PropertySet}, {@link Property}, {@link @xeokit/data!DataObject | DataObject}
@@ -370,7 +375,9 @@
* }
* ````
*
- * ### Reading DataObjects
+ *
+ *
+ * ## Reading DataObjects
*
* With our {@link @xeokit/scene!SceneModel | SceneModel} built, we'll now use the {@link @xeokit/data!Data.searchObjects | Data.searchObjects} method to
* traverse it to fetch the IDs of the {@link @xeokit/data!DataObject | DataObjects} we find on that path.
@@ -391,9 +398,11 @@
* // resultObjectIds == ["table", "tableTop", "redLeg", "greenLeg", "blueLeg", "yellowLeg"];
* ````
*
- * ### Searching DataObjects
+ *
+ *
+ * ## Searching DataObjects
*
- * In our fourth example, we'll demonstrate how to traverse the {@link @xeokit/data!DataObject | DataObjects} along their
+ * In our next example, we'll demonstrate how to traverse the {@link @xeokit/data!DataObject | DataObjects} along their
* {@link @xeokit/data!Relationship | Relationships}. We'll start at the root DataObject and visit all the DataObjects
* we encounter along the outgoing Relationships.
*
@@ -410,6 +419,37 @@
* //..
* }
* ````
+ *
+ *
+ *
+ * ## Serializing a DataModel to JSON
+ *
+ * ````javascript
+ * const dataModelJSON = dataModel.getJSON();
+ * ````
+ *
+ *
+ *
+ * ## Deserializing a DataModel from JSON
+ *
+ * ````javascript
+ * const dataModel2 = sce.createDataModel({
+ * id: "myDataModel2"
+ * });
+ *
+ * dataModel2.fromJSON(dataModelJSON);
+ *
+ * dataModel2.build();
+ * ````
+ *
+ *
+ *
+ * ## Destroying a DataModel
+ *
+ * ````javascript
+ * dataModel2.destroy();
+ * ````
+ *
* @module @xeokit/data
*/
export * from "./Data";
@@ -425,3 +465,4 @@ export * from "./DataObjectParams";
export * from "./PropertyParams";
export * from "./PropertySetParams";
export * from "./SearchParams";
+export * from "./loadDataModel";
diff --git a/packages/data/src/loadDataModel.ts b/packages/data/src/loadDataModel.ts
new file mode 100644
index 000000000..1a5da23b7
--- /dev/null
+++ b/packages/data/src/loadDataModel.ts
@@ -0,0 +1,45 @@
+import {DataModelParams} from "./DataModelParams";
+import {DataModel} from "./DataModel";
+
+
+/**
+ * Loads {@link @xeokit/scene!DataModelParams | DataModelParams} into a {@link @xeokit/scene!DataModel | DataModel}.
+ *
+ * Expects {@link @xeokit/scene!DataModel.built | DataModel.built} and
+ * {@link @xeokit/scene!DataModel.destroyed | DataModel.destroyed} to be ````false````
+ *
+ * See {@link "@xeokit/data" | @xeokit/data} for usage.
+ *
+ * @param params - Loading parameters.
+ * @param params.fileData - DataModelParams to load.
+ * @param params.dataModel - DataModel to load into.
+ * @returns {Promise} Resolves when DataModel has been loaded.
+ * @throws *{@link @xeokit/core!SDKError | SDKError}*
+ * * If the DataModel has already been destroyed.
+ * * If the DataModel has already been built.
+ */
+export function loadDataModel(params: {
+ fileData: DataModelParams;
+ dataModel: DataModel;
+}): Promise {
+ return new Promise(function (resolve, reject) {
+ if (!params) {
+ return reject("Argument expected: params");
+ }
+ const {fileData, dataModel} = params;
+ if (!fileData) {
+ return reject("Argument expected: fileData");
+ }
+ if (!dataModel) {
+ return reject("Parameter expected: params.dataModel");
+ }
+ if (dataModel.destroyed) {
+ return reject("DataModel already destroyed");
+ }
+ if (dataModel.built) {
+ return reject("DataModel already built");
+ }
+ dataModel.fromJSON(fileData);
+ return resolve();
+ });
+}