Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
Hello,
I am working with a model that I created a single sequence in CREO Illustrate. It is a simple car moving down an assembly line. I wanted to see if it was possible to just start this sequence immediately once the model has loaded up when starting vuforia instead of having to tie it to a button or something else to get it to start running.
Is there a way to do this?
Thanks!
Andrew
Solved! Go to Solution.
Hi @awilber ,
at the first view I do not see any difference to my code. I checked the project and it working fine in preview so that the code should work in the original context.
1.)So the sequences (pvi) are embed in the pvz file / so you do not need to extract it
2.) when look in the code:
$scope.app.loadsequence = function()
{
$scope.setWidgetProp('model-1', 'sequence', "app/resources/Uploaded/l-Creo 3D - Figure 1.pvi");
twx.app.fn.triggerWidgetService("model-1", 'play');
// it will set the sequence to TestMYFigure1
// and will play it
};
///////////////// start the code when model widget is loaded -complette
$rootScope.$on('modelLoaded', function()
{
$scope.app.loadsequence();
});
so the code will work if your model widget is named "model-1" and the "sequence” property if it is set to "Figure 1" figure. So if you set it in Studio User Interface it is displayed as "Figure 1"
Also your model “src” property (in UI Resource) should be set to the correct pvz file. The model-1 is the name of the widget.
I tested in the original project (for HoloLens) and it works.
So here another version of the code which is more general:
$rootScope.$on('modelLoaded', function() {
$scope.app.playModelStepPvz("engine_test_exp-div-speed_High","Figure 1","model-1",3,true)
})
//////////////
//definition of the function
$scope.app.playModelStepPvz = function (pvz,sequence,modelName,step_number,play) {
//pvz file
//sequnece -sequnece name e.g. TestFigure1 - as shown in UI
//modelName - model name e.g. model-1 widget
//step_number - set this number to current step
//play true/false execute play for the model
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', '');});
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', 'app/resources/Uploaded/'+pvz +'.pvz');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', '');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', 'app/resources/Uploaded/l-Creo 3D - '+sequence +'.pvi');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'currentStep', parseInt(step_number));});
if(play) //check if play should be applyed
$timeout(function () {angular.element(document.getElementById(modelName)).scope().play(); }, 100)
//angular.element(document.getElementById(modelName)).scope().play(); }, 100);
}, 500);
};
So the code above will set t for the widget named: "modelName" the pvz file to the string in the variable "pvz" and will set the sequence and the step number and if the last variable "play" is true it will play it otherwise will not play
I think when the src /Resource property in a model is already set . Is better to use the simpliefied version (performance reasons):
//////////////////////////////////
$scope.app.playModelStep = function (sequence,modelName,step_number,play) {
//sequence -sequnece name e.g. TestFigure1 - as shown in UI
//modelName - model name e.g. model-1 widget
//step_number - set this number to current step
//play true/false execute play for the model
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', '');});
},10);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', 'app/resources/Uploaded/l-Creo 3D - '+sequence +'.pvi');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'currentStep', parseInt(step_number));});
if(play) //check if play should be applyed
$timeout(function () {angular.element(document.getElementById(modelName)).scope().play(); }, 100)
//angular.element(document.getElementById(modelName)).scope().play(); }, 100);
}, 500);
};
//////////////////////////////////
(without pvz ) argument
So here attached the demo project for mobile device
Hi @awilber ,
yes this is possible with javaScript.
I will check my projects and will provide an example....
The following example:
$scope.app.loadsequence = function()
{
$scope.setWidgetProp('model-1', 'sequence', "app/resources/Uploaded/l-Creo 3D - TestMYFigure1.pvi");
twx.app.fn.triggerWidgetService("model-1", 'play');
// it will set the sequence to TestMYFigure1
// and will play it
};
$scope.app.loadsequence1 = function()
{
$scope.setWidgetProp('model-1', 'sequence', "app/resources/Uploaded/l-Creo 3D - SecondTestSecondFigure.pvi");
twx.app.fn.triggerWidgetService("model-1", 'playAll');
// it will set the sequence to SecondTestSecondFigure
// and will play all Stepsi
};
$scope.app.playsequence = function()
{
twx.app.fn.triggerWidgetService("model-1", 'playAll');
// it will only play means you need to set the widget to the correct sequnece
};
///////////////// start the code when model widget is loaded -complette
$rootScope.$on('modelLoaded', function()
{
$scope.app.loadsequence();
// it will set the sequence to TestMYFigure1
// and will play it
});
this code will demonstrate how to start automatically a sequence
You need to add the code to the Home.js (View) or to the view which is called on start.
The modelload event will call the code when the model widget is loaded complette
Then we have 3 different functions:
1.) $scope.app.loadsequence() - it will set the Sequence property to a Figure (please , pay attention that the name is different as the Figure name and you need a prefix and suffix)
e.g. if the sequence is name displayed in UI is "TestFigure1" then you need to call "l-Creo 3D - TestFigure1.pvi"
then it will play the first step
2.) $scope.app.loadsequence() - same as 1.) but it will play all steps of the sequence
3.) this will play all steps. To call this function is required that you already explicitly set the Sequence property in UI
Roland,
Thanks for the reply!
So I took your code and I put it into my .js location.
My model is named model-1 (just as yours was)
When I got into the uploads folder I have 2 .pvi files under a folder. Do I take those .pvi files and load them down to the root "upload" folder, or leave them embedded in the folder below upload?
And then my code I put in there is as follows: What am I missing? I can't seem to get it to go.
$scope.app.loadsequence = function()
{
$scope.setWidgetProp('model-1', 'sequence', "app/resources/Uploaded/l-Creo 3D - Figure 1.pvi");
twx.app.fn.triggerWidgetService("model-1", 'play');
// it will set the sequence to TestMYFigure1
// and will play it
};
$scope.app.loadsequence1 = function()
{
$scope.setWidgetProp('model-1', 'sequence', "app/resources/Uploaded/l-Creo 3D - Figure 2.pvi");
twx.app.fn.triggerWidgetService("model-1", 'playAll');
// it will set the sequence to SecondTestSecondFigure
// and will play all Stepsi
};
$scope.app.playsequence = function()
{
twx.app.fn.triggerWidgetService("model-1", 'playAll');
// it will only play means you need to set the widget to the correct sequnece
};
///////////////// start the code when model widget is loaded -complette
$rootScope.$on('modelLoaded', function()
{
$scope.app.loadsequence();
// it will set the sequence to TestMYFigure1
// and will play it
});
Thank you for the help, greatly appreciated!
Roland, not sure if you saw my reply...still looking to see if you can help clarify how to implement this?
Thank you so much for the help!
Hi @awilber ,
I did see it first now when I tried to answer to a similar request. I will check tommorow and will replay. I am sorry for the delay
Hi @awilber ,
at the first view I do not see any difference to my code. I checked the project and it working fine in preview so that the code should work in the original context.
1.)So the sequences (pvi) are embed in the pvz file / so you do not need to extract it
2.) when look in the code:
$scope.app.loadsequence = function()
{
$scope.setWidgetProp('model-1', 'sequence', "app/resources/Uploaded/l-Creo 3D - Figure 1.pvi");
twx.app.fn.triggerWidgetService("model-1", 'play');
// it will set the sequence to TestMYFigure1
// and will play it
};
///////////////// start the code when model widget is loaded -complette
$rootScope.$on('modelLoaded', function()
{
$scope.app.loadsequence();
});
so the code will work if your model widget is named "model-1" and the "sequence” property if it is set to "Figure 1" figure. So if you set it in Studio User Interface it is displayed as "Figure 1"
Also your model “src” property (in UI Resource) should be set to the correct pvz file. The model-1 is the name of the widget.
I tested in the original project (for HoloLens) and it works.
So here another version of the code which is more general:
$rootScope.$on('modelLoaded', function() {
$scope.app.playModelStepPvz("engine_test_exp-div-speed_High","Figure 1","model-1",3,true)
})
//////////////
//definition of the function
$scope.app.playModelStepPvz = function (pvz,sequence,modelName,step_number,play) {
//pvz file
//sequnece -sequnece name e.g. TestFigure1 - as shown in UI
//modelName - model name e.g. model-1 widget
//step_number - set this number to current step
//play true/false execute play for the model
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', '');});
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', 'app/resources/Uploaded/'+pvz +'.pvz');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', '');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', 'app/resources/Uploaded/l-Creo 3D - '+sequence +'.pvi');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'currentStep', parseInt(step_number));});
if(play) //check if play should be applyed
$timeout(function () {angular.element(document.getElementById(modelName)).scope().play(); }, 100)
//angular.element(document.getElementById(modelName)).scope().play(); }, 100);
}, 500);
};
So the code above will set t for the widget named: "modelName" the pvz file to the string in the variable "pvz" and will set the sequence and the step number and if the last variable "play" is true it will play it otherwise will not play
I think when the src /Resource property in a model is already set . Is better to use the simpliefied version (performance reasons):
//////////////////////////////////
$scope.app.playModelStep = function (sequence,modelName,step_number,play) {
//sequence -sequnece name e.g. TestFigure1 - as shown in UI
//modelName - model name e.g. model-1 widget
//step_number - set this number to current step
//play true/false execute play for the model
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', '');});
},10);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', 'app/resources/Uploaded/l-Creo 3D - '+sequence +'.pvi');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'currentStep', parseInt(step_number));});
if(play) //check if play should be applyed
$timeout(function () {angular.element(document.getElementById(modelName)).scope().play(); }, 100)
//angular.element(document.getElementById(modelName)).scope().play(); }, 100);
}, 500);
};
//////////////////////////////////
(without pvz ) argument
So here attached the demo project for mobile device
Here is another example:
//added the sequnece listener
$scope.$on("sequenceloaded", function (evt, arg) {
console.log("sequence loaded, starting play");
$scope.app.fn.triggerWidgetService("model-1","playAll");});
//////////////////////////////////
$rootScope.$on('modelLoaded', function()
{ $scope.app.test();
});
$scope.app.test=function () {
////////////////
$timeout( function() {$scope.app.setSequence(1);} , 500);
$scope.$applyAsync();
//$timeout( function() {$scope.app.fn.triggerWidgetService("model-1","playAll");} , 1500);
$timeout( function() { $scope.app.setSequence(2); }, 11000);
// $timeout( function() { $scope.app.setSequence(3); }, 30000);
$timeout( function() {twx.app.fn.triggerWidgetService("model-1", 'reset');
$scope.$applyAsync(); console.log("reset-4");
}, 20000);
} //end of test
//var figure_list =["l-Creo 3D - Figure 1","l-Creo 3D - Figure 2","l-Creo 3D - Figure 3"];
var figure_list =["l-Creo 3D - TestFigure1","l-Creo 3D - SecondTestFigure"];
$scope.app.setSequence = function(val)
{ console.log(" called app.setSequnece("+ (val-1)+")=app/resources/Uploaded/"+figure_list[val-1]+".pvi")
try{$scope.setWidgetProp('model-1', 'sequence', "app/resources/Uploaded/"+figure_list[val-1]+".pvi"); }
catch(e) {console.warn("exception="+e);}
$scope.$applyAsync();
};
////////////////////////////// 'stepcompleted' the better way to call an play or playAll when is sequence is loaded
Here is a little bit more complex.
So,we have a model with more than one sequence /Figures and we want to play all of them.
All Figures names are contained by the figure_list variable (javaScript array)
Here the code will start in the modelload event the app.test() function
In the app.test() function then the javascript code will call with delay of 500msec the first sequence. In the sequenceLoad event (when the sequence loading was complette) the code will start the playAll service to play all step of the sequence 1 (the first item in the array list )
On the same way the second sequence will be called with a delay of 11 seconds
And after 20 seconds the code will reset the model widget.