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

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

Extracting the viewables and the seqnece steps information from a .pvz file for the usage in TWX

RolandRaytchev
21-Topaz I

Extracting the viewables and the seqnece steps information from a .pvz file for the usage in TWX

This post should provide more detailed steps additional to the posts ("How to extract the components with properties from a pvz file"[1.] and "How to use ThingView Widget from Navigate to display CAD Model/Viewables in custom mashup- Concept"[2]) for the extracting the viewables and the seqnece steps information from a .pvz / Creo Illustrate model for further usage in a thingworx service.

1.) Extracting the data from the Creo View Model ( Created from Creo Illustrate via publish to pvz functionality)

As described in [1.] we required for the extraction of information a Creo View Toolkit.  A good choice will be the usage the Creo View  WebGL toolkit module.  

The toolkit program is called inside a html document where the javaScript Creo View WebGl Api is embedded. So, the most important logic could be called on the window load function. This code below will initialize  the thingview library and  will open the pvz model file (value of variable CUR_MODELPATH in the code below  is set the complete model path)

...  
window.onload = function() { ThingView.init("js/ptc/thingview", function() { // ThingView should only be initialised once per frame //---------------------------------- //send the modelname to server var xhr = new XMLHttpRequest(); xhr.open("POST", "RAY_LOG_FILE:", true); xhr.setRequestHeader("Content-Type", "application/json"); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { var json = JSON.parse(xhr.responseText); } }; //set the json modelname object var JSON_BOM_MODEL_OBJ = new Object; MODELNAME = CUR_MODELPATH.substring(CUR_MODELPATH.lastIndexOf("/") + 1) JSON_BOM_MODEL_OBJ.name = "BOMMODELNAME"; JSON_BOM_MODEL_OBJ.value = MODELNAME; xhr.send(JSON.stringify(JSON_BOM_MODEL_OBJ)) console.warn("sent BOMMODELNAME=" + MODELNAME) //finish the sending of the model_name //---------------------------------- console.log("Creo View WebGL Viewer is now initialised"); session = ThingView.CreateSession("CreoViewWebGLDiv"); //refers to the CreoViewWebGLDiv -> a div area in the html fileSource // which contains the code var xhttp = new XMLHttpRequest(); MODELNAME = CUR_MODELPATH.substring(CUR_MODELPATH.lastIndexOf("/") + 1) xhttp.open("POST", "RAY_JSON_VIEWABLE:", true); xhttp.setRequestHeader("Content-Type", "application/json"); xhttp.onreadystatechange = function() { if (xhttp.readyState === 4 && xhttp.status === 200) { var json = JSON.parse(xhttp.responseText); } }; var js_obj = new Object; js_obj.name = "VIEWABLE"; js_obj.value = MODELNAME; var data = JSON.stringify(js_obj); xhttp.send(data); model = session.MakeModel(); ////==================LoadFromURL Callback model.LoadFromURLWithCallback(CUR_MODELPATH, true, true, false, function(success, isStructure, errorStack) { var illustrations = model.GetIllustrations(); for (var i = 0; i < illustrations.size(); i++) { console.log("Illistration name: " + illustrations.get(i).name); // seems illustrations.get(i).name == pviFile model.LoadIllustrationWithCallback(illustrations.get(i).name, function(success, pviFile, stepInfoVec) { if (success === true) { var hasAnimation = model.HasAnimation() var hasSequence = model.HasSequence() xhttp.open("POST", "RAY_JSON_VIEWABLE:", true); xhttp.setRequestHeader("Content-Type", "application/json"); xhttp.onreadystatechange = function() { if (xhttp.readyState === 4 && xhttp.status === 200) { var json = JSON.parse(xhttp.responseText); } }; var js_obj = new Object; js_obj.name = pviFile; js_obj.value = pviFile; js_obj.type = "viewable"; js_obj.hasSequence = hasSequence; js_obj.hasAnimation = hasAnimation; var data = JSON.stringify(js_obj); xhttp.send(data); for (var ii = 0; ii < stepInfoVec.size(); ++ii) { xhttp.open("POST", "RAY_JSON_VIEWABLE_STEP:", true); xhttp.setRequestHeader("Content-Type", "application/json"); xhttp.onreadystatechange = function() { if (xhttp.readyState === 4 && xhttp.status === 200) { var json = JSON.parse(xhttp.responseText); } }; var step_obj = new Object; console.log("step nr=" + ii); step_obj.viewablename = pviFile; step_obj.nr = ii; step_obj.name = stepInfoVec.get(ii).name; step_obj.description = stepInfoVec.get(ii).description; var data = JSON.stringify(step_obj); xhttp.send(data); //============================================= } } }) } ////============= setTimeout(function() { { xhttp.open("POST", "RAY_JSON_VIEWABLE:", true); xhttp.setRequestHeader("Content-Type", "application/json"); xhttp.onreadystatechange = function() { if (xhttp.readyState === 4 && xhttp.status === 200) { var json = JSON.parse(xhttp.responseText); } }; var js_obj = new Object; js_obj.name = "FINISHVIEWABLES"; var data = JSON.stringify(js_obj); xhttp.send(data); } }, 10000); }); ///model load from URL funciton ///////////// }); // ThingView.init( ) }; //window onload function

The program will generate 2 different json file and will send them to the http server.

When the Creo View WegGl program is started (load  the html file from the http server)  - So on the server side - in the node.js console  we can see the printing of the received data - example on the picture below:

 

2019-02-05_14-30-08.gif

The Creo View WebGl program will create on the server side  2 json files (this requires also handling of the received  data on the server side as allready mention in the post [1.]  )

Example for extracting of data : worldcar-brake-multi-figure.pvz

worldcar-brake-multi-figure.pvz-viewableSteplist.json

[{"viewablename":"Sequence","nr":0,"name":"Sequence","description":""},
{"viewablename":"Sequence","nr":1,"name":"Step 1","description":"Remove spring clips"},
{"viewablename":"Sequence","nr":2,"name":"Step 2","description":"Release 4 bolts"},
{"viewablename":"Sequence","nr":3,"name":"Step 3","description":"Pull apart the calipers"}]

worldcar-brake-multi-figure.pvz-viewablelist.json

[{"name":"Figure 1","value":"Figure 1","type":"viewable","hasSequence":false,"hasAnimation":false},
{"name":"Sequence","value":"Sequence","type":"viewable","hasSequence":true,"hasAnimation":false},
{"name":"Parts List","value":"Parts List","type":"viewable","hasSequence":false,"hasAnimation":false},
{"name":"Sectioning","value":"Sectioning","type":"viewable","hasSequence":false,"hasAnimation":false},
{"name":"Translation","value":"Translation","type":"viewable","hasSequence":false,"hasAnimation":false},
{"name":"Animation","value":"Animation","type":"viewable","hasSequence":false,"hasAnimation":true}]

 

2.) Definition of a service in Thingworx for the Sequence Step List (see also "Service for creating of Bom - and Viewable Lists from json files [3]  )   

Here the first Step is to define a general service which will will convert the JSON file to an InfoTable using particular dataShape.  The json file will be taken from a Repositroy  repository

var params = {
	path: the_json_path /* STRING */
};
var Content = Things[the_Repository_Name].LoadJSON(params);
var params1 = {
infoTableName: undefined /* STRING */,
dataShapeName:  the_dataShape_name /* DATASHAPENAME */
};

// result: INFOTABLE
var jsonTable = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape(params1);
var result = DataShapes.ThingviewBomData.CreateValues();

for(i in Content.array){
    jsonTable.AddRow(Content.array[i]);
}
result = jsonTable; //returns the InfoTable

 

The service has 3 Input parameters : the_json_path, the_dataShape_name and the_Repository_Name (all are String type)

 

2019-02-06_10-50-28.gif

 

so this service could be called for any file repository, containing any json files(it is not file specific) . Via the dataShape name we will specify the filed definitions.  We need to do this  for each specific json file. In this case we have first manually to  create a DataShape which is compatible to the Json Object.  For example when we start the service RayJsonToInfoTable:

 

2019-02-06_11-05-46.gif

And the dataShape what we need to define in this particular example:

2019-02-06_16-40-26.gif

For the achieving  of the final goal -> the creation of the  Sequence Step List. We need to create a  another service where we can specify the arguments for DataShape and  repository name. Example:

2019-02-06_16-52-34.gif

 

So the input argumets are:  1.) the path to the json file and 2.) the name of the sequence for which we want to see the steps.  

 

I am not sure if we can omit the step , where we create a  dataShape for specific json - so some kind of  dynamic dataShape generation - because in such case  we need only to specify the json file without manual editing opreration.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions

In the mean time , I found a solution  how to read a JSON file  and to convert it to a INFO table without explicit DataShape defintion. The service definition is similar to the described service in the post.

2019-02-06_17-15-10.gif

This service has to input arguments 1.) for the JSON file path (the location of the repository where it is saved) and 2.) for the repository name - so means we can call from any repository. The output is an INFOTable but without a DataShape defintion.

The clue in here is to define the dataShape dynamicaly when we read the json File. 

So the converting process is implmented in 2 loops 

->>one loop for the dataShape defintion and the second loop for the reading of the different rows. Here the JavaScript code:

//var my_data_shape= "fields_dataShape";
var params = {
	path:the_json_path  /* STRING */
};

//create an json Object array
var ContentJSON = Things[the_repository].LoadJSON(params);
//get the first row for the dataShape defintion
var FirstRowJson  =ContentJSON.array[0];
//create an empty InfoTable
var resInfoTable = { dataShape: { fieldDefinitions : {} }, rows: [] };
//defines the dataShape
for(var prop in FirstRowJson)
{
    if(FirstRowJson.hasOwnProperty(prop))
    {  
      resInfoTable.dataShape.fieldDefinitions[prop] = { name:prop, baseType: 'STRING' };
    }  
}
//add the rows to the InfoTables
for(i in ContentJSON.array){
    resInfoTable.rows[i]=ContentJSON.array[i];
}
result = resInfoTable;
 

And here an example for the results of the service call:

2019-02-06_17-29-01.gif

 

View solution in original post

1 REPLY 1

In the mean time , I found a solution  how to read a JSON file  and to convert it to a INFO table without explicit DataShape defintion. The service definition is similar to the described service in the post.

2019-02-06_17-15-10.gif

This service has to input arguments 1.) for the JSON file path (the location of the repository where it is saved) and 2.) for the repository name - so means we can call from any repository. The output is an INFOTable but without a DataShape defintion.

The clue in here is to define the dataShape dynamicaly when we read the json File. 

So the converting process is implmented in 2 loops 

->>one loop for the dataShape defintion and the second loop for the reading of the different rows. Here the JavaScript code:

//var my_data_shape= "fields_dataShape";
var params = {
	path:the_json_path  /* STRING */
};

//create an json Object array
var ContentJSON = Things[the_repository].LoadJSON(params);
//get the first row for the dataShape defintion
var FirstRowJson  =ContentJSON.array[0];
//create an empty InfoTable
var resInfoTable = { dataShape: { fieldDefinitions : {} }, rows: [] };
//defines the dataShape
for(var prop in FirstRowJson)
{
    if(FirstRowJson.hasOwnProperty(prop))
    {  
      resInfoTable.dataShape.fieldDefinitions[prop] = { name:prop, baseType: 'STRING' };
    }  
}
//add the rows to the InfoTables
for(i in ContentJSON.array){
    resInfoTable.rows[i]=ContentJSON.array[i];
}
result = resInfoTable;
 

And here an example for the results of the service call:

2019-02-06_17-29-01.gif

 

Top Tags