Community Tip - You can Bookmark boards, posts or articles that you'd like to access again easily! X
This example briefly describes how you can use the Step names that you used in Creo Illustrate sequence definitions to drive a corresponding step instruction/description in your experience. This is an unsupported, preliminary solution - R&D is working on a better, final solution. But as long as this is not available, you can use this one for PoC and demo purposes.
To setup the scene: Here is what I meant with Step names that you used in Creo Illustrate:
Now in Thingworx Studio you want to have the following result:
The text is rendered with a simple Label widget. You'll have to remember the ID of this widget for the following javascript tweak. Add the following text to the Javascript section of your View:
var labelId = "label-1"; // ID of the Label widget that displays the Step progress and description text
// this $on event handler switches the label based on the the sequence definition
// the arg variable is of the following form: (<step #>/<total step #) <step name>
$scope.$on('newStep', function(evt, arg) {
$scope.setWidgetProp( labelId, "text", arg); // get the currentStep from the arg
});
Now you only need to provide the correct initial value in the Label widget text property and add control widgets (Buttons, Playback) to drive your animation and you're done.
Easy!
Thank you Moritz von Hasselbach. The code works .
But when Creo Illustrate step names inclsude Chinese character,In ThingWorx Studio preview, Chinese characters can not be displayed properly.
Hi Moritz,
How to write a Java script so that a label gets the description of a particular step only when it plays
Regards
Suresh
Hello Moritz,
this is great tutorial. Thank you much. I have two additional questions:
1/ Is possible to show only Step name?
2/ How to show Step description?
Thank you for your time.
Regards
Tomas
Hi Moritz,
As per the previous two comments, I'd also like to know if there is a way to extract out the step description. If I follow your example, the label shows (<step #>/<total step #) <step name>:
As Thomas showed in his previous post, in Creo Illustrate, you would type in detailed information in the notes tab which in the PVI file is stored as step_decription.
If found that in the sequence.js file in the project folder, the function SequenceStep(step) gets the following properties:
And in the vuforia-angluar.js file, there's the definition of the newStepEventArgument that is set to (current step / total steps) step name.
So the question is, how to we extract out the information like step_description into the label text?
Many thanks,
Allan
Hi, Let me know if there are any chance to bring the step_description from Creo Illustrate
Regards,
Thadeus.D
Same request / goal here - would be nice to have the way to get the data from the steps' notes.
Thanks a lot
Hi Moritz,
Good day!
I would like to know, how to display only "step name" in my vuforia studio?
Currently it is showing like this "1/11 Step name". But what I want is only "Step name" to be seen.
Thank you!
You can cut of the first part e.g. '( 1/11) ' with a regexp so that you end up with just the title.
The code snippet would look like this:
var labelId = "label-1"; // ID of the Label widget that displays the Step progress and description text // this $on event handler switches the label based on the the sequence definition // the arg variable is of the following form: (<step #>/<total step #) <step name> $scope.$on('newStep', function(evt, arg) { var arg2 = arg.match(\(\d+\/\d+\) (.*))[1]; $scope.setWidgetProp( labelId, "text", arg2); // get the currentStep from the arg });
Hmm... It gives me an error.
You might try using the 'stepstarted' and/or 'stepcompleted' events instead of newStep. The arguments returned by those events are not concatenated together (as is the case with newStep), and also include a stepDescription which should be the 'notes' for the step from Creo Illustrate.
$scope.$on('stepstarted', function(evt, arg1, arg2, arg3) { var parsedArg3 = JSON.parse(arg3); $scope.view.wdg['label-1']['text'] = "Event: " + evt.name + " arg3 fields, name: " + parsedArg3.stepName + " duration(ms): " + parsedArg3.duration + " total steps: " + parsedArg3.totalSteps + " step desc: " + parsedArg3.stepDescription ; });
Wow. Great idea. Thanks a lot.
I tried your solution but it works only with the chrome browser "preview" of Vuforia Studio. Not in normal use on my iPhone or Tablet. The View app just says: undefined
The description field is also not comming on a HoloLense device.
So In Creo Illustrate (e.g. 5.0) we can define a text note to a step.
In the Preview of the Chrome browser we can received this text via arg3 which is a string containing a json -where we can find also the step note from Creo Illustate . So e.g. the code:
var _stepDescription; // private member Object.defineProperty($scope,"stepDescription",{ get: function() { return _stepDescription; }, set: function(value) { _stepDescription = value; if(_stepDescription) $scope.setWidgetProp("3DLabel-1", "text", _stepDescription); } }); $scope.$on('stepstarted', function(evt, arg1, arg2, arg3) { var parsedArg3 = JSON.parse(arg3); console.warn(evt); console.warn(arg1); console.warn(arg2); console.warn(arg3); console.log("stepName="+parsedArg3.stepName); console.log("stepDescription="+parsedArg3.stepDescription); console.log("nextStep="+parsedArg3.nextStep); $scope.stepDescription=parsedArg3.stepDescription; });
will print in the debugging console in chrome some thing like :
So the code will work fine in the preview and will set the label with the text from the step note in Creo Illustrate
When we review the experience on the HoloLens device - the 3d label will not change. The reason is that the arg3 of the callback function by the stepstarted event will not contain the step note. When we check the Vuforia view log on the HoloLense:
... 2018-10-02 05:22:05.266 -07:00 [Debug] Speech recognition result generated with confidence: High and text "test" 2018-10-02 05:22:05.266 -07:00 [Debug] event [test] broadcast on rootScope and dispatched against domID [] with type [], targetName [] and data [] 2018-10-02 05:22:05.286 -07:00 [Debug] event [stepcompleted] broadcast on rootScope and dispatched against domID [model-1] with type [null], targetName [model-1] and data [{"stepNumber":1,"stepName":"Step 1","nextStep":1,"totalSteps":5}] 2018-10-02 05:22:05.532 -07:00 [Debug] event [stepstarted] broadcast on rootScope and dispatched against domID [model-1] with type [null], targetName [model-1] and data [{"stepNumber":1,"totalSteps":5,"stepName":"Step 1"}] 2018-10-02 05:22:05.532 -07:00 [Debug] stepName=Step 1 2018-10-02 05:22:05.535 -07:00 [Debug] stepDescription=undefined 2018-10-02 05:22:05.535 -07:00 [Debug] nextStep=undefined 2018-10-02 05:22:13.892 -07:00 [Debug] event [stepcompleted] broadcast on rootScope and dispatched against domID [model-1] with type [null], targetName [model-1] and data [{"stepNumber":1,"stepName":"Step 1","acknowledge":false,"acknowledgeMessage":"TODO: figure out real acknowledge message","nextStep":2,"totalSteps":5}] ...
we can see that the arg3 argument contains the step number, next step, step name ... etc. but not the the step note.
To track the step number / name and the total number of steps such code will work fine.
With the mentioned events ('stepstarted' and/or 'stepcompleted' )will work fine but the described method in the original post should still work.
So to monitor the steps in a view I used a similar approach with RegEx expression and it works stable.
So the following definition:
///////////// var stepArray = ['0-Start Step', '1-DoorLock installation', '2-mount the DoorFrame', '3-Assemble the Isolation', '4-Assemble the Door panel', '5-Assembly the Door Handles', '6-Check the Door Mechanism and clean', 'step 6', 'step 7']; $scope.$on('newStep', function(evt,arg) { console.debug("console.debug: $scope.$on -> newStep:".concat("started") ); var getStepRegex = /\((\d*)\//; console.log("console.log():".concat(arg)); console.info("console.info():getStepRegex.exec(arg)[0]=".concat(getStepRegex.exec(arg)[0]) ); console.warn("console.warn():getStepRegex.exec(arg)[1]=".concat(getStepRegex.exec(arg)[1]) ); $scope.message = getStepRegex.exec(arg)[1]; console.info('message='+$scope.message); console.info('modelXrotation='+$scope.modelXrotation); }); Object.defineProperty($scope, 'message', { get: function () { return _message; }, set: function (step) { if(stepArray[step]) { //_message = step + ': ' + stepArray[step]; _message = 'PLAY STEP: ' + stepArray[step]; } else { _message = "Something going wrong- retry,please!"; }
The code above will print for e.g. step nr. 2 the following messages into the console (Str +Schift +I):
console.log():(2/7) Step 2 console.info():getStepRegex.exec(arg)[0]=(2/ console.warn():getStepRegex.exec(arg)[1]=2 message=PLAY STEP: 2-mount the DoorFrame
And it will update correctly the 3d Label with the correct instruction (picutre bellow for steps 1 ... 3 and 5)
Hey there,
is there any new possibility to use the step notes in studio?
Note: if "Allow download for offline viewing" is activated, it won't run properly in offline mode. You might need to change
$scope.setWidgetProp(labelId, "text", arg)
into
$scope.view.wdg['labelId']['text']=arg;
I don't know why, but it worked for me.
Hello All,
I have managed to get the step names visible in Studio.
But I have some of those containing special character s (i.e. "é", "á"). Those are not showing correctly in the Studio preview.
Illustrate exports them fine, as I can judge from the .xlf file.
How can I get the correct values in Studio?
Thanks
I had the same problem, and I found encoding and decoding the string seems to do the trick:
$rootScope.$on("newStep", function(evt, arg) { var text = decodeURIComponent(escape(arg.match(/\d*\)\s*(.*)$/)[1])); console.log("newStep: setting steptext to " + text); $scope.stepText = text; });
Wait, I take it back. I just discovered that this approach doesn't work on many devices. Back to the drawing board...
So, it turns out, my solution works great in the browser preview, but it throws exceptions on iOS (at least some of the time). Happily, I found that on iOS I could just pass through the string and it would render correctly.
Here's a new version of the function that seems to work OK both in preview and on iOS:
$scope.$on("newStep", function (evt, arg) { var stepname = $scope.fixEncoding(arg); $scope.setWidgetProp("instruction","text", stepname); }); $scope.fixEncoding = function(str) { try { return decodeURIComponent(escape(str)); } catch (ex) { // can't convert, just use string as-is return str; } }