From 64f69eb0ff1aca91e84899d1c67e0194ca40465a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Roussel?= Date: Tue, 15 Feb 2022 10:22:16 +0100 Subject: [PATCH 1/3] stashed changes from shensquared:text2d --- examples/demo.ipynb | 69 +++++++++++++++++++++++++++++++++++++++++ src/meshcat/commands.py | 2 +- src/meshcat/geometry.py | 47 ++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) diff --git a/examples/demo.ipynb b/examples/demo.ipynb index a3c6369..5562863 100644 --- a/examples/demo.ipynb +++ b/examples/demo.ipynb @@ -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": {}, diff --git a/src/meshcat/commands.py b/src/meshcat/commands.py index 793ac40..3816461 100644 --- a/src/meshcat/commands.py +++ b/src/meshcat/commands.py @@ -1,4 +1,4 @@ -from .geometry import Geometry, Object, Mesh, MeshPhongMaterial, OrthographicCamera, PerspectiveCamera, PointsMaterial, Points +from .geometry import Geometry, Object, Mesh, MeshPhongMaterial, OrthographicCamera, PerspectiveCamera, PointsMaterial, Points, TextTexture from .path import Path diff --git a/src/meshcat/geometry.py b/src/meshcat/geometry.py index 1dfc845..ffa6a80 100644 --- a/src/meshcat/geometry.py +++ b/src/meshcat/geometry.py @@ -80,6 +80,26 @@ 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. @@ -195,6 +215,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__() @@ -551,6 +591,13 @@ 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" From 445d3132cbd948c69cb8f91c96f363b5132fdef2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Roussel?= Date: Tue, 15 Feb 2022 10:52:02 +0100 Subject: [PATCH 2/3] fix stray 'unicode' --- src/meshcat/geometry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meshcat/geometry.py b/src/meshcat/geometry.py index ffa6a80..755ab72 100644 --- a/src/meshcat/geometry.py +++ b/src/meshcat/geometry.py @@ -229,7 +229,7 @@ def lower(self, object_data): return { u"uuid": self.uuid, u"type": u"_text", - u"text": unicode(self.text), + u"text": self.text, u"font_size": self.font_size, u"font_face": self.font_face, } From 8dddc8524d341512072284bbfe7b1f4b79867e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Roussel?= Date: Wed, 23 Mar 2022 14:17:53 +0100 Subject: [PATCH 3/3] remove unused attributes --- src/meshcat/geometry.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/meshcat/geometry.py b/src/meshcat/geometry.py index 755ab72..2d1ebdb 100644 --- a/src/meshcat/geometry.py +++ b/src/meshcat/geometry.py @@ -216,8 +216,7 @@ 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]): + def __init__(self, text, font_size=100, font_face='sans-serif'): super(TextTexture, self).__init__() self.text = text # font_size will be passed to the JS side as is; however if the