cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X

Vuforia Studio and Chalk Tech Tips

Sort by:
How can we make a 3D Widget on HoloLens visible in front of me every time ?  The goal here is to get a some UI containing 3D Widgets (3dButtons , 3dImages , 3d Labels and 3d Models) in front of current HoloLens view. For example after saying "show UI" the UI elements should appear in front view e.g. distance of 1,5 meters. Example:   In the Tech Tip article "How to create a custom button pressable on HoloLens device?" is shown how to create a custom UI button. Now  based on the example of this project   the functionality will be extended by adding the possibility for dynamic display of the UI elements in front of the current view. To be able to move the elements in front of us we need to calculated the current view matrix and the inverse matrix  of if.  For this goal we need to prepare some mathemtics function like , matrix inverse calculation, marix multiplication , matrix with vector multiplicaiton, vector product und dot vector product ... etc. When we sear in Internet there a lot of sources where we can find the informormation how to implement such mathematical tools. The first steps is to calculate the view matrix - e.g. some code:   ... function get_mat4x4_camera(eyepos,eyedir,eyeup) { // printVector(eyepos, "eyepos") // printVector(eyedir, "eyedir") // printVector(eyeup, "eyeup") var mat4x4 =[[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,0.0],[0.0,0.0,0.0,1.0]]; var i=0; var eyeZaxis = this.vec_normilize(eyedir); var eyeYaxis = this.vec_normilize(eyeup); var eyeXaxis = this.vec_normilize(this.vec_product(eyeYaxis,eyeZaxis)) for (i=0;i<3;i++) mat4x4[i][0] = eyeXaxis[i]; for (i=0;i<3;i++) mat4x4[i][1] = eyeYaxis[i]; for (i=0;i<3;i++) mat4x4[i][2] = eyeZaxis[i]; for (i=0;i<3;i++) mat4x4[i][3] = eyepos[i]; //for (i=0;i<3;i++) mat4x4[i][3] = 0.0-eyepos[i]; return mat4x4; //return this.transpondMat(mat4x4); } ////////////////////// vector with length =1.0 function vec_normilize(ary1) { ret=[]; var len=this.vec_len(ary1); for (var i = 0; i < ary1.length; i++) ret[i]=ary1[i]/len; return ret; }; //vector product range =3 function vec_product(a, b) { var vecprod =[0.0,0.0,0.0]; vecprod[0]=a[1]*b[2]- a[2]*b[1]; vecprod[1]=a[2]*b[0]- a[0]*b[2]; vecprod[2]=a[0]*b[1]- a[1]*b[0]; return vecprod; };   When we find programming code for mathematical operation we need to verify it by some examples where we know the results, because often there are some math sources which does not implement the correct solution. I think a good resource are e.g.: https://www.learnopencv.com/rotation-matrix-to-euler-angles/  https://www.learnopencv.com/ https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Matrix_math_for_the_web So that we do not need to re-invent the wheel, but we need to be careful to find the correct mathematical relations and to test and verify if they really work. Next step is to calculate the invert matrix of the view matrix.  A good implementation I found is this one:   function matrix_invert(M){ // I use Guassian Elimination to calculate the inverse: // (1) 'augment' the matrix (left) by the identity (on the right) // (2) Turn the matrix on the left into the identity by elemetry row ops // (3) The matrix on the right is the inverse (was the identity matrix) // There are 3 elemtary row ops: (I combine b and c in my code) // (a) Swap 2 rows // (b) Multiply a row by a scalar // (c) Add 2 rows //if the matrix isn't square: exit (error) if(M.length !== M[0].length){return;} //create the identity matrix (I), and a copy (C) of the original var i=0, ii=0, j=0, dim=M.length, e=0, t=0; var I = [], C = []; for(i=0; i<dim; i+=1){ // Create the row I[I.length]=[]; C[C.length]=[]; for(j=0; j<dim; j+=1){ //if we're on the diagonal, put a 1 (for identity) if(i==j){ I[i][j] = 1; } else{ I[i][j] = 0; } // Also, make the copy of the original C[i][j] = M[i][j]; } } // Perform elementary row operations for(i=0; i<dim; i+=1){ // get the element e on the diagonal e = C[i][i]; // if we have a 0 on the diagonal (we'll need to swap with a lower row) if(e==0){ //look through every row below the i'th row for(ii=i+1; ii<dim; ii+=1){ //if the ii'th row has a non-0 in the i'th col if(C[ii][i] != 0){ //it would make the diagonal have a non-0 so swap it for(j=0; j<dim; j++){ e = C[i][j]; //temp store i'th row C[i][j] = C[ii][j];//replace i'th row by ii'th C[ii][j] = e; //repace ii'th by temp e = I[i][j]; //temp store i'th row I[i][j] = I[ii][j];//replace i'th row by ii'th I[ii][j] = e; //repace ii'th by temp } //don't bother checking other rows since we've swapped break; } } //get the new diagonal e = C[i][i]; //if it's still 0, not invertable (error) if(e==0){return} } // Scale this row down by e (so we have a 1 on the diagonal) for(j=0; j<dim; j++){ C[i][j] = C[i][j]/e; //apply to original matrix I[i][j] = I[i][j]/e; //apply to identity } // Subtract this row (scaled appropriately for each row) from ALL of // the other rows so that there will be 0's in this column in the // rows above and below this one for(ii=0; ii<dim; ii++){ // Only apply to other rows (we want a 1 on the diagonal) if(ii==i){continue;} // We want to change this element to 0 e = C[ii][i]; // Subtract (the row above(or below) scaled by e) from (the // current row) but start at the i'th column and assume all the // stuff left of diagonal is 0 (which it should be if we made this // algorithm correctly) for(j=0; j<dim; j++){ C[ii][j] -= e*C[i][j]; //apply to original matrix I[ii][j] -= e*I[i][j]; //apply to identity } } } //we've done all operations, C should be the identity //matrix I should be the inverse: return I; }   Further we need to extract from the inverse matrix the Euler angels for rx , ry, and rz: //============================== function lcs2Euler( X1x, X1y, X1z, Y1x, Y1y, Y1z, Z1x, Z1y, Z1z) { var x=0; var y=0; var z=0; var sy = Math.sqrt(X1x * X1x + Y1x * Y1x); if (!sy < DBL_EPSILON) { x = Math.atan2( Z1y, Z1z); y = Math.atan2(-Z1x, sy); z = Math.atan2( Y1x, X1x); } else { x = Math.atan2(-Y1z, Y1y); y = Math.atan2(-Z1x, sy); z = 0; } //printVector ([pre,nut,rot],"lcs2Euler"); return [x,y,z]; } We already calucalted the rotation and now we need to calculate the x,y, z postion. This will be a point which is in front of use - along the gaze vector with particular distance and then x, and z corrinates of the view X and View Y vector: $scope.setWidgetProp( wdgName, 'rx', rad2deg(EulerAnglesInv[0]) ) $scope.setWidgetProp( wdgName, 'ry', rad2deg(EulerAnglesInv[1]) ) $scope.setWidgetProp( wdgName, 'rz', rad2deg(EulerAnglesInv[2]) ) var eye_dir_norm = vec_normilize($scope.eyedir) //projected to normal var eyeZaxis = eye_dir_norm; var eyeYaxis = vec_normilize($scope.eyeup); var eyeXaxis = neg_dir(vec_normilize(vec_product(eyeYaxis,eyeZaxis))) var newCalc = []; // here it will translate along the eye_dir and move in x and y axis for (var i=0; i<3; i++) newCalc[i]= $scope.eyepos[i] + disScale*eye_dir_norm[i] + Xcomp*eyeXaxis[i] + Ycomp*eyeYaxis[i]; //correction of the translation to the view plane in distnace of disScale $scope.setWidgetProp( wdgName, 'x', newCalc[0] ) $scope.setWidgetProp( wdgName, 'y', newCalc[1] ) $scope.setWidgetProp( wdgName, 'z', newCalc[2] )   So that now we can display the UI widgets with some calls like this: $scope.setWdgetPos('ShopingCard3DImage', 1.8, -0.25, 0.35) $scope.setWdgetPos('3DImage-1' , 1.6, 0.28, -0.1) $scope.setWdgetPos('3DImage-2' , 1.6, 0.28, 0.05) $scope.setWdgetPos('3DImage-3' , 1.6, 0.28, 0.3) $scope.setWdgetPos('3DButton-1' , 1.6, -0.25, -0.1) $scope.setWdgetPos('3DButton-2' , 1.6, -0.25, 0.0) $scope.setWdgetPos('3DButton-3' , 1.6, -0.25, 0.1) $scope.setWdgetPos('model-2' , 1.7, 0, 0.1 , 1) $scope.setWdgetPos('3DLabel-1' , 1.6, 0.25, 0.14)   In this article I provided a demo project which is attached to this article as zip file. I attached also the javascript math function which I used.    Where we have the widget name, distance along the gaze vector from the device and the X and Y position /X and Y view vectors /screen  To be able to get the device  gaze , up(y) and the x vector we can use the 'tracking' event:   //==================== $scope.eyeMat=[]; $scope.eyeInvMat=[]; //==================== $rootScope.$on('tracking', function( tracker,fargs ) { for(var i=0; i<fargs.position.length; i++) {$scope.eyepos[i] =fargs.position[i]; $scope.eyedir[i] =fargs.gaze[i]; $scope.eyeup [i] =fargs.up [i]; } $scope.eyeMat =get_mat4x4_camera(fargs.position,neg_dir(fargs.gaze),[0,1,0]); $scope.eyeInvMat = matrix_invert($scope.eyeMat) var EulerAngles =transfMat2Euler($scope.eyeMat); var EulerAnglesInv =transfMat2Euler($scope.eyeInvMat); $scope.$applyAsync(); //////////////////////// finished tml3dRenderer.setupTrackingEventsCommand })   The tracking callback function will save the current view vectors (gaze, up, postion) to a global variables which could be used later from the other functions. I created a demo project which is one possible example showing how we can implement such functionality. The sample project is for the HoloLens - I tested with on preview mode and on the  HoloLens 1 device and it was working fine. (- zipped project with password "PTC" - please, unzip it and import it to Studio) A note about the attached file: - the file project-"HoloLens3dFlexibleUI-article_ExampleProject.zip" should be unzipped to HoloLens3dFlexibleUI-article.zip - which is a project file for Vuforia Studio - demo project and could be imported in the Vuforia Studio UI. To unzip the project-example.zip you need a password simple: 'PTC ' - in capital characters -the file: myMathFunc.zip contains the used mathematical function definitions (zipped js file) . The javascript file is also contained by  the Studio project/ upload folder. When we test the project:     Where we see in front in the middle a cursor where we can tab or we can say show UI to display the UI:  
View full tip
Vuforia Studio New Duplicate action available for views in an experience Usability and UI improvements to the New Project window Improvements to Image Target widget source validation to help users upload images that will result in reliable targets Support for ThingWorx 9.4 Vuforia View Bounding box and location information can now be generated for any model at runtime (iOS and Android) As of March 2024, you will no longer be able to install Vuforia View on devices running iOS 14. Experience Service New Project Access screen allows administrators to disable publishing projects with public access in Vuforia Studio Note: If your Experience Service is hosted by PTC Cloud Services, open a Technical Support case requesting to update the configuration Bug Fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Vuforia Studio There were no new features or updates for the 9.17.0 version of Vuforia Studio Vuforia View HoloLens: Dynamic bounding box information is now available at runtime iOS: iOS/iPadOS 17 is now supported iOS/iPadOS 15 is no longer supported Experience Service Ability to disable publishing experiences for offline viewing Note: If your Experience Service is hosted by PTC Cloud Services, open a Technical Support case requesting to update the configuration Bug Fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Vuforia Studio 2D Rendering Updated from AngularJS to LitElement The 2D rendering in Vuforia Studio has been updated to use LitElement instead of AngularJS. Vuforia View RealWear RealWear has announced that RealWear HMT-1 devices are at end-of-life, and will no longer receive firmware or security updates beyond v12.6. As a result, we will be unable to fully support HMT-1 and HMT-1Z1 devices beginning in the upcoming 9.21.0 release. We encourage you to upgrade to RealWear’s Navigator series for continued device support from PTC. For more information, see RealWear’s RealWear HMT-1 and HMT-1Z1 End of Security Update support notice and Firmware Update and Support Policy. Bug Fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Vuforia Studio Changes to Check for Updates functionality—You will no longer be automatically prompted with the Update Available window when a new version of Vuforia Studio is available. Beginning in version 9.11.0, you must manually check for updates by navigating to the Vuforia Studio menu in the upper-right corner, and selecting Check for Updates. Once the Check for Updates window appears, compare Your version with the version that is displayed above the list of new features. For more information, see Update Vuforia Studio to the Latest Version. Windows OS: Vuforia Studio is now available for download from the Microsoft Store (The legacy installer is no longer available on the PTC Software Downloads page). A new app package (appxbundle) installer is now available on the PTC Software Downloads page for installing in a closed network environment. (The legacy restricted installer is no longer available on the PTC Software Downloads page). Mac: The Check for Updates action is now available from the Vuforia Studio menu in the upper-right corner. For more information, see Update Vuforia Studio to the Latest Version. Vuforia View ios: Quickly take sharper pictures—Users can now turn advanced camera controls on and off to using the new Turn on Tap to Focus action available from the experience menu. When Tap to Focus is turned off, the focus of interest is automatically selected by the device’s automatic focus areas and exposure setting. When Tap to Focus is turned on, the Vuforia View user can manually select the focus of interest by tapping on a specific area of the screen. Note: By default, Tap to focus is turned off. As of September 2023, Vuforia View will no longer be supported on the following devices. For more detailed information, see the What's New in the Help Center. Surface Pro 7 Surface Pro 6 Surface Pro 5th Gen (2017) Surface Pro 4 Surface Book Surface Go Surface Go2 Vuzix M400 Smart Glasses Experience Service: There are no new features or updates for the 9.11.0 version of the Experience Service. Bug fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Experience Service Added Entra ID Configuration Examples An Entra ID SSO configuration example was added to the Help Center. For more information, see Microsoft Entra ID Configuration Example in the Experience Service and Admin Help Center. Added Okta SSO Configuration Example An Okta SSO configuration example was added to the Help Center. For more information, see Okta Configuration Example in the Experience Service and Admin Help Center. Bug Fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Vuforia Studio Enhancements to userpick Event (iOS and Android only) The userpick event now contains geometric information that can be used to localize augmentations based on user interactions. For more information, see Geometric Information Mapping with the userpick Event. The response payload of the user pick event is added to the result “eventData” of the event listener $scope.$on(‘userpick’, function(event, targetName, targetType, eventData). Tracking Status API Now Available (iOS and Android only) Tracking status is now exposed via the Tracking API allowing you to build your own business logic linked to tracking status or tracking status changes. For more information, see Tracking Status API. Note: Tracking status is not available in preview. Multibyte Characters Now Fully Supported Multibyte characters are now supported in all of the following places: Display URLs Folder names Exported ZIP files The following enhancements were also made as part of this update: Experiences with only whitespace characters in the name will be renamed to untitled+<timestamp>. Whitespace characters at the very beginning or end of a project name will be removed. Project names must contain no more than 255 characters. Note: A known issue exists where renaming a project that has more than 255 characters results in a non-localized system message. Improvements to Model Rendering and Lighting Improvements were made to the rendering and lighting environment for 3D models in Vuforia Studio to be consistent with other PTC products such as Creo Parametric and Creo Illustrate. Modernized Architecture to Resolve AngularJS Vulnerabilities Modernized the architecture of the Vuforia Studio web editor to address and resolve AngularJS–related vulnerabilities. Note: Improvements to the runtime components for this issue remain in progress. ThingWorx 9.6 Now Supported ThingWorx 9.6 is now supported. Vuforia View Support for iOS/iPadOS 18.0 iOS/iPadOS 18.0 is now supported. Support for Android 15 Android 15 is now supported. Bug Fixes See Bug Fixes for additional information on bugs resolved in this release    
View full tip
The new 3D-Guided Service Instructions example use case walks you through creating a Vuforia Studio Experience that will allow a frontline worker to:  Find the physical location of a broken part on an object using a digital model  Search for parts on a 3D model of the object  Find and order replacement parts from a vendor using a persistent shopping cart   The 3D-Guided Service Instructions use case will walk you through the following sections: 3D-Guided Service Instructions 101: Use Attributes in Creo Illustrate  3D-Guided Service Instructions 201: Use JavaScript to Highlight Parts and Create Ionic Popups  3D-Guided Service Instructions 202: Use JavaScript to Find Parts  3D-Guided Service Instructions 301: Add Pricing Data and a Shopping Cart to a Model  3D-Guided Service Instructions 302: Add a Simple ThingWorx Service to Vuforia Studio  3D-Guided Service Instructions 303: Create a Persistent Shopping Cart Using ThingWorx
View full tip
Often, we need to display some sections, or we required to have a view of a x-section of the model. This is in generally no part of the current functionality but there are some approaches which could be helpful. In this article I want to mention 3 different approaches, which could be used but no one of them is really perfect:   1.) uploading different models -  so we can use an additional models for each cut and then we can change the model if you want to display a cut, it means you can make the one model not visible and the display the second model or vice versa.  I tested with cuts created in Creo Illustrate 5.0 and Creo View 5.0 but it seems that Vuforia Studio could not display them /neither as part of sequence or as static to the current figure:     The only possible  way in this example is to create in Creo an assembly cut /with option cut also on part level  and  then create from there a new .pvz model.  In this case this seems to work fine: :     2.) the second approach is to remove components  step  by step,  so to see the inner components when the outer components are blanked: All different components, which should be displayed or blanked, need to be defined as modelItem where we can set the visible property to true or false Is also possible to blank or display  a list of components where the list is defined in json file. This could be done with JavaScript code. In this case we do not need to define a modelItem widgets.  For more information you can check the post    3.)  The last most powerful option is to use a shader for the model Widget. So for example we can use some kind of clipping functionality of the model where we can set the x min and x max value or ymin and ymax or zmin and zmax value what should be displayed. This will create a clipping effect. So only the geometry which satisfy this criteria will be displayed.     How to achieve a clipping functionality using a shader. 3.1) define a shader - this requires creating a tmlText widget where we can define the shader Code. The code should be inserted into the text property of the tml widget For the clipping along x axis with planes which are parallel to the  YZ plain we need to define the following javascript with GLSL:   <script name="slice_world_based_x" type="x-shader/x-vertex"> attribute vec3 vertexPosition; attribute vec3 vertexNormal; varying vec3 N; varying vec4 vertexCoord; uniform mat4 modelMatrix; uniform mat4 modelViewProjectionMatrix; void main() { vec4 vp = vec4(vertexPosition, 1.0); gl_Position = modelViewProjectionMatrix * vp; vertexCoord = modelMatrix*vp; // the surface normal vector N = vec3(normalize(modelMatrix* vec4(vertexNormal,0.0))); } </script> <script name="slice_world_based_x" type="x-shader/x-fragment"> // this setting is needed for a certain use of properties precision mediump float; // determine varying parameters varying vec3 N; varying vec4 vertexCoord; // determine shader input parameters uniform vec4 surfaceColor; uniform float slicex; uniform float slicewidth; const vec3 lightPos = vec3(1.0, 2.2, 0.5); const vec4 ambientColor = vec4(0.3, 0.3, 0.3, 1.0); void main() { // calc the dot product and clamp based on light position // 0 -> 1 rather than -1 -> 1 // ensure everything is normalized vec3 lightDir = -(normalize(lightPos)); vec3 NN = normalize(N); // calculate the dot product of the light to the vertex normal float dProd = max(0.0, dot(NN, -lightDir)); // calculate current color of vertex, unless it is being clipped... // only geometry with coordinates which satisfy the condition below // will be displayed if ( vertexCoord.x > (slicex + slicewidth/2.0) || vertexCoord.x < (slicex - slicewidth/2.0) ) { discard; } else { // calculate the color based on light-source and shadows on model gl_FragColor = (ambientColor + vec4(dProd)) * surfaceColor; } } </script> Save the tml Text widget .     3.2) You can also define shaders for clipping along the Y and the Z axis. Here you can use the same shader javascript definition but you need to change the shader name and to modify the if  check respectively to the Y or Z coordinate:   <script name="slice_world_based_y" type="x-shader/x-vertex"> ... // calculate current color of vertex, unless it is being clipped... if ( vertexCoord.y > (slicex + slicewidth/2.0) || vertexCoord.y < (slicex - slicewidth/2.0) ) { discard; } else ...   To set the clipping values for different axes and to control it by   sliders we can use some code like this:   $scope.DIR="y"; $scope.slice = function() { var slicexCur = ($scope.view.wdg['slider-1']['value']/100.0)-0.5; var slicewidthCur = ($scope.view.wdg['slider-2']['value']/100.0); $scope.view.wdg['modelx']['shader'] = "slice_world_based_"+$scope.DIR+";slicex f "+ slicexCur + ";slicewidth f " + slicewidthCur; } //////////////////////////////////////////// $scope.$on('$ionicView.afterEnter', function(){ // Anything you can think of $scope.clickY() }); /////////////////////////////////////// $scope.clickX=function() { $scope.view.wdg['toggle-X']['value'] =true $scope.view.wdg['toggle-Y']['value'] =false $scope.view.wdg['toggle-Z']['value'] =false $scope.DIR="x" } $scope.clickY=function() { $scope.view.wdg['toggle-X']['value'] =false $scope.view.wdg['toggle-Y']['value'] =true $scope.view.wdg['toggle-Z']['value'] =false $scope.DIR="y" } $scope.clickZ=function() { $scope.view.wdg['toggle-X']['value'] =false $scope.view.wdg['toggle-Y']['value'] =false $scope.view.wdg['toggle-Z']['value'] =true $scope.DIR="z" } ///////////////////////////////////////   Here the slice() function is called in the slider change event (for the both slider widgets). For better understanding of the functionality you can review the attached Vuforia Studio project Here attached the improved version for HL. It is also approved by dev team.  slice_example.zip https://community.ptc.com/sejnu66972/attachments/sejnu66972/tkb_vuforiatechtips/48/4/slice_example.z... Another version (also for HL) attached here is the example   slice_example_using_ABCD  project – where the dev team demonstrates an efficient way showing how we can define a cutting plane via plane ABCD parameters (refer to  plane geometry equations : geometry https://en.wikipedia.org/wiki/Plane_(geometry)   To cover this functionality the dev team developed some studio extensions that  PTC customers can use instead.   That extensions widgets will handle reflections etc, and I it is recommend to use  those extensions .: https://github.com/steveghee/OCTO_Studio_extensions https://github.com/steveghee/OCTO_effects_extensions  
View full tip
Unfortunately, in the Vuforia Studio Documentation there is no complete List with the possible events which could be handled JS. Therefore for the first time this article tries to provide additional Information about known events :   1.) modelLoaded - is not required any more because the UI allow directly to specify this event. ... $rootScope.$on('modelLoaded', function() { //do some code here } ) .... 2.) Step completed example: scope.$on('stepcompleted', function(evt, arg1, arg2, arg3) { var parsedArg3 = JSON.parse(arg3); console.log("stepcompleted stepNumber="+parsedArg3.stepNumber + " nextStep="+parsedArg3.nextStep); $scope.app.stepNumber=parseInt(parsedArg3.stepNumber); $scope.app.nextStep=parseInt(parsedArg3.nextStep); $scope.app.duration=parseFloat(parsedArg3.duration); }); 3.) Event - stepstarted: ... $scope.$on('stepstarted', function(evt, arg1, arg2, arg3) { var parsedArg3 = JSON.parse(arg3); console.warn(arg3); console.log("stepstarted stepNumber="+parsedArg3.stepNumber); $scope.app.stepNumber=parseInt(parsedArg3.stepNumber); $scope.app.nextStep=parseInt(parsedArg3.nextStep); $scope.app.duration=parseFloat(parsedArg3.duration); }); ... Please, pay attention that on some platforms will not provide complete information  in stepstarted. So, In this case the complete info is available in 'stepcompleted' – the best is to test it.   4.) after entering in  a view in studio (e.g. Home ...):   ... $scope.$on('$ionicView.afterEnter', function() {$scope.populateModelList(); }); ... 5.) click/tap event on the current panel: ... $rootScope.$on('click', function() { tapCount++;console.log("click event called");} ); ... or  with coordinates ... document.addEventListener('click', function(event) {console.log("click() 1 called"); $scope.lastClick = { x: event.pageX, y: event.pageY}; }); ... you can also see this topic.   6.) New step  -example: ... $scope.$on('newStep', function(evt,arg) { var getStepRegex = /\((\d*)\//; console.log(arg); console.log( getStepRegex.exec(arg)[1]); //check what it prints to the console - the step number }); ...    7.) Here is also  a more advance construct- it defines a userpick event e.g. for all models widgets: angular.forEach($element.find('twx-dt-model'), function(value, key) { // search all twx-td-model's -> means all model widgets angular.element(value).scope().$on('userpick',function(event,target,parent,edata) { //for each model widget will set a userpick listener console.log('edata');console.warn(edata); console.log("JSON.parse(edata)");console.warn(JSON.parse(edata)); var pathid = JSON.parse(edata).occurrence; $scope.currentSelection = target + "-" + pathid; // this is the current selection - the selected component occurence // you can use it for example as shown below // try{ //tml3dRenderer.GetObject($scope.currentSelection).GetWidget().ApplyOccludeOpacity(OCLUDE_VAL,OPACITY_VAL); //} catch (e1234) {$scope.view.wdg['3DLabel-4']['text']= "e 1234exception in GetObject.GetWidget..."; } // } ) //end of the userpick defintion } ) //end of for each funciton  8.) tracking event:   ... $scope.$on('trackingacquired', function (evt,arg) { // alert('didStartTracking'); // this is not really needed $scope.message = parseInt($scope.app.params["currentStep"]); $scope.$apply(); }); $scope.$on('trackinglost', function (evt,arg) { // alert('didFinishTracking'); $scope.message = "Scan the ThingCode with your camera."; $scope.$apply(); }); ....   9.) popover event:     // var my_tmp = '<ion-popover-view><ion-header-bar> <h1 class="title">My Popover Title</h1> </ion-header-bar> <ion-content> My message here! </ion-content></ion-popoverview>'; $scope.popover= $ionicPopover.fromTemplate(my_tmp, { scope: $scope }); $ionicPopover.fromTemplateUrl('my-popover.html', { scope: $scope }).then(function(popover) { $scope.popover= popover; }); $scope.openPopover= function($event) { $scope.popover.show($event); }; $scope.closePopover= function() { $scope.popover.hide(); } //////////////destroy popover $scope.$on('$destroy', function() { $scope.popover.remove(); }); /////// hide popover $scope.$on('popover.hidden', function() { // your hide action.. }); // on remove popover $scope.$on('popover.removed', function() { // your remove action }); }); 10) watch event -watches are created using the $scope.$watch() function. When you register a watch you pass two functions as parameters to the $watch() function: 1)A value function 2)A listener function    When the value returned by function 1.) changes - this lead to execution of the funciton 2.) Example:   ... $scope.$watch(function(scope) { return $scope.view.wdg['label-1']['text'] }, // watches if change for the the text of label-1 //when changes then play a step for model-1 function() { console.log($scope.view.wdg["model-1"]); $scope.view.wdg["model-1"].svc.play; } ); ...   11.) Camera tracking - make sense only on mobile device- no sense for preview mode!   //// define tracingEvent only on end device tml3dRenderer.setupTrackingEventsCommand (function(target,eyepos,eyedir,eyeup) { // $scope.view.wdg['3DLabel-1']['text']="eyepos=("+eyepos[0].toFixed(2)+","+eyepos[1].toFixed(2)+","+eyepos[2].toFixed(2)+")"; $scope.app.params['target']=target; $scope.app.params['eyepos']="eyepos=("+eyepos[0].toFixed(2)+","+eyepos[1].toFixed(2)+","+eyepos[2].toFixed(2)+")"; $scope.app.params['eyedir']="eyedir=("+eyedir[0].toFixed(2)+","+eyedir[1].toFixed(2)+","+eyedir[2].toFixed(2)+")"; $scope.app.params['eyeup'] ="eyeup =("+ eyeup[0].toFixed(2)+","+ eyeup[1].toFixed(2)+","+ eyeup[2].toFixed(2)+")"; ///////////////////// },undefined); //// define tracingEvent only on end device } //end device   12.) There is also a sequenceloaded event, which is useful if you have a model with multiple sequences defined, and you are switching sequences dynamically in the experience.   $scope.$on("sequenceloaded", function (evt, arg) { console.log("sequence loaded, starting play"); $scope.setWidgetProp("loading","visible",false); $scope.app.fn.triggerWidgetService("model-1","playAll"); }); In this point is  here a good feedback comming from advance user (expert) : If you grep for "$emit" through a project folder, you can turn up the following event names: valueacquired (bar code scanner) usercanceled (bar code scanner) tracking modelloadfailed sequenceloaded newStep playstarted sequenceacknowledge playstopped sequencereset onReset If you grep for "$on(", you can find some additional ones: trackingacquired trackinglost modelLoaded click app-fn-navigate app-fn-show-modal app-fn-hide-modal $ionicView.afterEnter $stateChangeStart loaded3DObj loadedSeqErr loadedSeq $destroy select3DObj move3DObj loadError3DObj readyForZoom3DObj serviceinvoke stepstarted stepcompleted twx-entity twx-service-input twx-service-name This is a  good point and it seems that this list contains the most of the possible events.   Events Handling Feedbacks from EXTERNAL DATA  services  Such event is    the twx-service complete event. This event is called when we call a service registered in the external data and the service is completed. Here an example (also mention in the post😞 Here in the example in the external data the service LoadJSON was added.       ////////////////////////////////////////////////////////////// $scope.GetJsonFromTwxRepository = function(path) { $scope.$applyAsync(function() { $rootScope.$broadcast('app.mdl.CAD-Files-Repository.svc.LoadJSON', {"path":path} );} ,500 ); $scope.app.speak("after call of GetJsonFromTwxRepository") //in the modelloaded listener register // LoadJSON-complete event -> to laod the data into session rootScope.$on('modelLoaded', function() { //// $scope.$root.$on('LoadJSON-complete', function(event, args) { console.log("LoadJSON-complete event"); $scope.COMP_LOCs=args.data console.log(JSON.stringify( $scope.COMP_LOCs)) }); /// });   So the code above shows how to call from JavaScript the service added to the external data. This service should return the called JsonObject. The call is asynchronously so that when  thingworx  will come back the listener 'LoadJSON-complete' will be called and here will print the content of the JsonObject to the console. Here the listener is registered inside the modelload event (this is event is coming late – so to be on the save side that everything is already initialized) This is generally that you for any Thingworx services added to the External data <your_twx_service_name>-complete  the arg.data contains then the data which should be returned by the method.
View full tip
Vuforia Studio Support for sequences created with Creo Illustrate 8.0 Support for occlusion on Area Targets Improvements to 3D Panel widget: Ability to configure offset and snap distance Bug fixes and minor improvements Vuforia View Support for Windows Surface Go 2 Android: Support for Android 6 and 7 will be discontinued in July 2021 RealWear: Support for RealWear 11 will be discontinued in July 2021 Bug fixes and minor improvements Experience Service Support for ThingWorx 9.2 Support for RHEL 8.4 Support for Ubuntu 20.04 Support for PostgreSQL 13.3 Bug fixes and minor improvements
View full tip
Vuforia Studio ThingWorx 9.5 Support ThingWorx 9.5 is now supported in Vuforia Studio. New Observation for Stationary Objects Preset A new Observation for Stationary Objects preset is available for Advanced Views for objects that can be recognized from any angle when standing around the object, but not from below it. For more information, see Observation for Stationary Objects in the Vuforia Developer Library. Note: This new guide view replaces the 360 Dome guide view that was previously available. macOS Sonoma Support macOS Sonoma is now supported. Vuforia View RealWear HMT-1 Devices No Longer Supported Vuforia View is no longer supported on RealWear HMT-1 devices, as RealWear has announced that the HMT-1 devices are at end-of-life and will no longer receive firmware or security updates beyond v12.6. We encourage you to upgrade to RealWear’s Navigator series for continued device support from PTC. For more information, see RealWear’s RealWear HMT-1 and HMT-1Z1 End of Security Update support notice and Firmware Update and Support Policy. Bug Fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
To ensure your Chalk experience is the best, make sure to familiarize yourself with the below best practices.   Initialization Keep movement fluid and slow Forward and backward smooth motion is best to allow device to create mapping Small circles in front of the object are also good Note: Do not rotate your device - keep the device's orientation fixed, moving it parallel to the object of interest and keeping the latter in view during initialization movement Environment It is important for the environment to have a lot of saliency, interesting features, & textures e.g. Stickers, buttons, cables, images/designs, shapes with corners, etc Stationary objects are best for Chalking Reflective, plain colored, or blank surfaces are not good for using Chalk Marks Well-lit areas are best for Chalk performance If an environment is too dark the device's camera will not be able to detect objects External light may be needed if the environment is too dark Either user can toggle the flash on Network/Bandwidth Low bandwidth will result in poor video quality Ensure that you have good bandwidth Chalk Marks Use simple drawings to communicate instructions Circles, lines, & arrows work best Delete Chalk Marks that are no longer needed to reduce clutter Use the pause button to draw on a steady image  
View full tip
Vuforia Studio (Windows only) The ssl-settings.json file has been moved to the ProgramData directory for streamlined SCCM deployment. Note: This only applies to Vuforia Studio run over HTTPS. A new shortcut to configure HTTPS locally for Vuforia Studio is now available. For more information, see Vuforia Studio run over HTTPS. Vuforia View An updated version of Vuforia View was not released for 9.12.0. Experience Service There are no new features or updates for the 9.12.0 version of the Experience Service. Bug fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
As part of the Vuforia Studio 9.13.0 release, a new way to create and configure model targets is now available!    The updated Model Target widget allows users more configuration options within Vuforia Studio to ensure optimal tracking of their models. Advanced configuration options include:   Automatic coloring of Model Targets Simplification when model is too complex (Advanced Views only) Multiple Advanced Guide Views For additional information on these new options, see our Configure a Model Target Help Center topic.
View full tip
You can rename a project to avoid overwriting an existing published project with the same name on your Experience Service. To Rename your project, open the project you want to rename and click on the project name in the header bar; the field will become editable. For additional information, see Rename a Project  Here are a few things you need to consider when renaming a project: Renaming an already published project creates a duplicate of the project that is unpublished; it does not rename the already published project on the Experience Service To avoid having multiple copies of the same project on your Experience Service, unpublish the original project before renaming it and publishing it. Once you rename an already published project, and then publish the renamed project, a new QR code is created (different from the originally published project's QR code)
View full tip
With release 9.1.0, Vuforia Studio now supports Area Targets. Area Targets can be used when creating spatial instructions using the surroundings as interactive elements to be explored. For example, you can use an Area Target when you want to deliver augmentations to stationary objects in a scanned environment. You'll need to create an Area Target before you can import it into Vuforia Studio to leverage the Area Target widget. Below is an overview of the required steps to create and upload Area Targets for Vuforia Studio.   Step 1: Create a Vuforia Engine Developer Account   This account is separate from your regular PTC support account and is required to generate Area Targets.   Step 2: Download a Target Generator Once you've created a Developer account, you'll need to download a target generator. The target generator you download will depend on the device used to scan your environment.   Vuforia Studio currently supports scans created with: Matterport Pro2 Camera Requires the Area Target Generator desktop application. iOS devices with LiDAR sensors Requires the iOS app Vuforia Area Target Creator to scan and create Area Targets Step 3: Create an Area Target   Creating an Area Target using the Matterport Pro2 Camera:   Log into the Vuforia Area Target Generator with your Vuforia Developer Credentials Select New Area Target from Matterport Scan Enter your Matterport token information See Retrieving Models with the Matterport™ API Token for instructions on obtaining your token ID Enter the Scanned Space ID and Area Target Name The Scanned Space field is the Matterport™ SpaceID and a unique 11-digit ID that is associated with your individual scans. Find the unique ID of your scan by opening the scanned space from your Matterport™ account. Copy the entire URL, or just the SpaceID portion as illustrated and paste it into the Scanned Space  field. Area Target name must not contain any spaces Select Create Area Target to generate an Area Target of your scan. Full instructions for creating a scan and area target using the Matterport Pro2 Camera can be found here.   Creating an Area Target using the Vuforia Area Target Creator (requires internet connection): Login with your Vuforia Developer Credentials from step 1. Select the Plus Button to create a new scan and enter a scan name Start the scan Press the Stop Button to finish the scan Select the Legacy Dataset option, then select Generate to generate an Area Target database     Step 4: Prepare your files for Studio   NOTE: All filenames are case sensitive   Area Targets created with the Vuforia Area Target Generator: Navigate to the location you entered when creating your Area Target Location defaults to C:/Users/<username>/Documents/Vuforia Areas Create a zip file titled <target_name>.zip that contains ONLY: <target_name>.dat <target_name>.xml <target_name>_authoring.glb Area Targets created with the Vuforia Area Target Creator: Share your files to your Studio authoring machine Press the Container button and swipe one of the Area Target datasets listed to the left. A share icon will appear. Press the Share icon next to a listed dataset Select your transfer method It is possible to manually pull the files directly from your device. Using iTunes or a similar file explorer, navigate to the app's AreaTargetData folder and copy the desired Area Target directory.  Ensure that your <target_name>.zip file contains ONLY: <target_name>.dat <target_name>.xml <target_name>_authoring.glb Step 5: Upload your Area Target file to Vuforia Studio Add an Area Target widget your canvas Select the green plus button next to Data set  Browse to the location of your <target_name>.zip file and select open   See our Help Center for more information on Area Targets in Vuforia Studio.
View full tip
Vuforia Studio New and improved Model Target widget allows more advanced configurations of Model Targets  including: Automatic coloring of Model Targets Simplification when a model is too complex (for Advanced Views) Ability to create multiple Advanced Model Targets You can now use a command prompt shortcut to configure Vuforia Studio to run over HTTPS Vuforia View RealWear Navigator 520 devices are now supported Experience Service (On-premises) Access to Vuforia Cloud Services to generate Advanced Model Targets is now available for on-premises installations of the Experience Service. For more information, see Request Advanced Model Target Generation. For more information about installing and deploying an Experience Service on-premises, see the Experience Service Help Center. Bug fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Experience Service Added Entra ID Configuration Examples An Entra ID SSO configuration example was added to the Help Center. For more information, see Microsoft Entra ID Configuration Example in the Experience Service and Admin Help Center. Added Okta SSO Configuration Example An Okta SSO configuration example was added to the Help Center. For more information, see Okta Configuration Example in the Experience Service and Admin Help Center. Bug Fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Vuforia Studio Known Issue: Unable to Upload Files to Vuforia Studio in Chrome for Mac OS There is currently a known issue in Chrome for Mac where users are unable to upload files to Vuforia Studio when using Chrome 122.0.0.0 and 123.0.0.0. If you are using either of the aforementioned versions of Chrome for Mac, please update to Chrome 123.0.6312.10 to resolve the issue. According to Google, this issue should be resolved in Chrome 124.0.0.0. For more information, see Google’s IssueTracker. New Project Overwrite Message When Publishing A new message appears when a user publishes a project that has the same name as an existing published project on the same Experience Service. Project Name Can Now Be Updated from the Header Bar within a Project Users can now rename a project by clicking on the project name in the header bar from within a project. Image Targets Now Generated at Runtime Image Targets are now generated at runtime, and no longer at design time. Note: If you’re using Vuforia View 9.16.0 or above, all existing projects and new projects should work as expected as this change is backwards compatible. However, experiences that contain an Image Target and have been created with Vuforia Studio 9.19.0 and above will not work properly when consumed with Vuforia View 9.15.0 and below. Performance Improvement to Uploading a CAD Model .glb files no longer appear under Resources to help improve performance when uploading a CAD file. Bug Fixes See Bug Fixes for additional information on bugs resolved in this release
View full tip
Vuforia Studio Ability to Install Vuforia Studio for offline use (Windows) New Scaling Digital Twin Experiences use case focuses on: Digital twins Identity Resolution Service (IRS) Connecting an AR digital twin to ThingWorx Object configurations ThingWorx content storage New Static Object setting when configuring the detection position for a Model Target Bug fixes and minor improvements Vuforia View iOS/Android/Windows: Added support for Model Targets with a "static" motion hint When used with Car Mode, this combination provides enhanced tracking for larger objects with reflective surfaces iOS Support for iOS 15 HoloLens: Resolved issue with component placement in certain Creo Illustrate sequences Bug fixes and minor improvements Experience Service Bug fixes and minor improvements
View full tip
Announcements