Skip to content

Commit

Permalink
Merge pull request #111 from Arpafaucon/stashed_text2d
Browse files Browse the repository at this point in the history
[rebased] Text rendering: python-side
  • Loading branch information
rdeits authored Mar 25, 2022
2 parents c3a9cea + 8dddc85 commit 0f25add
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 1 deletion.
69 changes: 69 additions & 0 deletions examples/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
2 changes: 1 addition & 1 deletion src/meshcat/commands.py
Original file line number Diff line number Diff line change
@@ -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


Expand Down
46 changes: 46 additions & 0 deletions src/meshcat/geometry.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -195,6 +215,25 @@ def lower(self, object_data):
}


class TextTexture(Texture):
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
# 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": 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 @@ -551,6 +590,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"

Expand Down

0 comments on commit 0f25add

Please sign in to comment.