Is there a way to unload a loaded model? - autodesk-forge

I would like to use a single viewer to load/unload models instead of tearing down the viewer and creating a new instance of viewer.
Reasoning: I've loaded multiple models and one of the models is too large and problematic that it slows down the rendering, I'm thinking if it's possible to just unload the problematic model instead of reloading all the models EXCEPT the problematic model.

If you just want to unload a specific model, the following code snippet might help.
const models = viewer.impl.modelQueue().getModels();
const model = models[2]; //!<< The model you want to unload
viewer.impl.unloadModel( model );

Related

Query properties using the forge-viewer library without rendering model

I'm using the forge-viewer library to display models. I'm wondering if it is possible to at the same time query properties from another model, without rendering the other model or altering the state of the original viewer instance?
Preferably by obtaining a new instance of Autodesk.Viewing.Model, in order to use methods like model.getProperties(...).
Loading with the original viewer instance causes the other model to display in the browser
const document: Autodesk.Viewing.Document = await myLoadDocumentFunction("urn:another-model-urn");
const defaultModel = document.getRoot().getDefaultGeometry();
const model = await viewer.loadDocumentNode(document, defaultModel);
As the documentation states, the options input variable for loadDocumentNode() is passed on to loadModel() so you can check the documentation of that function to see what options are available.
One of them is loadAsHidden which seems to do exactly what you need:
FYI: it should also be possible to create another Viewer instance, make it invisible (e.g. placing it off the screen) and load extra models there: Multiple instances of Autodesk Forge Viewer

Access viewer methods from AggregatedView for more than one model in Autodesk Forge Viewer?

I am loading two different models via AggregatedView.
Although I have access to view.viewer, executing
var view = new Autodesk.Viewing.AggregatedView();
//...
view.viewer.isolate([0]);
only affects one of the two models.
Is there any way I can call viewer methods such as isolate(), show(), hide(), etc. on both models?
Note that many of the Viewer3D methods such as Viewer3D#isolate accept an additional parameter that you can use to specify the model.
And if the method you're interested in doesn't accept the model as one of its parameters, you can often find the same method directly on the Model class, for example, Model#getProperties.

Data driven game with phaser 3

well i'm working on an e-learning platform for kids that contain courses and each course contain lessons and some games
games will be programmed in phaser 3
so the admin in the dashboard will have a form to add new course (add the lesson which is a video and also a link to the phaser game since the admin is not a developer so i wanted to transform my phaser game to a link or something like that )
my question is how to get a game set up to use data from json objects from a URL [sort of Data-driven game ]
ps: to develop this platform i'm using spring boot and angular
Until you actually instantiate a Phaser game as e.g. const game = Phaser.Game(myconfig), you can do any number of things to load the required data asynchronously. So the part about getting data is resolved that way.
The question of how to actually use the data is a more broad question. I would consider thinking about the asset loading and then instantiation together, and set up predefined factory functions to consume the same data the Loader functions will take.
You can trivially load assets from json data with the pack method in the Loader plugin, see here.
Then, you need to implement something that will act upon those assets once they are loaded, depending on the data:
{
...
"sceneSprites":{
"oneSprite":{'
"textureKey": "myAssetLoaded",
"x":32,
"y":42,
"tint": 0xff0000
(etc)
}
}
}
The keys that you define in the "pack" part of the json will be in the TextureManager, and you just match that key in the object data.
Then you create a scene with a series of functions that iterate over the data you have and create objects based on the data:
class MyScene extends Phaser.Scene {
create(){
for(const obj of spriteData){
const spr=this.add.sprite(obj.x,obj.y,obj.texturKey)
spr.setTint(obj.tint)
}
}
}
This is just a rough sketch of the things you would have to do. In general you can create one phaser "game" that is built with enough helper factory functions ontop of what phaser provides, to consume the specific data you have in any of your given json files.
I am sure you could cover a lot of Phaser functionality this way, including tweens, shaders, and audio.

How to design correctly a web app in sails.js?

I build a web app using sails.js and I have few questions about the design of the app:
Should I create controllers for each page, component, or model? I saw in the documentation and at some tutorials that they create controllers for each model. That looks nice but if I have a complex page/component and I want to create view with multi models (and data) it doesn't help me.
Where should I put the business logic part of a component or feature? I read about Serivce but I'm not sure that this is the right place.
To sum up, I saw that in sails the code is arranged like the models (you have model, controller and view for each model) but what if I want to arrange it by features or components or pages?
Thanks!
Basically you should have Controller for each Model (but if you don't need specific controller and it would be empty you don't need to create it). It's just a good practice to have a Controller for each Model.
If you use some part of code in many places and it is not connected with one specified Model it should be Service (like sending emails, notifications, logging, images processing). Read about DRY
Controller should be as simple as possible. It should contain call of Model and Service and callback with rendering output. All business logic should be in Models.
I created some additional 'helper' Models for more complex Models like Users or so to make Classes bit shorter.
To sum up. Core of your application is Model. It's not only responsible for database layer, bur also business layer of your app. Later there is Controller. It gets data from Model and it passes it to Views which is responsible for presentation of data taken from Model.
Answer to First
Sails is for REST API it has nothing to do with view.
you just need to know what MVC is and what REST is....
In one Controller you can invoke multiple models or one model can be invoked in multiple controllers.
In one page you can fetch data from two different API's which may be from different controller or Even they can be of different server.
for Example:
In the page you are getting data directly from ellasticsearchAPI(say esAPI1)
You are getting data from sails API(sAPI1).
You are getting data from other sails API(sAPI2).
Answer to Second
For neatness you should try to keep controller as clean as possible. So for the same sailsJS provide you services. Where you can write Common functionalities which are to be used in multiple controllers.
See the codes for example
Codes
here is the controller:
//TestController
module.exports = {
action1:function(req,res){
Model1.find().exec(function(err,data1){
if(err)
return res.negotiate(err);
res.ok(data1);
});
},
action2:function(req,res){
Model2.find().exec(function(err,data1){
if(err)
return res.negotiate(err);
res.ok(data2);
});
},
action3:function(req,res){
var hash=SomeService.getMeHashCode(req.query.text)
res.ok({hashedData:hash});
}
};
And this is service.
//SomeService.js
module.exports = {
getMeHashCode:function(strinToBeHashed){
var hash=doSomeThingToHash(strinToBeHashed);
return hash;
}
};

Model view controller

I have a tree control in my GUI (with naturally lots of GUI/platform specific functions to handle the nodes).
I have a data model with its own complex set of nodes, children, properties etc..
I want the tree to display a representation of the model, be able to send messages to the nodes inside the model and be told to redraw itself when the model changes.
But I don't want the GUI code to need to know the details of the model's data types and I don't want to pollute the model by linking it to the GUI classes.
I can't get my head around how the controller is supposed to do this and what functions it should provide?
(this is in C++ but that shouldn't matter)
GUI "controls" don't quite fit neatly into a model-view-controller pattern because they typically have their own internal model rather than accepting a reference to one. If the control is structured that way, you'll need an adapter class that "data-binds" the control's internal model to the underlying data model.
This can accomplish something similar to what model-view-controller would, except that the adapter class plays the role both of a view hookup component (updating the GUI from the data model) and a controller (interpreting GUI events into model actions).
Qt provides a group of classes for model-view programming. You can hook a tree view to a filesystem model, for example, and neither directly know anything about each other (except a pointer to the model in the view).
Your requirements are:
Tree displays representation of model
Nodes in tree can send messages to nodes inside model
Tree redraws itself based on model changes
I don't know exactly what kind of data you're working with here, but a hierarchical model is a fairly simple thing. I'll take it as a given you know how to iterate hierarchical data and populate a tree view.
Your controller should have member function(s) for sending messages to the model. The parameters should be a model element and the message you want to send. This way, the UI is completely unaware of how the message gets to the element, but can get the messages through.
The last requirement is more tricky, and depends on a few things (e.g., the lifetime of the controller, application architecture, etc.) I'm going to assume the controller lives as long as the tree view does. If that's the case, then your controller should provide a way to set a callback on model changes. Then, when the controller changes the model, it can callback to the UI without being aware of the UI.
i think your troubles start with an unfortunate choice of words. the 'control' thingies doesn't have anything to do with the 'controller' in MVC. that's why some GUI libraries use other names (widgets is a common one).
your 'tree control' is the view, not the controller. it should be tied to the GUI, both for display, and to get GUI events and turn them into 'tree events'.
the controller gets those 'tree events' and does the necessary modifications to the model. that's where you couple the 'action' with the 'response'.
First Solution: You can implement a "Subject observer" pattern between model and view, with model as the subject and view as the observer. Whenever there is a change in the state of model, it can fire a event to all the observers those are registered, they can update themselves.
Second Solution: Introduce a controller, which registers with model as observer. Upon receiving a event for update from Model, it can update the view. Even you can decouple view from controller using one more subject observer pattern between controller and view
Third Solution: Use MVP pattern. Model view Presenter. This pattern used whenever there is no much computation in controller i.e., job of the controller is just to update its corresponding view. Here controller becomes Presenter.
You need a controller that sits outside the display widget but has the state of the tree (in MFc there are CTreeView/CTreeCtrl classes - there is a similiar separation in Qt) the tree controller handles all the data storage and calls redraws on the tree widget.
Changes in the tree widget get sent to the tree controller - so this controller needs to know about the gui functions.
The model will need set/get functions for all the relevant parameters for the nodes. But these can return simple types so aren't dependent on the gui.
Updating the view form the model requires sending a message, if you don't want the model to know about your gui messaging the best you can do is register a callback function (a void pointer to a function) from the tree controller - and call this to do an update.
This update function can then query the model for the changes.