Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add interfacing to javascript side 2d text rendering #32

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
69 changes: 69 additions & 0 deletions demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,75 @@
"vis.delete()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"MeshCat supports simple 2d texts rendering. For example, to write 2d texts onto a geometry:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"vis.set_object(g.Box([1, 1, 2]),g.MeshPhongMaterial(map=g.TextTexture('Hello, world!')))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is also possible to simple write 'floating' texts onto a scene without attaching it to an object (e.g., for scene description):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"vis.delete()\n",
"vis.set_object(g.SceneText('Hello, world!',font_size=100))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and just like the usual geometry/object, the scene texts can be rotated:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Rz = tf.rotation_matrix(np.pi/2, [0, 0, 1])\n",
"Ry = tf.rotation_matrix(np.pi/2, [0, 1, 0])\n",
"vis.set_transform(Ry.dot(Rz))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Under the hood, the `SceneTexts` are written onto a `Plane` geometry, and the plane size can be specified by width and height. These two parameters affect the texts size when the font_size itself is set too large; they would force a font downsizing when rendering so as to fit all the texts within the specified plane."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for i in np.linspace(8,2,10):\n",
" vis.set_object(g.SceneText('Hello, world!',width=2*i,height=2*i,font_size=300))\n",
" time.sleep(0.05)"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
3 changes: 2 additions & 1 deletion src/meshcat/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
if sys.version_info >= (3, 0):
unicode = str

from .geometry import Geometry, Object, Mesh, MeshPhongMaterial, PointsMaterial, Points
from .geometry import (Geometry, Plane, Object, Mesh,
MeshPhongMaterial, PointsMaterial, Points, TextTexture)

class SetObject:
__slots__ = ["object", "path"]
Expand Down
48 changes: 48 additions & 0 deletions src/meshcat/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,25 @@ def intrinsic_transform(self):
return np.diag(np.hstack((self.radii, 1.0)))


class Plane(Geometry):

def __init__(self, width=1, height=1, widthSegments=1, heightSegments=1):
super(Plane, self).__init__()
self.width = width
self.height = height
self.widthSegments = widthSegments
self.heightSegments = heightSegments

def lower(self, object_data):
return {
u"uuid": self.uuid,
u"type": u"PlaneGeometry",
u"width": self.width,
u"height": self.height,
u"widthSegments": self.widthSegments,
u"heightSegments": self.heightSegments,
}

"""
A cylinder of the given height and radius. By Three.js convention, the axis of
rotational symmetry is aligned with the y-axis.
Expand Down Expand Up @@ -184,6 +203,26 @@ def lower(self, object_data):
}


class TextTexture(Texture):

def __init__(self, text, font_size=100, font_face='sans-serif',
width=200, height=100, position=[10, 10]):
super(TextTexture, self).__init__()
self.text = text
# font_size will be passed to the JS side as is; however if the
# text width exceeds canvas width, font_size will be reduced.
self.font_size = font_size
self.font_face = font_face

def lower(self, object_data):
return {
u"uuid": self.uuid,
u"type": u"_text",
u"text": unicode(self.text),
u"font_size": self.font_size,
u"font_face": self.font_face,
}

class GenericTexture(Texture):
def __init__(self, properties):
super(GenericTexture, self).__init__()
Expand Down Expand Up @@ -390,6 +429,15 @@ def PointCloud(position, color, **kwargs):
)



def SceneText(text, width=10, height=10, **kwargs):
return Mesh(
Plane(width=width,height=height),
MeshPhongMaterial(map=TextTexture(text,**kwargs),transparent=True,
needsUpdate=True)
)


class Line(Object):
_type = u"Line"

Expand Down