diff --git a/src/meshcat/geometry.py b/src/meshcat/geometry.py index 42c9d84..8ea128f 100644 --- a/src/meshcat/geometry.py +++ b/src/meshcat/geometry.py @@ -14,11 +14,13 @@ class SceneElement(object): + def __init__(self): self.uuid = unicode(uuid.uuid1()) class ReferenceSceneElement(SceneElement): + def lower_in_object(self, object_data): object_data.setdefault(self.field, []).append(self.lower(object_data)) return self.uuid @@ -44,6 +46,7 @@ class Image(ReferenceSceneElement): class Box(Geometry): + def __init__(self, lengths): super(Box, self).__init__() self.lengths = lengths @@ -59,6 +62,7 @@ def lower(self, object_data): class Sphere(Geometry): + def __init__(self, radius): super(Sphere, self).__init__() self.radius = radius @@ -68,8 +72,8 @@ def lower(self, object_data): u"uuid": self.uuid, u"type": u"SphereGeometry", u"radius": self.radius, - u"widthSegments" : 20, - u"heightSegments" : 20 + u"widthSegments": 20, + u"heightSegments": 20 } @@ -78,6 +82,7 @@ class Ellipsoid(Sphere): An Ellipsoid is treated as a Sphere of unit radius, with an affine transformation applied to distort it into the ellipsoidal shape """ + def __init__(self, radii): super(Ellipsoid, self).__init__(1.0) self.radii = radii @@ -86,11 +91,61 @@ def intrinsic_transform(self): return np.diag(np.hstack((self.radii, 1.0))) +class Ring(Geometry): + """ + A two-dimensional ring or possibly ring sector geometry. + Optional thetaStart and thetaLength by default gives a full ring (2pi angle) + """ + + def __init__(self, innerRadius, outerRadius, thetaStart=0, thetaLength=np.pi * 2): + super(Ring, self).__init__() + self.innerRadius = innerRadius + self.outerRadius = outerRadius + self.thetaStart = thetaStart + self.thetaLength = thetaLength + + def lower(self, object_data): + return { + u"uuid": self.uuid, + u"type": u"RingGeometry", + u"thetaSegments": 20, + u"phiSegments": 20, + u"innerRadius": self.innerRadius, + u"outerRadius": self.outerRadius, + u"thetaStart": self.thetaStart, + u"thetaLength": self.thetaLength + } + + +class Circle(Geometry): + """ + Circle or circular sector. + """ + + def __init__(self, radius, thetaStart=0, thetaLength=np.pi * 2): + super(Circle, self).__init__() + self.radius = radius + self.thetaStart = thetaStart + self.thetaLength = thetaLength + + def lower(self, object_data): + return { + u"uuid": self.uuid, + u"type": u"CircleGeometry", + u"segments": 20, + u"radius": self.radius, + u"thetaStart": self.thetaStart, + u"thetaLength": self.thetaLength + } + """ A cylinder of the given height and radius. By Three.js convention, the axis of rotational symmetry is aligned with the y-axis. """ + + class Cylinder(Geometry): + def __init__(self, height, radius=1.0, radiusTop=None, radiusBottom=None): super(Cylinder, self).__init__() if radiusTop is not None and radiusBottom is not None: @@ -113,7 +168,28 @@ def lower(self, object_data): } +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, + } + + class MeshMaterial(Material): + def __init__(self, color=0xffffff, reflectivity=0.5, map=None, **kwargs): super(MeshMaterial, self).__init__() self.color = color @@ -135,22 +211,22 @@ def lower(self, object_data): class MeshBasicMaterial(MeshMaterial): - _type=u"MeshBasicMaterial" + _type = u"MeshBasicMaterial" class MeshPhongMaterial(MeshMaterial): - _type=u"MeshPhongMaterial" + _type = u"MeshPhongMaterial" class MeshLambertMaterial(MeshMaterial): - _type=u"MeshLambertMaterial" + _type = u"MeshLambertMaterial" class MeshToonMaterial(MeshMaterial): - _type=u"MeshToonMaterial" - + _type = u"MeshToonMaterial" class PngImage(Image): + def __init__(self, data): super(PngImage, self).__init__() self.data = data @@ -168,6 +244,7 @@ def lower(self, object_data): class GenericTexture(Texture): + def __init__(self, properties): super(GenericTexture, self).__init__() self.properties = properties @@ -182,6 +259,7 @@ def lower(self, object_data): class ImageTexture(Texture): + def __init__(self, image, wrap=[1001, 1001], repeat=[1, 1], **kwargs): super(ImageTexture, self).__init__() self.image = image @@ -201,6 +279,7 @@ def lower(self, object_data): class GenericMaterial(Material): + def __init__(self, properties): self.properties = properties self.uuid = str(uuid.uuid1()) @@ -215,6 +294,7 @@ def lower(self, object_data): class Object(SceneElement): + def __init__(self, geometry, material=MeshPhongMaterial()): super(Object, self).__init__() self.geometry = geometry @@ -251,7 +331,8 @@ def item_size(array): elif array.ndim == 2: return array.shape[0] else: - raise ValueError("I can only pack 1- or 2-dimensional numpy arrays, but this one has {:d} dimensions".format(array.ndim)) + raise ValueError( + "I can only pack 1- or 2-dimensional numpy arrays, but this one has {:d} dimensions".format(array.ndim)) def threejs_type(dtype): @@ -280,6 +361,7 @@ def pack_numpy_array(x): class ObjMeshGeometry(Geometry): + def __init__(self, contents): super(ObjMeshGeometry, self).__init__() self.contents = contents @@ -299,6 +381,7 @@ def from_file(fname): class PointsGeometry(Geometry): + def __init__(self, position, color=None): super(PointsGeometry, self).__init__() self.position = position @@ -318,6 +401,7 @@ def lower(self, object_data): class PointsMaterial(Material): + def __init__(self, size=0.001, color=0xffffff): super(PointsMaterial, self).__init__() self.size = size