3D text using meshwriter in Angular

3D text in Babylon.

When I tried to use Meshwriter in angular, I get an error like this

ERROR TypeError: meshwriter__WEBPACK_IMPORTED_MODULE_3___default.a.MeshWriter is not a function.
Babylonjs-GUI is also an extension that works good inside angular framework when installed as npm package.

MeshWriter should be added in Babylon namespace(Babylon.d.ts).

1 Like

gopivell, sorry for the difficulty. Can you give me a bit more information?

How are you loading it in Angular? Can you copy the commands to this thread? And where does the error arrive? On the JavaScript console of the browser? If a screen shot of that has any more information, that would be great.

There are several ways to load MeshWriter as a regular script file. For example:

const typeURL   = "https://host/path/meshwriter.min.js";  
jQuery.getScript(typeURL).then(startWriting)

But, as it was written in JavaScript, not Typescript, it might not fit into certain build flows. Please be patient.

I have Installed meshwriter package 1.1.1 from npm in the project.
Since its is angular, I cant import like this,

const typeURL = “https://host/path/meshwriter.min.js”;
jQuery.getScript(typeURL).then(startWriting)

code snippet:

import * as BABYLON from ‘babylonjs’;
import * as GUI from ‘babylonjs-gui’;
import * as MeshWriter from ‘meshwriter’;

export class TextDisplay {
private GUI2DText: GUI.TextBlock;
constructor(){
this.GUI2DText = new GUI.TextBlock();
}

public Display3DText ( scene?:any ): void{
  let Writer = (BABYLON as any).MeshWriter(scene, {scale:0.5});
  let  text1  = new Writer( 
            "ABC",
            {
                "anchor": "center",
                "letter-height": 50,
                "color": "#1C3870",
                "position": {
                    "z": 20
                }
            }
        );

       let text2  = new Writer( 
            "abcdefghijklmnopqrstuvwxyz",
            {
                "anchor": "center",
                "letter-height": 50,
                "color": "#70381C",
                "position": {
                    "z": -20
                }
            }
        );

let text3 = new Writer(
“$12,345-#67,890 = 100%++!”,
{
“anchor”: “left”, // The default value; this line has no effect
“letter-height”: 20,
“color”: “#70701C”,
“position”: {
“y”: 40,
“x”: 5
}
}
);
let text4 = new Writer(
“false||TRUE === 1 && 0.0??”,
{
“anchor”: “right”,
“letter-height”: 20,
“color”: “#70701C”,
“position”: {
“y”: 40,
“x”: -5
}
}
);
}
}

In this sample code, I have used GUI. Here GUI runs without any errors.

The error I get for meshwriter is

AppComponent_Host.ngfactory.js? [sm]:1 ERROR TypeError: babylonjs__WEBPACK_IMPORTED_MODULE_1__.MeshWriter is not a function
at TextDisplay.Display3DText (TextDisplay.ts:13)
at AppComponent.InitializeRendering (app.component.ts:38)
at AppComponent.ngAfterViewInit (app.component.ts:28)
at callProviderLifecycles (core.js:32328)
at callElementProvidersLifecycles (core.js:32293)
at callLifecycleHooksChildrenFirst (core.js:32275)
at checkAndUpdateView (core.js:44281)
at callWithDebugContext (core.js:45632)
at Object.debugCheckAndUpdateView [as checkAndUpdateView] (core.js:45194)
at ViewRef_.detectChanges (core.js:31126)

You can also refer the following links

You can also refer


1 Like

That is a ton of helpful information! Thank you.

Let me see what I can do on this today.

@gopivell, I have gone through this twice now. I think the larger problem may be that MeshWriter is not written in TypeScript. This prevents it from fitting into some build processes.

When the module is loaded, it should put MeshWriter in some handy places, like BABYLON.MeshWriter. (If BABYLON is in the global address space.) Typing BABYLON.MeshWriter in the address bar should give you the MeshWriter Wrapper. That really should work.

If BABYLON is not loaded previously then the function is associated with window.MeshWriter. You can go from there.

Nonetheless I updated the version of MeshWriter in NPM. You might (possibly) find that the latest version (1.1.2) yields better results. Please do try it.

Although it is untidy, it may be best to simply load meshwriter.min.js independently, after BABYLON is loaded. Unless Angular prevents that somehow . . .

1 Like

@TheLeftover,
Thanks for package update.

I tried loading script in the angular component, But it is not working.

I have used npm package MeshWriter 1.1.2. Javascript packages can be imported into angular. Importing works fine now.
I am able to import like this

import MeshWriter from ‘meshwriter’;

public Display3DText ( scene?:any ): void{
let Writer = MeshWriter(scene, {scale:0.5});
let text1 = new Writer(
“ABC”,
{
“anchor”: “center”,
“letter-height”: 50,
“color”: “#1C3870”,
“position”: {
“z”: 20
}
}
);

       let text2  = new Writer( 
            "abcdefghijklmnopqrstuvwxyz",
            {
                "anchor": "center",
                "letter-height": 50,
                "color": "#70381C",
                "position": {
                    "z": -20
                }
            }
        );

let text3 = new Writer(
“$12,345-#67,890 = 100%++!”,
{
“anchor”: “left”, // The default value; this line has no effect
“letter-height”: 20,
“color”: “#70701C”,
“position”: {
“y”: 40,
“x”: 5
}
}
);
let text4 = new Writer(
“false||TRUE === 1 && 0.0??”,
{
“anchor”: “right”,
“letter-height”: 20,
“color”: “#70701C”,
“position”: {
“y”: 40,
“x”: -5
}
}
);
}

But, it crashes in the line
let text1 = new Writer()

That is good news. Different error messages help.

The Earcut module is a common stumbling point. You can read about it at the MeshWriter github repo help. (GitHub - briantbutton/meshwriter: Babylon Mesh Writer) You can get it there. A recent version of Earcut is also delivered in the MeshWriter npm package (node_modules/meshwriter/earcut).

Hope that helps. 3:00am here. Going back to sleep. I will check in again tomorrow.

@gopivell, that is awesome! I am delighted.

Were you able to find Earcut and get it loaded likewise? I would like to close this out as a success.

Hi @TheLeftover,
Sorry for the late reply.
I did find earcut and installed it as npm package. But the above mentioned error is repeated, “Earcut is not defined”.
I suggest you to import earcut as a npm package in mesh writer. I hope this solves the issue.

Another possibility is to simply add something like <script src="https://preview.babylonjs.com/earcut.min.js"></script> in your html page (or get earcut in your own directory tree and make the script points to it).

@Evgeni_Popov
Hi,
In Angular, Cannot import external scripts like that.
Need to import as npm package only.

It seems it is possible:

@Evgeni_Popov
Hi,
External javascript can be imported if it does not have any dependency with any other modules.

If I am using Earcut directly in my app, I can use it as external js. But I am using meshwriter in my project. Earcut is dependency for meshwriter.
Here, Meshwriter is an npm package. So, meshwriter has to import Earcut as a module.

Ok, thanks for the information, I don’t know Angular (yet).

gopivell, did you try the link approach per Evgeni_Popov suggestion?

The Earcut module is a standalone module; it has no external dependencies. At the end, it defines “Earcut” as a new global variable. That’s it. I know Angular like to control the environment but surely it does not inhibit something like that!

For the record, MeshWriter makes no mention of Earcut. It needs/wants no pointer to Earcut. It calls BABYLON.PolygonMeshBuilder which uses Earcut.

There are many other uses for PolygonMeshBuilder. Hope this helps.

Hi @TheLeftover,

In index.js,
Kindly add
var earcut = require(‘earcut’);

and
in following statement pass this variable
meshBuilder = new BABYLON.PolygonMeshBuilder(“MeshWriter-”+letter+index+"-"+weeid(), array, scene, earcut);

In package.json,
add this dependency
“dependencies”: {
“earcut”: “^2.2.1”
}

This issue is caused due to Babylon code in polygonBuilder.ts.
declare var earcut: any;
variable is not initialized.
So, Earcut should be added in babylon’s package.json
declare var earcut: any = = require(‘earcut’);

Either we can fix in babylonjs or meshwriter.

Thanks
Gopinath Vellingiri

It is actually by design in the babylon side to be compatible with both umd and esm modules, so in case of es6 we can inject the dependency. I guess the easiest is to allow the same injection through the meshWriter.

gopivell, you have done impressive homework! I will add earcut to the MeshWriter package and pass it to BABYLON as a parameter, per your suggestion. Clever of you to find that!

I’ll get the new version out on NPM this week. I need to update documentation and check for backward compatibility.

Thank you for your patient and helpful persistence. MeshWriter will be better because of this.


Update: The version used for the playgrounds: https://sanfrancisco.ca.illuminated.city/js/meshwriter.min.js
has been updated to incorporate Earcut. It does not seem to have broken anything. When I get a build on NPM, I will post here. You can tell me if it fixes your problem.

1 Like

Hi @TheLeftover,
I shall use new version of meshwriter once it is ready.

Thank you for your patience to help me.