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

How to select model components in a 3d model without explicit definition of model Items?

No ratings

In Vuforia studio the best way to interact with 3d model components is to define explicit 3d modelitems (widget modelItem). So this will be an easy way to access the componets and to change their properties e.g. setting of the color 

e.g.: $scope.setWidgetProp("modelItem-1", "color",  "rgba(128,0,0,1)");

 

This will  change the modelItem-1 property color to brown – and will display the component which is specified by this modelItem with a  brown color.

Another way to do this in javaScript is something like :

 

$scope.view.wdg['modelItem-1']['color'] = "rgba(128,0,0, 1);";//brown
$scope.view.wdg['modelItem-1']['opacity'] = 0.5;//set transparency to 0.5
//or for the same 
$scope.setWidgetProp("modelItem-1", "color", "rgba(128,0,0,1);"); //brown
$scope.setWidgetProp("modelItem-1", "opacity", 0.5); //set transparency to 0.5

 

But in some cases during the project development it  could  be helpful when we are  able to manipulate the components or request information about them without defining of explicit modelItem widgets. For example if we want to select a component to see some information about the component and change the color of it:

 

var PICK_COLOR  = "rgba(255,0,0,1)";
...
$timeout( //timeout block 1
  function() { //timeout function 1
    angular.forEach( //==== for each 3d model block
                     // this will call the function below for each 3d model 
        $element.find('twx-dt-model'), function(value, key) { //for each 3d model block function
       //=====================================================================================
        angular.element(value).scope().$on('userpick',function(event,target,parent,edata) {
          // start the $on() listener 'userpick' + function definition
          //=================================================================================
          
          var pathid = JSON.parse(edata).occurrence;
	  $scope.currentSelection = target + "-" + pathid;  
          // create a component selection e.g. "model-1-/0/0/3/2"
          console.log("twx.app.isPreview() ="+twx.app.isPreview() );
          //print an info if is called in preview mode and could be checked if required
          
           try{tml3dRenderer.setColor($scope.currentSelection,   PICK_COLOR);}
           catch (ex) {console.warn("Exception 1 in tml3dRenderer.setColor()=>"+ex);}
           //will set the color of the selected component  
           } //end of mobile device
        modelItemsList.push($scope.currentSelection);
        } //end is in array
      
  
 //=================================================================================	
	 }); // finish the $on() listener 'userpick' + function definition
  }      //finish for each 3d model block function
    );   //  finish for each 3d model block
 //=================================================================================
 } ,50);   // finishtimeout block 1 and function

2018-11-06_13-12-34.jpg2018-11-06_13-13-25.jpg2018-11-06_13-12-46.jpg

 

If  we use  PICK_COLOR  = "rgba(255,0,0,0)";

It means that this color (red) is set for a selected component. Here the one additional detail is the last argument - which have a value of 0. Means alpha channel =0 - or full transparence. On the most mobile devices it will hide the selected component, but this is not supported techniques and we have to use always color with alpha channel >0. / transparent but still visible/

 

Calling of the tml3dRenderer.setColor(…, undefined); will set the component color back to default - example:

 

tml3dRenderer.setColor(‘model-1-/0/0/3/2’, undefined);

 

 Another important point is that when we know the model name and know the component ids, in this case we can also set the color or hide components without explicit definition of model items.

For example for a particular model we have prepared  a json file (*):

 

 

{	"/0/0/2"  :"rgba(255,0,0,1);",
        "/0/0/0"  :"rgba(128,0,0,1);",
	"/0/0/5"  :"rgba(128,0,128,1);", 
	"/0/0/3/0":"rgba(0,255,0,1);", 
	"/0/0/6"  :"rgba(255,200,0,1);", 
	"/0/0/3/1":"rgba(0,0,0,0.2);",
	"/0/0/7/0":"rgba(0,0,0,0.2);", 
	"/0/0/7/1":"rgba(0,0,0,0.2);" 
 }

 

The model to which this json file was created is placed in Vuforia Studio as model widget with name=model-1 

We can then read this json file (from prject->src\phone\resource\Uploaded folder) with some javaScript construct like (below) and set the color property of the components (also change the transparence - for the components with alpha channel =0.2) 

Here an example (*):

 

//========================================================
// reading a json file with component setting for the components
//========================================================

$scope.setCompProps=function() {
var FILES_MODEL_COMP = {
  'model-1':'comp_info.json'
};

$scope.compJSON_Data = new Array();

angular.forEach(FILES_MODEL_COMP, function(jsonFile, target) { console.log("angular.forEach jsonFile = "+jsonFile + ", target="+target);
  $http.get('app/resources/Uploaded/' + jsonFile).success(function(data, status, headers, config) {
    $scope.compJSON_Data[target]=data;
// in this case is $scope.compJSON_Data['model-1']= of the json structure file here the content'comp_info.json';

 angular.forEach(data , function(color, path_id){
console.log("target="+target+" --> color = "+color + ",path_id="+path_id);
tml3dRenderer.setColor(target+'-'+path_id, color);
   
});//end for each function

  })
  .error(function(data, status, headers, config) {console.log("calling in foreach 1 failed");
  });
});
};

 

 

So when we start for this particular model the test code it will change the display of the model according to the setting of the comp_info.json  file:

 

2018-11-06_14-36-52.jpg

2018-11-06_14-14-34.jpg

 

The code above is more than intended for setting colors and transparency  . According a recommendation from development for hiding of components is better to use  the hidden property:

 

tml3dRenderer.setProperties($scope.currentSelection, { hidden:true } );

 

The sample  code below  ( more simplified) is  for the case that we want to blank a component by click on it:

 

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 
     try{
      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;
     console.log("=>>"+$scope.currentSelection);
     } catch (ea) {console.error("not twx-model is clicked but still fired")}
 try{ 
    // here below the change recommended from R&D
     tml3dRenderer.setProperties($scope.currentSelection, { hidden:true } ); 
 
} catch (e1234) {console.error( "e="+e1234); }

 

Here tested the code on the HoloLens 1.0 device:

 

2019-05-23_11-35-29.jpg

 

When we have a color definiton  with  opacity -> the alpha channel set here e.g. to 0.1 /  and the defined color should be changed later :

 

var PICK_COLOR_OPACITY1 = "rgba(,,,0.1)";

 

to change the rgba expression by setting another value of transparency you can use some construct like this:

 

var PICK_COLOR_OPACITY1  = "rgba(,,,0.1)";
var OPACITY_VAL=0.3;
var PICK_COLOR_OPACITY2= PICK_COLOR_OPACITY1.replace( "0.1)",OPACITY_VAL+")");

 

The JavaScript code above  will set transperancy value of  0.3 (replacing the 0.1 by 0.3)

But for the case that we have in a json file a defintion of color with alpha chanel =0  :

 

 

...
"/0/0/3/1":"rgba(0,0,0,0.0);",
...

 

In this case we can  modify (recommended)  the code to check the value of the alpha channel and if it is ==0 to set  the "hidden" property  - example (*) :

 

...
//========================================================
// reading a json file with component setting for the components
//========================================================

$scope.setCompProps=function() {
var FILES_MODEL_COMP = {
'model-1':'comp_info.json'
};

$scope.compJSON_Data = new Array();

angular.forEach(FILES_MODEL_COMP, function(jsonFile, target) { console.log("angular.forEach jsonFile = "+jsonFile + ", target="+target);
$http.get('app/resources/Uploaded/' + jsonFile).success(function(data, status, headers, config) {
$scope.compJSON_Data[target]=data;
// in this case is $scope.compJSON_Data['model-1']= of the json structure file here the content'comp_info.json';
//because R&D statement to use hidde property need to check of alpha chanel ==0
angular.forEach(data , function(color, path_id){
console.log("target="+target+" --> color = "+color + ",path_id="+path_id);
var start_alpha = color.lastIndexOf(",");
var end_alpha = color.lastIndexOf(")");
var alpha_str = color.substring(start_alpha+1, end_alpha);
var num = Number(alpha_str);
if ( (isNaN(num )) || (num <= 0.0) )
{//set color properly to alpha channel 1.0
var new_color= color.substring(0,start_alpha+1)+"1.0"+ color.substring(end_alpha,color.length)
tml3dRenderer.setColor(target+'-'+path_id, new_color);
tml3dRenderer.setProperties(target+'-'+path_id, { hidden:true } );
}
else
{
// color unchanged
tml3dRenderer.setColor(target+'-'+path_id, color);
}
});//end for each function
})
.error(function(data, status, headers, config) {console.log("calling in foreach 1 failed");
});
});
};
/////////////
...

 

The example above will set to the component the correct values of the color but with alpha channel 1.0 and will interpret the original alpha value from the file as setting of the hidden property to true.  Does this make sense? Yes if we later set the hidden property to false then the color setting will be applied according to the definition from  the json file

Version history
Revision #:
7 of 7
Last update:
‎06-30-2019 08:49 PM
Updated by:
 
Labels (1)
Contributors
Comments

Hi @RolandRaytchev 

 

This is awesome. I don't think I understand everything you're doing, but I get the idea. It's very involved.

 

I'm trying to do something similar (below). What do you think of this?

I wrote some Python code to turn an arbitrarily long list of component IDs ("0/0/2/0","0/0/2/1", etc) into a string with the correct syntax for me to paste it into the Home.json file to create a bunch of model items. After working out a few glitches (such as extra commas) I got it working, so that it actually creates about 25 model items and applies things like unique click expressions & color to them. However, here's the issue I have: If I enter the coordinates as x,y,z & rx,ry,rz as all = 0, it overrides their correct positions. They end up in all sorts of wrong orientations. I tried it again without listing these parameters at all, and the orientations of the model items were even worse.

 

Somehow when a model-item widget is created in Vuforia Studio the normal way (click and drag, or entering the component ID) Vuforia Studio displays the x,y,z coordinates all as 0's, but the actual Home.json file is populated with coordinates extracted from the PVZ file. If I could get these coordinates somehow, I could insert them into the string before pasting it into the Home.json. I just can't figure out how. I know Creo Illustrate lists a bunch of parameters when you highlight parts, but coordinates are not included. I haven't had any success "decoding" pvz files either. Searching for this is how I came across this tip you shared.

 

What do you think might work for this?

 

It's super cool when I can create 25+ model items very quickly and accurately, all with colors and unique click expressions like app.displayInfo("0/0/0/2"); This allows me to use a function "displayinfo" to update 3D labels with parameters associated with "0/0/0/2" such as part description & part number. But it's not going to work if the exploded view of the product, and the animations, all show components in the wrong positions & orientations.

 

This is the view from the Vuforia Studio editor: (model items are all in position 0,0,0 which is incorrect)

clipboard_image_0.png

The Preview window shows the wrong positions as well -- until the "explode.pvi" animation starts. However on the HoloLens the positions and orientations are wrong even after the animation. This is because the HoloLens animation moves each component relative to its original position & orientation (which are wrong), instead of in reference to a global coordinate system.

clipboard_image_1.png