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

Community Tip - Stay updated on what is happening on the PTC Community by subscribing to PTC Community Announcements. X

Is there a way to load 3D model from Thingworx repository to Experience dynamically ?

Jamal8548
12-Amethyst

Is there a way to load 3D model from Thingworx repository to Experience dynamically ?

The scenario is that we are thinking to get the 3d models from windchill to thingworx and then to vuforia studio.

What can be the best scenario?
1) Integration of thingworx with windchill (any documentation)

Or 

2) We upload the 3d models in thingworx repositry and fetch them in vuforia studio? if possible is there more information about the process?

6 REPLIES 6

Hi @Jamal8548 ,

for the point 1.) data migration from  Windchill to Thingworx repository , please, contact the Windchill Customization Visualisation group/ believe configuration the worker to export data  which could be imported later - or /possibly the bether option/ you can check the Thingworx naviage so you can post your quesiton  in the Thingworx developement communty - Thingworx Navigate communty https://community.ptc.com/t5/ThingWorx-Navigate/bd-p/thingworxnavigate . So far I have informaiton from the Navigate team  there are some kind of connectors which coould be customized to different tasks and possibly this could be hepful for you to manage this task. Please, address the quesiton 1.) there . Thanks

 

to point 2)  - let say you have all data already uploaded to a folder into a think which is created from FileRepository template. In this case you can use the LoadBinary service  to start  downlaod and then to received the model in the LoadBinary-complete event some think like that:

//---loading the model
$scope.app.LoadModel = function(widgetName,path ) {
 console.warn("$scope.app.LoadModel(",widgetName,",src,",path,")")
  $scope.wdgName=widgetName 
  $scope.serviceName='LoadBinary'
  $scope.repositoryThing='CADRepository1_test'
  var parameters   =  {"path":path}  ;  console.warn(parameters)
 
  twx.app.fn.triggerDataService($scope.repositoryThing,$scope.serviceName,JSON.parse(JSON.stringify( parameters)));
  $scope.$applyAsync();                
  console.log("after callLoadBinaryContent wdgName:"+$scope.wdgName)
};


//========== the LoadBinary-complete event
$scope.$root.$on('LoadBinary-complete', function(event, args) { 
  console.log("LoadBinary-complete event");console.log("name="+event.name)
  console.warn(args.data[0].Content)
  $scope.$applyAsync(); 
 
 $timeout((data)=>{
 
 $scope.setWidgetProp( $scope.wdgName,'src',data );  
 $scope.$applyAsync();  
  },500,true,  args.data[0].Content)  
});

So in the example it will set the received data to the src of a model widgit (name of the widgit is in the variable $scope.wdgName. So to work that you need to add the Thingrepository to the external data /here CADRepository1_test and the service LoadBinary 

Also all data and services which should be accessed in Vuforia Studio should be conigured according the Studio help:

https://support.ptc.com/help/vuforia/studio/en/#page/Studio_Help_Center%2FAnonymousAccess.html%23

https://support.ptc.com/help/vuforia/studio/en/#page/Studio_Help_Center%2FGrantUserPermissions.html

 

Thank you @RolandRaytchev for always supporting the community.  you are passing data in the timeout function but the data itself is deriving from args. can you please see now i am taking the data and i mean content below and assigning it to model.

 

$scope.$root.$on('LoadBinary-complete', function(event, args) { 
  console.log("LoadBinary-complete event");console.log("name="+event.name)
  console.warn(args.data[0].Content)
  $scope.$applyAsync(); 
 
  let a =args.data[0].Content
  
  
 $timeout((a)=>{
 console.log("yes",a);
 $scope.setWidgetProp( $scope.wdgName,'src',a );  
 $scope.$applyAsync();  
  },500,true,  args.data[0].Content)  
});

 

 

 

service response below

Jamal8548_0-1721222461134.png

 

error for now

Jamal8548_1-1721222505288.png

 

this is pvz file which i am taking from thingworx repositry and setting it to the model.

Hi @Jamal8548 ,

so far it should work but it seems that it has an issue to get the whole data at one piece ... not sure, at all. The data is printing OK and I remember that was working in the past.

So possibly with small pvz that will work , e.g. some cube  pvz with small size to see if that issue is still there.

I looked in some of my projects and see that I was also faced with this issue in the one of the 9.15+ version and used a different approuch  which  was working on mobile... some code like that:

 

//===========================================================
// Event : LoadBinary-complete 
//===========================================================
$scope.$root.$on('LoadBinary-complete', function(event, args) { 
  console.log("LoadBinary-complete event");console.log("name="+event.name)
  console.warn(args.data[0].Content)

 const dataURI=  ('data:image/pvz;base64,'+args.data[0].Content).replace(/\n/g, '').trim(); 
   const  blob = dataURItoBlob(dataURI);//----  //possibly this blob get the whole object from server and not only part of it!!!
  //because otherwise it does not make any sense but without this it did not work at all
  console.warn("blob = ");console.warn(blob)
const objectURL = URL.createObjectURL(blob); 
  
  $scope.setWidgetProp( 'textArea-1','text',JSON.stringify(objectURL).slice(0,100) );  
  $scope.$applyAsync(); 
  //https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/srcObject
  
 $timeout((data)=>{
 
 $scope.setWidgetProp( $scope.wdgName,'src',data );  
 //$scope.setWidgetProp( $scope.wdgName,'scale',$scope.app.curr_scale );  
   $scope.app.params.scale=$scope.app.curr_scale
    
   for(let i=0; i<11;i++)  $timeout(()=>{$scope.$applyAsync(); },50*i);
 },500,true,'data&colon;image/pvz;base64,'+ args.data[0].Content)  
 
});
//-----------------------------------------------------
$scope.app.LadeModelTest=()=>{
console.log("only print for the LadeModelTest to see that it was called");
//$scope.app.LadeModel('model-1','/CAD/Engine_Low.pvz')
 // $scope.app.LadeModel('model-1','/pvz/mill5MT_High.pvz')	
  $scope.app.LadeModel('model-1',$scope.app.randomMod())
};

 

code is not really a good programming style example ... but tested in the 9.21 with project and it worked - tested now in preview - is ok. So far I see your issue is in preview - so frist there to check. I will attach a demo project 

2024-07-25_11-28-26.jpg

To get the project working without many changes you need to have a repostitory thing with the name

const TWXmodelID = 'CADRepository1_test'

or you have to change the code line 6 on Home.js to the name of the repository what you use

Also you have to load some files into a folder of your repository . Add that information in the Lines 37-45

 

 $scope.app.ListeMods=[
      {'name':'3dgauge1','pvz':'/pvz/3dgauge1.pvz','scale':3},
      {'name':'bla-bla','pvz':'/pvz/bla-bla.pvz','scale':3},
      {'name':'engine_test_exp','pvz':'/pvz/engine_test_exp.pvz','scale':0.5},
      {'name':'mill5MT_High','pvz':'/pvz/mill5MT_High.pvz','scale':1},
      {'name':'navipad','pvz':'/pvz/navipad.pvz','scale':2},
      {'name':'ventil_bg_anno','pvz':'/pvz/ventil_bg_anno.pvz','scale':3},
      {'name':'wandregal','pvz':'/pvz/wandregal.pvz','scale':0.5}
 ]

 

here you should provide information abouth the name, pvz filename and Studio display scale... so means you can change that informaiton according to the used repository folder and data what is loaded there.

Also you need to add LoadBinary into the external data section / so first remove the old objects and recreate the bindings again

Also,please,  take care that LoadBinary service has the correct permission in TWX  but I think that is something what you alreay set ... so regarding  the status of the provided pictures

I hope that helps! If not then, please , let me know. Thanks

 

so the code of dataURItoBlog() function mention in the post... also in the project

 

//===========================================================
// function deffintions
//===========================================================
function dataURItoBlob(dataURI)
{
    // convert base64/URLEncoded data component to raw binary data held in a string
    var byteString;

    if(dataURI.split(',')[0].indexOf('base64') >= 0)
        byteString = atob(dataURI.split(',')[1]);
    else
        byteString = unescape(dataURI.split(',')[1]);

    // separate out the mime component
    var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

    // write the bytes of the string to a typed array
    var ia = new Uint8Array(byteString.length);
    for(var i = 0; i < byteString.length; i++)
    {
        ia[i] = byteString.charCodeAt(i);
    }

    return new Blob([ia], {type: mimeString});   //'video/ogg'
}
//===========================================================

 

so took it from so some post of the  Stack Overflow but could not rember ...

Hello @Jamal8548

 

It looks like you have some responses on your topic. If any of these replies helped you solve your question please mark the appropriate reply as the Accepted Solution. 

Of course, if you have more to share on your issue, please let the Community know so other community members can continue to help you.

Thanks,
Vivek N.
Community Moderation Team.

I still need some time for proper testing. i will be back on this topic in upcoming weeks. Thanks.

Top Tags