meshcat-dev / meshcat

Remotely-controllable 3D viewer, built on top of three.js
MIT License
256 stars 48 forks source link

add 2d text (as the texture of a plane) #43

Closed shensquared closed 5 years ago

shensquared commented 6 years ago

Following the suggestions in https://github.com/rdeits/meshcat/pull/41 Here's an initial attempt

screen shot 2018-11-12 at 12 29 22 am

Still a lot to clean up but want to first check, does this look like what you had in mind?

rdeits commented 6 years ago

Yeah, awesome! So, one question we should resolve is how we want to represent this in the meshcat interface. For example, one way to do it would be to add a new kind of object (like the way _meshfile works) which includes the specifications for the plane and the text on it. A second option would be to just expose the relevant pieces: for example, we could add a Plane geometry and create a TextTexture, and then drawing text on a plane would consist of sending a Plane with a TextTexture from the Python side.

I think I prefer the second option: it requires a bit more logic on the Python side, but it means that we can write text on anything, rather than just planes. And we can create convenience functions in Python so that simple tasks like drawing text on a flat surface is still easy. What do you think?

shensquared commented 6 years ago

Agreed, option 2 is more versatile and python friendly, which I guess is the point.

I think here’s what’s probably necessary for the job:

The only part I don’t immediately know how to do is actually creating TextTexture() in python. I know how to do it in JS now, but the tutorials I found all depend on creating a canvas in HTML first and then add the text via fillText. Not sure how this canvas business can be handled on the python side?

rdeits commented 6 years ago

Yeah, this sounds pretty good. Right, writing text into a canvas is possible in python, but I'd rather not bother with it. Instead, I think we can send a set_object command as you suggested, and we can make the TextTexture.lower() method return something like this:

{
    uuid: "<insert uuid here>",
    type: "_texttexture"
    text: "Hello world",
    font: "sans-serif",
    width: 200,
    height: 100,
    position: [10, 10],
}

Then on the Javascript side, we would need a little bit of logic to look for _texttexture textures and replace them with images by rendering the text into a Canvas using the provided arguments.

In that way, we can still rely on the browser's very convenient text rendering, while still staying very generic and composable.

Does that seem reasonable?

shensquared commented 6 years ago

Yep, sounds very good and doable. Will try it and update here.

shensquared commented 5 years ago

Finished a draft on both the JS and the python ends. Here's what it looks like writing on a cube: screen shot 2018-11-26 at 12 16 54 am Still need clean up and figuring out details like text placement, optimizing the default font size, canvas size etc...

rdeits commented 5 years ago

Hey Shen! Are you still working on this branch? Anything I can do to help?

shensquared commented 5 years ago

Hey Robin, sorry for leaving it hanging here. I honestly had forgotten about this -- functionally it was working properly and hardcoding a few parameters served me well enough for then, so I lost track of cleaning it up here...

But yeah, I still do want it in. Will revisit it by the weekend and hopefully it will be pretty quick. But will definitely bother you if needed help :)

rdeits commented 5 years ago

Ok, sounds good! Thanks!

shensquared commented 5 years ago

Hey @rdeits, the PR is ready for review now.

rdeits commented 5 years ago

Hey @shensquared I just wanted to let you know I haven't forgotten about this! I'm playing around with some ways to simplify the text loading logic (and also simplify some of the mesh loaders as well). I'll let you know if it works out (or if it doesn't...).

shensquared commented 5 years ago

Ah, sounds good, thanks for letting me know.

rdeits commented 5 years ago

I think https://github.com/shensquared/meshcat/pull/1 should work pretty well, and it avoids the complexity of needing a separate SetText command type.

shensquared commented 5 years ago

Updated both the javascript and python codes for the new design.

Something weird came up. I noticed ctx.font isn’t getting updated correctly if using ${} syntax. By splitting out a dummy font middle-man, it seems ${} itself isn't to blame, though something is lost down this road.

screen shot 2019-03-01 at 6 59 44 am

Using “” + “” syntax works correctly, hence the small change.

rdeits commented 5 years ago

Oh, fascinating (and baffling). Thanks for figuring that out.

This looks great, so I'm going to merge it!

We can still make more changes if necessary, since meshcat-python won't actually start using any of this new code until we merge https://github.com/rdeits/meshcat-python/pull/32