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

Incorporate CAD Metadata Into an Experience ( version 8.5.13 and later)

No ratings

In Vuforia Studio version 8.5.13 a new metadata is intruduced. This will make the techniques described e.g. in the posts "How to extract the components with properties from a pvz file","Extracting the viewables and the seqnece steps information from a .pvz file for the usage in TWX" and "How to extract model data of 3d models in Vuforia Studio (without external Tools)?"  for the most cases not neccessarly any more. as In Vuforia Studio when a model is imported (add Resource) there is a new check button “Allow the Experience access to CAD metadata” :



The selection of this checkbox lead that when the model is loaded to the “app/resources/Uploaded” folder but also an a json object with the name <model name>.metadata.json
Example when we load the model “Coffee Maker Model_High.pvz” then we have also a json file named “Coffee Maker Model_High.metadata.json”. This JSON file contains the metadata to the coffee maker model



The metadata json file contains some different sections for each component /

  • For each component / CompPath Id  we have a sub object – comp obj


"/11":{"":{"Feature_Id":"11","Source_file_name": …

"/14":{"":{"Feature_Id":"14","Source_file_name": …

Where “/” means the root asm , “/11” and “/14” are components paths

  • The component object contains the following sections : general(empty string as key of the json obj) “”, "PROE Parameters" and "__PV_SystemProperties"

(see the attached example “Coffee Maker Model_High.metadata.json”)

The one possible approach could be , to use only this json object directly  but we can use also the PTC API which is provided starting with the Vuforia Studio 8.5.13

Metadata Access:

  • Read the json object into memory (javascript): 

In this case we can use the json object which was already created when the model data is omported in Studio.





var metaDataArray=[];
//========================== When Model Loaded Event
$rootScope.$on("modelLoaded", function() {
  if (arguments.length >0){ 
//================== if args >1 ======================
    var modelWidgetId=arguments[1]; 
    metaDataArray[modelWidgetId]={}; console.warn($scope.view.wdg);    
    let wdg= $scope.view.wdg[modelWidgetId];    
    let mdlsrc=$scope.getWidgetProp(modelWidgetId,'src');     console.log( "mdlsrc="+mdlSrc); 
    //==== extracts the model file name with extension
    let mdlNameExt= mdlSrc.replace(/^.*[\\\/]/, '');  console.log( "mdlNameExt="+mdlNameExt); 
    //==== extracts the model file name without extension
    var mdlName=mdlNameExt.replace(/\.[^/.]+$/, ""); console.log( "mdlName="+mdlName); 
   // ---adds the modelname to the array element for the widget
    // $https call of the JSON file form the UPLOAD folder
   $http.get('app/resources/Uploaded/' + metaDataArray[modelWidgetId]['mdlName']+'.metadata.json')
          .success(function(data, status, headers, config) {//-------- success fnc
 			angular.forEach(data , function(value ,key){ //-------- ForEach json loop
					});//--------end of ForEach json loop   
                        // print the data to the console
  		console.log("metaDataArray[]"); console.warn(metaDataArray);
														})//-------- end success fnic
  .error(function(data, status, headers, config) {console.log("problem in the http will create a new ");});    





 The code listed above will load the json file to the modelWidget/s (it will works also if we have many model widngets there - and each model widget ponts to model which is imported with metadata)

When we  test this code we can check the object in memory (console.warn() ) :



Now we can access the metadata using the normal JSON functionality - so we can   access the component data via the Comp Path Id / id paths - corresponds to the modelItem widget property occurrence:





$ function() {
 // visiting array with string index
    console.log(" model Widget = "+ key);
    let compList = metaDataArray[key]['CompIdList'];
    //select randomly from the coponent list 
    let randomNum= parseInt(Math.random()*metaDataArray[key]['CompIdList'].length)
    let randomComp= metaDataArray[key]['CompIdList'][randomNum];
    console.log("random component selected = " +randomComp);
   // let DispName = metadata.get(randomComp, 'Display Name')
    /*** you can use here one of the following   fields
    "Child Count","Component Name","Display Name","Model Extents (mm)","OL File Name","Part Depth""Part ID","Part ID Path","Part Name","Part Path"
    let DispName = metaDataArray[key]['data'][randomComp]['__PV_SystemProperties']['Display Name']
    console.log("DispName= "+ DispName)
    let model_extend_mm = metaDataArray[key]['data'][randomComp]['__PV_SystemProperties']['Model Extents (mm)']
     console.log("model_extend_mm= "+ model_extend_mm)
    let creaDate = metaDataArray[key]['data'][randomComp]['PROE Parameters']['CREATION_DATE']
     console.log("creaDate= "+ creaDate)
       console.log("model_extend_mm= "+ model_extend_mm)
    let designState = metaDataArray[key]['data'][randomComp]['PROE Parameters']['DESIGN_STATE']
     console.log(" designState= "+  designState)
     // make a selection string for this component
    let mdl_selection= key+"-"+randomComp;
    console.log ("mdl_selection="+mdl_selection)
    // generate some random rgbá color
    let r =parseInt(Math.random()*255);
    let g =parseInt(Math.random()*255);
    let b =parseInt(Math.random()*255);
    let a =parseInt(Math.random()*0.8)+0.2;
    //apply blink funciton for this component selection with random color





When we test the listed code above we will have in the chrome console window:


Using furhter the json  functionality we can also implement e.g. some user picks where you can associate it with the metadata :





angular.forEach($element.find('twx-dt-model'), function(value, key) {
   // find all model widget feature and perform funciton() 
   // for each model widget - key == modelWidgetId
//define the userpick function for each modelWidgetId 
angular.element(value).scope().$on('userpick',function(event,target,parent,edata) {
if (edata) {
    if ($scope.currentSelection) { // selection is not null make it undefined
       tml3dRenderer.setColor($scope.currentSelection, undefined);    }
    //create the selection string  <modelWidgetId>-<occurance Path Id>
    $scope.currentSelection = target + '-' + JSON.parse(edata).occurrence;
    //generate a random rgba color
        let r =parseInt(Math.random()*255);
    	let g =parseInt(Math.random()*255);
    	let b =parseInt(Math.random()*255);
    	let a =parseInt(Math.random()*0.8)+0.2;
    	//call blinkSelection function for the selected component
    //write the data SystemProperty of this compoonent in to a textArea Widget
     $scope.setWidgetProp('textArea-1','text',JSON.stringify( metaDataArray[target]['data'][JSON.parse(edata).occurrence]['__PV_SystemProperties']));
      }    })






This code will write the meta data to the selected component form the __PV_SystemPoperties section to a text area widget. Also the component will blink fwith random rgba color:


I attached an small example ( which should demonstrated the described techniques


  • Vuforia Studio metadata API

The first step is to call the metadata for a model widget. For this we can use the following construct e.g. WidgetId is ‘model-1’ :




(metadata) => {  
// <HERE  CALL YOUR CODE with metadata > 




So for example we can use get the “Display Name of the component with the path Id =’/0/6’:




PTC.Metadata.fromId('model-1').then( (metadata) => {  
Let disp_name= metadata.get('/0/6', 'Display Name');
console.log(“Display Name=”+disp_name);




The most of the  methods which could be applied to the metadata object and also some examples are described in the PTC Help (Incorporate CAD Metadata Into an Experience)

This functionality is available first with Vuforia Studio 8.5.13. To this article is also attached a PDF copy of the metioned link above.

There we can use 2 different approaches:

  1. To get a selected object or list of objects:
    let metaDATA=PTC.Metadata.fromId('model-1')
     metaDATA.then(function(meta) { console.log("success func of metaData");
     //a test with a fix model widget id  
        var designer = meta.get('/11','DESIGNER','PROE Parameters');
        console.log("Designer= " + designer);
        var ptc_mat = meta.get('/11','PTC_MATERIAL_NAME','PROE Parameters');
        console.log("PTC_MATERIAL_NAME= " + ptc_mat);
        var dispName = meta.get('/11','Display Name','__PV_SystemProperties');
        console.log("dispName= " + dispName);
        var DV_System_Categ= meta.get('/11'). getCategory ('__PV_SystemProperties')
        let myQuery=meta.find('Display Name').like('PRT').find('Part Depth').in(0,3);
        console.log("myQuery Name:"+myQuery._friendlyName);
         console.log("myQuery selected Paths :"+JSON.stringify(myQuery._selectedPaths));                          
        })  .catch(function(err) 
             {console.log("problem with the read of metadata ");console.warn(err);});  
  2. To call for the selected object a callback function where the Path id was passed as function argument:




$ function(){
let pathDepth=4
 PTC.Metadata.fromId( $
               {meta.find('Part Depth').lessThan(3).find('Display Name')

//========================== app.testCustomSelection
$ function(modelId,whereFunc,selectFunc,pathDepth) {
   var metaDATA= PTC.Metadata.fromId(modelId)
         .then(function(meta) {meta.findCustom(whereFunc,selectFunc);})
$ = function(idpath) {
      // scope var `this` is the metadata instance
      const depth = this.get(idpath, 'Part Depth')
      const name  = this.get(idpath, 'Display Name')
      return parseFloat(depth) > $ || 
                 (name &&'PRT') >= 0)
$ = function(idpath) {
   const name  = this.get(idpath, 'Display Name')
  console.log("app.selectFunc["+$"] idpath=" 
              +idpath+ " >>>Name: "+name);
  return this.get(idpath, 'Display Name');}





In the example above the query is done by the  where function and for all selected models the callback function select Func  is called where the pathId was passed to the function



I attached an small example ( which should demonstrated the described techniques

Version history
Revision #:
7 of 7
Last update:
‎10-19-2020 02:58 AM
Updated by:
Labels (2)