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

Is it possible to add 3D labels with Javascript?

nishihira
7-Bedrock

Is it possible to add 3D labels with Javascript?

Hello.
I would like to know how to add a new 3D label when i press the 2D button.
However, please tell me how to hide the 3D labels, except to show the 3D labels when I press the 2D button.

 

1 ACCEPTED SOLUTION

Accepted Solutions

Hi @nishihira ,

there are 2 different questions, possibly the second one is not clear expressed and need further clarification.

-Currently , so far I know , you could not create a new widget (eg. 3Dlabel) on mobile device when you are already in the view .

- to the second question - what you can do -> is to select all widgets from type 3Dlabels and to hide them -set visible attribute to false. -and later display only this one what you want to be visible. e.g the follow function could display all 3DLebels or to hide them - possibly this is one is  the sub task what you want to implement:

 

 

//////=========================================================
function hasWdgProp(widget,property)
{
 	for (wp in widget)	{
            //console.log("property="+property+" | wp="+wp);
           if(wp==property) return true;
           else continue;
						}
}

//////========================================
$scope.hiddeAll3Dlabels=function(){
  var wdgs=$scope.app.view.Home.wdg; 
  for(wdg in wdgs)
  {   
    if(hasWdgProp(wdgs[wdg],'fontColor') && hasWdgProp(wdgs[wdg],'text')  )
    { //3DLabel have property fontColor and text
       wdgs[wdg].visible=false;
        $scope.$applyAsync();
  } } };
//////========================================
$scope.displayAll3Dlabels=function(){
  var wdgs=$scope.app.view.Home.wdg; 
  for(wdg in wdgs)
  {   
    if(hasWdgProp(wdgs[wdg],'fontColor') && hasWdgProp(wdgs[wdg],'text')  )
    { //3DLabel have property fontColor and text
       wdgs[wdg].visible=true;
        $scope.$applyAsync();
  } } };
//////========================================

 

 

Back to the question about dynamically create a widgets- there is only one  option , I know ,  -> this is using tmlText widget but it works only on load of the  view. I do not know how to activate this later. Possibly is there some mechanism, but the only one what was working for me was to left the view,   change the list and then go back  to the view.

Here is an example , showing how  you can create variables text labels when you enter a view - so you need to set a JSON List to an App parameter (it contains the properties) 

 

 

//==================================================================================================================
$scope.myLabels = [
  {  widgetid:"label-1", widgetname:"label-1" , text:"Text for Label-1",x:"0.1",y:"0.0",z:"0.1",ry:"0" },
  {  widgetid:"label-2", widgetname:"label-2" , text:"Text for Label-2",x:"0.1",y:"0.2",z:"0.1",ry:"10" },
  {  widgetid:"label-3", widgetname:"label-3" , text:"Text for Label-3",x:"0.1",y:"0.3",z:"0.1",ry:"20" },
  {  widgetid:"label-4", widgetname:"label-4" , text:"Text for Label-4",x:"0.1",y:"0.4",z:"0.1",ry:"30" },
  {  widgetid:"label-5", widgetname:"label-5" , text:"Text for Label-5",x:"0.1",y:"0.5",z:"0.1",ry:"45" },
  {  widgetid:"label-6", widgetname:"label-6" , text:"Text for Label-6",x:"0.1",y:"0.6",z:"0.1",ry:"90" }
];
//===============================
$scope.goToTESTView= function(){
$scope.app.params.labellist=$scope.myLabels
  $scope.$applyAsync();
  $scope.navigate("TEST");
  
};

 

 

 So this will set the data of the 3Dlabels to the app parameter myLabels and will then call View "Test" where we want to display these widgets.

In the TEST view we have a tmlText widget which has the following defection:

 

 

<div ng-repeat="lab in app.params.labellist">
<twx-dt-label id="{{lab.widgetid}}" widgetName="{{lab.widgetname}}"  text="{{lab.text}}" scale="1" x="{{lab.x}}" y="{{lab.y}}" z="{{lab.z}}" rx="0" ry="{{lab.ry}}" rz="0"></twx-dt-label>
</div>

 

 

 I attached a simple project showing this. 

Also it seems that the 3DLabels are only displayed -means read only. For me there was no possible to modify these labels (e.g. to move or hide like a regular widget ) later inside the view- without to restart the view. possibly this requires further /better definition. Any recommendation are welcome.

2023-06-26_18-21-39.jpg

View solution in original post

3 REPLIES 3

Hi @nishihira ,

there are 2 different questions, possibly the second one is not clear expressed and need further clarification.

-Currently , so far I know , you could not create a new widget (eg. 3Dlabel) on mobile device when you are already in the view .

- to the second question - what you can do -> is to select all widgets from type 3Dlabels and to hide them -set visible attribute to false. -and later display only this one what you want to be visible. e.g the follow function could display all 3DLebels or to hide them - possibly this is one is  the sub task what you want to implement:

 

 

//////=========================================================
function hasWdgProp(widget,property)
{
 	for (wp in widget)	{
            //console.log("property="+property+" | wp="+wp);
           if(wp==property) return true;
           else continue;
						}
}

//////========================================
$scope.hiddeAll3Dlabels=function(){
  var wdgs=$scope.app.view.Home.wdg; 
  for(wdg in wdgs)
  {   
    if(hasWdgProp(wdgs[wdg],'fontColor') && hasWdgProp(wdgs[wdg],'text')  )
    { //3DLabel have property fontColor and text
       wdgs[wdg].visible=false;
        $scope.$applyAsync();
  } } };
//////========================================
$scope.displayAll3Dlabels=function(){
  var wdgs=$scope.app.view.Home.wdg; 
  for(wdg in wdgs)
  {   
    if(hasWdgProp(wdgs[wdg],'fontColor') && hasWdgProp(wdgs[wdg],'text')  )
    { //3DLabel have property fontColor and text
       wdgs[wdg].visible=true;
        $scope.$applyAsync();
  } } };
//////========================================

 

 

Back to the question about dynamically create a widgets- there is only one  option , I know ,  -> this is using tmlText widget but it works only on load of the  view. I do not know how to activate this later. Possibly is there some mechanism, but the only one what was working for me was to left the view,   change the list and then go back  to the view.

Here is an example , showing how  you can create variables text labels when you enter a view - so you need to set a JSON List to an App parameter (it contains the properties) 

 

 

//==================================================================================================================
$scope.myLabels = [
  {  widgetid:"label-1", widgetname:"label-1" , text:"Text for Label-1",x:"0.1",y:"0.0",z:"0.1",ry:"0" },
  {  widgetid:"label-2", widgetname:"label-2" , text:"Text for Label-2",x:"0.1",y:"0.2",z:"0.1",ry:"10" },
  {  widgetid:"label-3", widgetname:"label-3" , text:"Text for Label-3",x:"0.1",y:"0.3",z:"0.1",ry:"20" },
  {  widgetid:"label-4", widgetname:"label-4" , text:"Text for Label-4",x:"0.1",y:"0.4",z:"0.1",ry:"30" },
  {  widgetid:"label-5", widgetname:"label-5" , text:"Text for Label-5",x:"0.1",y:"0.5",z:"0.1",ry:"45" },
  {  widgetid:"label-6", widgetname:"label-6" , text:"Text for Label-6",x:"0.1",y:"0.6",z:"0.1",ry:"90" }
];
//===============================
$scope.goToTESTView= function(){
$scope.app.params.labellist=$scope.myLabels
  $scope.$applyAsync();
  $scope.navigate("TEST");
  
};

 

 

 So this will set the data of the 3Dlabels to the app parameter myLabels and will then call View "Test" where we want to display these widgets.

In the TEST view we have a tmlText widget which has the following defection:

 

 

<div ng-repeat="lab in app.params.labellist">
<twx-dt-label id="{{lab.widgetid}}" widgetName="{{lab.widgetname}}"  text="{{lab.text}}" scale="1" x="{{lab.x}}" y="{{lab.y}}" z="{{lab.z}}" rx="0" ry="{{lab.ry}}" rz="0"></twx-dt-label>
</div>

 

 

 I attached a simple project showing this. 

Also it seems that the 3DLabels are only displayed -means read only. For me there was no possible to modify these labels (e.g. to move or hide like a regular widget ) later inside the view- without to restart the view. possibly this requires further /better definition. Any recommendation are welcome.

2023-06-26_18-21-39.jpg

Thank you @RolandRaytchev for your speedy and thorough replies!
Thanks further for the sample project. It helped me understand it very well.
I was able to add dynamic 3D labels with the help of the sample project.
Also, I was not able to change the labels as you mentioned. By the way, I tried the following.

// e.g 1
$scope.app.view['Purifier_Pipe'].wdg['label-1']['visible'] = false;
// e.g 2
$scope.setWidgetProp('label-1', 'visible', false);
// e.g 3
document.getElementById('label-1').remove();

 

Hello @nishihira ,

thanks for the feedback!

The idea is to leave the view (navigate to other accessory view, to change the json data and then return back to the view where it will display it according to the new update . Possibly there is other option to change they tml entity will work, but I have no information how...

When we have some actions base on DOM object , we need to check if they will work in chrome  but also we need to verify that functionality is OK on mobile platform. Sometimes this could work only in preview.

I remember another way to create 3d object , but it is to complex. (comparing to the way I already mentioned ) - so you can use the  tml3dRenderer.add3DObject() call to create your own objects. But you need to define the 3Dgemetry by vertex, edges, faces  etc. + transformation ,which is possibly not easy and I did not see any documentation showing how to use this (because this seems not be official supported functionality)

e.g.https://www.ptc.com/en/support/article/cs359260 -> simple example

https://www.ptc.com/en/support/article/cs358501

The advantage that this data is still not recognized as widget but  we can manipulate it later e.g. move or remove it. 

Here I also to provide a list what you use in the suggested tml dynamic entity creation according the the tml.md from PTC R&D (use the name without '_'):

## `<twx-dt-label>`
The Text Widget renders a text string in 3D.

### Attributes
* _id_: unique identifier of the asset
* _text_: text to be rendered
* _class_: CSS class to apply custom colors, fonts, etc.  Specific properties used below:
  * _font_: font property in CSS style (default: "36px Arial")
  * _font-style_: font property such as italic, oblique, normal
  * _font-weight_: boldness of the font (normal, bold, bolder, 200, etc)
  * _font-size_: font size
  * _--text-stroke-color_: color of the text outline (default: "rgba(0, 0, 255, 0)")
  * _--text-stroke-width_: width of the text outline (default: 1)
  * _color_: color of the text fill
  * _text-decoration_: css applies directly to the css of the canvas
* _textattrs_: (Deprecated 8.0.2, use font properties and CSS instead) rendering properties of the text in the format [property:value;] e.g. "font:46px Arial;stroke:#0000FF;fill:yellow", where:
  * _font_: font property in CSS style (default: "36px Arial")
  * _stroke_: color of the text outline (default: "rgba(0, 0, 255, 0)")
  * _linewidth_: width of the text outline (default: 1)
  * _fill_: color of the text fill
  * _background-color_: rgb color to fill in the background behind the text.
  * _opacity_: applies to background.  0..1 (0 = fully transparent)
  * _textalign_: horizontal position of the reference point relative to the text block e.g. left, right, center
  * _textbaseline_: vertical position of the reference point relative to the text block e.g. hanging, middle, etc.
* _font-outline-color_:  color of text outline (default: "rgba(255, 255, 255, 1)")
* _font-color_:  color of text (default: "rgba(0, 0, 0, 1)")
* _font-family_: Font family of text displayed (default: "Arial")
* _x, y, z_: position in xyz
* _rx, ry, rz_: orientation (degrees) about x,y,z axes
* _sx, sy, sz_: scale in xyz
* _width_ : physical width of the text in meters; if not specified and height is, will be calculated according to canvaswidth/canvasheight aspect ratio of the underlaying canvas. If neither width nor height is specified a default 1px = 1mm phsyical size conversion will be used.
* _height_ : physical height of the text in meters; (Default: .05); if not specified and width is, will be calculated according to canvaswidth/canvasheight aspect ratio of the underlaying canvas. If neither width nor height is specified a default height of .05 meters is used.
* _pivot_  : enum defining the pivot point for the text block. 1=top left,2 top center,3 top right. Default is 5 (center,middle)
* _hidden_: when set to true, the object will be hidden
* _opacity_: sets the asset's opacity factor for rendering (1 = opaque, 0 = fully transparent)
* _decal_: when set to true, the asset will appear on top of other 3D assets in the scene
* _occlude_: when set to true, the asset will mask the other 3D assets that appear behind it, and show the camera feed instead
* _billboard_: when set to true, the object will rotate to face the user while remaining aligned with the target's horizontal baseline
* _shader_: controls the appearance of the object.  if ommited, objects use a default lighting & appearance model
* _class_: specifies the class to used for CSS styling
* _style_: local override of style settings e.g. style="opacity:0.5;shader:fractal"

 

 

 

Top Tags