def _make_threejs_primitive(self): geometry = pythreejs.BufferGeometry() material = pythreejs.MeshStandardMaterial( vertexColors=pythreejs.enums.Colors.VertexColors, metalness=0.05, roughness=.9) result = pythreejs.Mesh(geometry, material) return result
def test_cylinder(): cylinder = Cylinder(10.0, 5.0, name='cylinder', color='blue', material="METAL") assert cylinder.name == 'cylinder' assert cylinder.__str__() == \ 'Cylinder cylinder color:blue material:METAL length:10.0 radius:5.0' assert cylinder.__repr__() == 'Cylinder' assert cylinder.length == 10.0 assert cylinder.radius == 5.0 assert cylinder.color == 'blue' if p3js is not None: mesh = cylinder._p3js_mesh() expected_mesh = p3js.Mesh(p3js.CylinderBufferGeometry(radiusTop=5.0, radiusBottom=5.0, height=10.0), p3js.MeshStandardMaterial(color='blue'), name='cylinder') assert repr(mesh) == repr(expected_mesh) cylinder.name = 'cylinder1' assert cylinder.name == 'cylinder1' cylinder.length = 14.0 assert cylinder.length == 14.0 cylinder.radius = 7.0 assert cylinder.radius == 7.0 cylinder.color = 'cyan' assert cylinder.color == 'cyan' cylinder.material = 'FOIL' assert cylinder.material == 'FOIL' assert cylinder.generate_dict() == { "color": "cyan", "type": "Cylinder", "name": "cylinder1", "length": 14.0, "radius": 7.0, "material": "FOIL" } assert isinstance(cylinder, Shape) cylinder_ = Cylinder(10.0, 5.0, color='blue') assert cylinder_.name == 'unnamed' assert cylinder_.__str__() == \ 'Cylinder unnamed color:blue material:default length:10.0 radius:5.0' assert cylinder_.__repr__() == 'Cylinder'
def test_cone(): cone = Cone(10.0, 5.0, name='cone', color='darkblue', material="CHECKERBOARD") assert cone.name == 'cone' assert cone.__str__() == \ 'Cone cone color:darkblue material:CHECKERBOARD length:10.0 radius:5.0' assert cone.__repr__() == 'Cone' assert cone.length == 10.0 assert cone.radius == 5.0 assert cone.color == 'darkblue' if p3js is not None: mesh = cone._p3js_mesh() expected_mesh = p3js.Mesh(p3js.CylinderBufferGeometry(radiusTop=0.0, radiusBottom=5.0, height=10.0), p3js.MeshStandardMaterial(color='darkblue'), name='cone') assert repr(mesh) == repr(expected_mesh) cone.name = 'cone1' assert cone.name == 'cone1' cone.length = 16.0 assert cone.length == 16.0 cone.radius = 3.0 assert cone.radius == 3.0 cone.color = 'darkcyan' assert cone.color == 'darkcyan' assert cone.generate_dict() == { "color": "darkcyan", "type": "Cone", "name": "cone1", "length": 16.0, "radius": 3.0, "material": "CHECKERBOARD" } assert isinstance(cone, Shape) cone_ = Cone(10.0, 5.0, color='darkblue') assert cone_.name == 'unnamed' assert cone_.__str__() == \ 'Cone unnamed color:darkblue material:default length:10.0 radius:5.0' assert cone_.__repr__() == 'Cone'
def test_torus_knot(): torus_knot = TorusKnot(10.0, 2.0, name='torus_knot', color='red') assert torus_knot.name == 'torus_knot' assert torus_knot.__str__() == ('TorusKnot torus_knot color:red ' 'material:default radius:10.0 ' 'tube_radius:2.0') assert torus_knot.__repr__() == 'TorusKnot' assert torus_knot.radius == 10.0 assert torus_knot.tube_radius == 2.0 assert torus_knot.color == 'red' if p3js is not None: mesh = torus_knot._p3js_mesh() expected_mesh = p3js.Mesh(p3js.TorusKnotBufferGeometry(radius=10.0, tube=2.0), p3js.MeshStandardMaterial(color='red'), name='torus_knot') assert repr(mesh) == repr(expected_mesh) torus_knot.name = 'torus_knot1' assert torus_knot.name == 'torus_knot1' torus_knot.radius = 12.0 assert torus_knot.radius == 12.0 torus_knot.tube_radius = 1.0 assert torus_knot.tube_radius == 1.0 torus_knot.color = 'blue' assert torus_knot.color == 'blue' assert torus_knot.generate_dict() == { "color": "blue", "type": "TorusKnot", "name": "torus_knot1", "radius": 12.0, "tube_radius": 1, "material": "default" } assert isinstance(torus_knot, Shape) torus_knot_ = TorusKnot(10.0, 2.0, color='red') assert torus_knot_.name == 'unnamed' assert torus_knot_.__str__() == ('TorusKnot unnamed color:red material:' 'default radius:10.0 tube_radius:2.0') assert torus_knot_.__repr__() == 'TorusKnot'
def test_plane(): plane = Plane(10.0, 20.0, name='plane', color='lightcyan') assert plane.name == 'plane' assert plane.__str__() == \ 'Plane plane color:lightcyan material:default length:10.0 width:20.0' assert plane.__repr__() == 'Plane' assert plane.length == 10.0 assert plane.width == 20.0 assert plane.color == 'lightcyan' if p3js is not None: mesh = plane._p3js_mesh() expected_mesh = p3js.Mesh(p3js.PlaneBufferGeometry(height=10.0, width=20.0), p3js.MeshStandardMaterial(color='lightcyan', side='DoubleSide'), name='plane') assert repr(mesh) == repr(expected_mesh) plane.name = 'plane1' assert plane.name == 'plane1' plane.length = 30.0 assert plane.length == 30.0 plane.width = 10.0 assert plane.width == 10.0 plane.color = 'lavender' assert plane.color == 'lavender' assert plane.generate_dict() == { "color": "lavender", "type": "Plane", "name": "plane1", "width": 10.0, "length": 30.0, "material": "default" } assert isinstance(plane, Shape) plane_ = Plane(10.0, 20.0, color='indigo') assert plane_.name == 'unnamed' assert plane_.__str__() == \ 'Plane unnamed color:indigo material:default length:10.0 width:20.0' assert plane_.__repr__() == 'Plane'
def test_torus(): torus = Torus(10.0, 2.0, name='torus', color='red') assert torus.name == 'torus' assert torus.__str__() == \ 'Torus torus color:red material:default radius:10.0 tube_radius:2.0' assert torus.__repr__() == 'Torus' assert torus.radius == 10.0 assert torus.tube_radius == 2.0 assert torus.color == 'red' if p3js is not None: mesh = torus._p3js_mesh() expected_mesh = p3js.Mesh(p3js.TorusBufferGeometry(radius=10.0, tube=2.0), p3js.MeshStandardMaterial(color='red'), name='torus') assert repr(mesh) == repr(expected_mesh) torus.name = 'torus1' assert torus.name == 'torus1' torus.radius = 15.0 assert torus.radius == 15.0 torus.tube_radius = 4.0 assert torus.tube_radius == 4.0 torus.color = 'tan' assert torus.color == 'tan' assert torus.generate_dict() == { "color": "tan", "type": "Torus", "name": "torus1", "radius": 15.0, "tube_radius": 4.0, "material": "default" } assert isinstance(torus, Shape) torus_ = Torus(10.0, 2.0, color='red') assert torus_.name == 'unnamed' assert torus_.__str__() == \ 'Torus unnamed color:red material:default radius:10.0 tube_radius:2.0' assert torus_.__repr__() == 'Torus'
def _p3js_mesh(self, constant_map={}): """Returns a PyThreeJS mesh object that corresponds to this shape.""" if p3js is None: raise ImportError('pythreejs is not installed.') data = self.generate_dict(constant_map=constant_map) attrs = dict() for k, v in self._p3js_attribute_map.items(): try: attrs[k] = data[v] except KeyError: attrs[k] = v try: geom_attr = '{}BufferGeometry'.format(self._p3js_geometry_type) Geometry = getattr(p3js, geom_attr) except AttributeError: geom_attr = '{}Geometry'.format(self._p3js_geometry_type) Geometry = getattr(p3js, geom_attr) geometry = Geometry(**attrs) # NOTE : For some reason traitlets doesn't think 'grey' is a valid HTML # color. This workaround should be removed, but deprecation will likely # be needed. if data['color'] == 'grey': color = 'gray' else: color = data['color'] material = p3js.MeshStandardMaterial(color=color, **self._p3js_material_attributes) mesh = p3js.Mesh(name=data['name'], geometry=geometry, material=material) self._mesh = mesh return mesh
def test_circle(): circle = Circle(10.0, name='circle', color='gold') assert circle.name == 'circle' assert circle.__str__() == \ 'Circle circle color:gold material:default radius:10.0' assert circle.__repr__() == 'Circle' assert circle.radius == 10.0 assert circle.color == 'gold' if p3js is not None: mesh = circle._p3js_mesh() expected_mesh = p3js.Mesh(p3js.CircleBufferGeometry(radius=10.0), p3js.MeshStandardMaterial(color='gold'), name='circle') assert repr(mesh) == repr(expected_mesh) circle.name = 'circle1' assert circle.name == 'circle1' circle.radius = 12.0 assert circle.radius == 12.0 circle.color = 'black' assert circle.color == 'black' assert circle.generate_dict() == { "color": "black", "type": "Circle", "name": "circle1", "radius": 12.0, "material": "default" } assert isinstance(circle, Shape) circle = Circle(10.0, color='gold') assert circle.name == 'unnamed' assert circle.__str__() == \ 'Circle unnamed color:gold material:default radius:10.0' assert circle.__repr__() == 'Circle'
def test_tetrahedron(): # Tetrahedron, Octahedron and Icosahedron geometry is defined by the # radius of the circumscribed sphere. It would be mentioned explicitly # in the docstrings tetrahedron = Tetrahedron(5.0, name='tetrahedron', color='maroon') assert tetrahedron.name == 'tetrahedron' assert tetrahedron.__str__() == \ 'Tetrahedron tetrahedron color:maroon material:default radius:5.0' assert tetrahedron.__repr__() == 'Tetrahedron' assert tetrahedron.radius == 5.0 assert tetrahedron.color == 'maroon' if p3js is not None: mesh = tetrahedron._p3js_mesh() expected_mesh = p3js.Mesh(p3js.TetrahedronGeometry(radius=5.0), p3js.MeshStandardMaterial(color='maroon'), name='tetrahedron') assert repr(mesh) == repr(expected_mesh) tetrahedron.name = 'tetrahedron1' assert tetrahedron.name == 'tetrahedron1' tetrahedron.radius = 7.0 assert tetrahedron.radius == 7.0 tetrahedron.color = 'orange' assert tetrahedron.color == 'orange' assert tetrahedron.generate_dict() == { "color": "orange", "type": "Tetrahedron", "name": "tetrahedron1", "radius": 7.0, "material": "default" } assert isinstance(tetrahedron, Shape) tetrahedron_ = Tetrahedron(5.0, color='maroon') assert tetrahedron_.name == 'unnamed' assert tetrahedron_.__str__() == \ 'Tetrahedron unnamed color:maroon material:default radius:5.0' assert tetrahedron_.__repr__() == 'Tetrahedron'
def test_box(): box = Box(10.0, 20.0, 30.0, name='box', color='blue', material="WATER") assert box.name == 'box' assert box.__str__() == 'Box box color:blue material:WATER depth:30.0 height:20.0 width:10.0' assert box.__repr__() == 'Box' assert box.width == 10.0 assert box.height == 20.0 assert box.depth == 30.0 assert box.color == 'blue' if p3js is not None: mesh = box._p3js_mesh() expected_mesh = p3js.Mesh(p3js.BoxBufferGeometry(width=10.0, height=20.0, depth=30.0), p3js.MeshStandardMaterial(color='blue'), name='box') assert repr(mesh) == repr(expected_mesh)
def test_sphere(): sphere = Sphere(10.0, name='sphere', color='azure') assert sphere.name == 'sphere' assert sphere.__str__() == \ 'Sphere sphere color:azure material:default radius:10.0' assert sphere.__repr__() == 'Sphere' assert sphere.radius == 10.0 assert sphere.color == 'azure' if p3js is not None: mesh = sphere._p3js_mesh() expected_mesh = p3js.Mesh(p3js.SphereBufferGeometry(radius=10.0), p3js.MeshStandardMaterial(color='azure'), name='sphere') assert repr(mesh) == repr(expected_mesh) sphere.name = 'sphere1' assert sphere.name == 'sphere1' sphere.radius = 14.0 assert sphere.radius == 14.0 sphere.color = 'aqua' assert sphere.color == 'aqua' assert sphere.generate_dict() == { "color": "aqua", "type": "Sphere", "name": "sphere1", "radius": 14.0, "material": "default" } assert isinstance(sphere, Shape) sphere_ = Sphere(10.0, color='azure') assert sphere_.name == 'unnamed' assert sphere_.__str__() == \ 'Sphere unnamed color:azure material:default radius:10.0' assert sphere_.__repr__() == 'Sphere'
def test_icosahedron(): icosahedron = Icosahedron(11.0, name='icosahedron', color='blue') assert icosahedron.name == 'icosahedron' assert icosahedron.__str__() == \ 'Icosahedron icosahedron color:blue material:default radius:11.0' assert icosahedron.__repr__() == 'Icosahedron' assert icosahedron.radius == 11.0 assert icosahedron.color == 'blue' if p3js is not None: mesh = icosahedron._p3js_mesh() expected_mesh = p3js.Mesh(p3js.IcosahedronGeometry(radius=11.0), p3js.MeshStandardMaterial(color='blue'), name='icosahedron') assert repr(mesh) == repr(expected_mesh) icosahedron.name = 'icosahedron1' assert icosahedron.name == 'icosahedron1' icosahedron.radius = 3.0 assert icosahedron.radius == 3.0 icosahedron.color = 'blue' assert icosahedron.color == 'blue' assert icosahedron.generate_dict() == { "color": "blue", "type": "Icosahedron", "name": "icosahedron1", "radius": 3.0, "material": "default" } assert isinstance(icosahedron, Shape) icosahedron_ = Icosahedron(11.0, color='blue') assert icosahedron_.name == 'unnamed' assert icosahedron_.__str__() == \ 'Icosahedron unnamed color:blue material:default radius:11.0' assert icosahedron_.__repr__() == 'Icosahedron'
def test_octahedron(): octahedron = Octahedron(12.0, name='octahedron', color='purple') assert octahedron.name == 'octahedron' assert octahedron.__str__() == \ 'Octahedron octahedron color:purple material:default radius:12.0' assert octahedron.__repr__() == 'Octahedron' assert octahedron.radius == 12.0 assert octahedron.color == 'purple' if p3js is not None: mesh = octahedron._p3js_mesh() expected_mesh = p3js.Mesh(p3js.OctahedronGeometry(radius=12.0), p3js.MeshStandardMaterial(color='purple'), name='octahedron') assert repr(mesh) == repr(expected_mesh) octahedron.name = 'octahedron1' assert octahedron.name == 'octahedron1' octahedron.radius = 2.0 assert octahedron.radius == 2.0 octahedron.color = 'red' assert octahedron.color == 'red' assert octahedron.generate_dict() == { "color": "red", "type": "Octahedron", "name": "octahedron1", "radius": 2.0, "material": "default" } assert isinstance(octahedron, Shape) octahedron_ = Octahedron(12.0, color='purple') assert octahedron_.name == 'unnamed' assert octahedron_.__str__() == \ 'Octahedron unnamed color:purple material:default radius:12.0' assert octahedron_.__repr__() == 'Octahedron'
def mesh_animation(times, xt, faces): """ Animate a mesh from a sequence of mesh vertex positions Args: times - a list of time values t_i at which the configuration x is specified xt - i.e., x(t). A list of arrays representing mesh vertex positions at times t_i. Dimensions of each array should be the same as that of mesh.geometry.array TODO nt - n(t) vertex normals faces - array of faces, with vertex loop for each face Side effects: displays rendering of mesh, with animation action Returns: None TODO renderer - THREE.Render to show the default scene TODO position_action - THREE.AnimationAction IPython widget """ position_morph_attrs = [] for pos in xt[ 1:]: # xt[0] uses as the Mesh's default/initial vertex position position_morph_attrs.append( THREE.BufferAttribute(pos, normalized=False)) # Testing mesh.geometry.morphAttributes = {'position': position_morph_attrs} geom = THREE.BufferGeometry( attributes={ 'position': THREE.BufferAttribute(xt[0], normalized=False), 'index': THREE.BufferAttribute(faces.ravel()) }, morphAttributes={'position': position_morph_attrs}) matl = THREE.MeshStandardMaterial(side='DoubleSide', color='red', wireframe=True, morphTargets=True) mesh = THREE.Mesh(geom, matl) # create key frames position_track = THREE.NumberKeyframeTrack( name='.morphTargetInfluences[0]', times=times, values=list(range(0, len(times)))) # create animation clip from the morph targets position_clip = THREE.AnimationClip(tracks=[position_track]) # create animation action position_action = THREE.AnimationAction(THREE.AnimationMixer(mesh), position_clip, mesh) # TESTING camera = THREE.PerspectiveCamera(position=[2, 1, 2], aspect=600 / 400) scene = THREE.Scene(children=[ mesh, camera, THREE.AxesHelper(0.2), THREE.DirectionalLight(position=[3, 5, 1], intensity=0.6), THREE.AmbientLight(intensity=0.5) ]) renderer = THREE.Renderer( camera=camera, scene=scene, controls=[THREE.OrbitControls(controlling=camera)], width=600, height=400) display(renderer, position_action)
def add_mesh(self, v, f, c=None, uv=None, shading={}, texture_data=None): sh = self.__get_shading(shading) mesh_obj = {} #it is a tet if v.shape[1] == 3 and f.shape[1] == 4: f_tmp = np.ndarray([f.shape[0]*4, 3], dtype=f.dtype) for i in range(f.shape[0]): f_tmp[i*4+0] = np.array([f[i][1], f[i][0], f[i][2]]) f_tmp[i*4+1] = np.array([f[i][0], f[i][1], f[i][3]]) f_tmp[i*4+2] = np.array([f[i][1], f[i][2], f[i][3]]) f_tmp[i*4+3] = np.array([f[i][2], f[i][0], f[i][3]]) f = f_tmp if v.shape[1] == 2: v = np.append(v, np.zeros([v.shape[0], 1]), 1) # Type adjustment vertices v = v.astype("float32", copy=False) # Color setup colors, coloring = self.__get_colors(v, f, c, sh) # Type adjustment faces and colors c = colors.astype("float32", copy=False) # Material and geometry setup ba_dict = {"color": p3s.BufferAttribute(c)} if coloring == "FaceColors": verts = np.zeros((f.shape[0]*3, 3), dtype="float32") for ii in range(f.shape[0]): #print(ii*3, f[ii]) verts[ii*3] = v[f[ii,0]] verts[ii*3+1] = v[f[ii,1]] verts[ii*3+2] = v[f[ii,2]] v = verts else: f = f.astype("uint32", copy=False).ravel() ba_dict["index"] = p3s.BufferAttribute(f, normalized=False) ba_dict["position"] = p3s.BufferAttribute(v, normalized=False) if type(uv) != type(None): uv = (uv - np.min(uv)) / (np.max(uv) - np.min(uv)) if texture_data is None: texture_data = gen_checkers(20, 20) tex = p3s.DataTexture(data=texture_data, format="RGBFormat", type="FloatType") material = p3s.MeshStandardMaterial(map=tex, reflectivity=sh["reflectivity"], side=sh["side"], roughness=sh["roughness"], metalness=sh["metalness"], flatShading=sh["flat"], polygonOffset=True, polygonOffsetFactor= 1, polygonOffsetUnits=5) ba_dict["uv"] = p3s.BufferAttribute(uv.astype("float32", copy=False)) else: material = p3s.MeshStandardMaterial(vertexColors=coloring, reflectivity=sh["reflectivity"], side=sh["side"], roughness=sh["roughness"], metalness=sh["metalness"], flatShading=sh["flat"], polygonOffset=True, polygonOffsetFactor= 1, polygonOffsetUnits=5) geometry = p3s.BufferGeometry(attributes=ba_dict) if coloring == "VertexColors": geometry.exec_three_obj_method('computeVertexNormals') else: geometry.exec_three_obj_method('computeFaceNormals') # Mesh setup mesh = p3s.Mesh(geometry=geometry, material=material) # Wireframe setup mesh_obj["wireframe"] = None if sh["wireframe"]: wf_geometry = p3s.WireframeGeometry(mesh.geometry) # WireframeGeometry wf_material = p3s.LineBasicMaterial(color=sh["wire_color"], linewidth=sh["wire_width"]) wireframe = p3s.LineSegments(wf_geometry, wf_material) mesh.add(wireframe) mesh_obj["wireframe"] = wireframe # Bounding box setup if sh["bbox"]: v_box, f_box = self.__get_bbox(v) _, bbox = self.add_edges(v_box, f_box, sh, mesh) mesh_obj["bbox"] = [bbox, v_box, f_box] # Object setup mesh_obj["max"] = np.max(v, axis=0) mesh_obj["min"] = np.min(v, axis=0) mesh_obj["geometry"] = geometry mesh_obj["mesh"] = mesh mesh_obj["material"] = material mesh_obj["type"] = "Mesh" mesh_obj["shading"] = sh mesh_obj["coloring"] = coloring mesh_obj["arrays"] = [v, f, c] # TODO replays with proper storage or remove if not needed return self.__add_object(mesh_obj)
def test_cube(): cube = Cube(10.0, name='cube', color='blue', material="WATER") assert cube.name == 'cube' assert cube.__str__() == 'Cube cube color:blue material:WATER length:10.0' assert cube.__repr__() == 'Cube' assert cube.length == 10.0 assert cube.color == 'blue' if p3js is not None: mesh = cube._p3js_mesh() expected_mesh = p3js.Mesh(p3js.BoxBufferGeometry(width=10.0, height=10.0, depth=10.0), p3js.MeshStandardMaterial(color='blue'), name='cube') assert repr(mesh) == repr(expected_mesh) cube.name = 'cube1' assert cube.name == 'cube1' cube.length = 16.0 assert cube.length == 16.0 cube.color = 'red' assert cube.color == 'red' assert cube.generate_dict() == { "color": "red", "type": "Cube", "name": "cube1", "length": 16.0, "material": "WATER" } assert isinstance(cube, Shape) if p3js is not None: mesh = cube._p3js_mesh() expected_mesh = p3js.Mesh(p3js.BoxBufferGeometry(width=16.0, height=16.0, depth=16.0), p3js.MeshStandardMaterial(color='red'), name='cube1') assert repr(mesh) == repr(expected_mesh) # testing unnamed cube = Cube(10.0, color='blue') assert cube.name == 'unnamed' expected = 'Cube unnamed color:blue material:default length:10.0' assert cube.__str__() == expected assert cube.__repr__() == 'Cube' cube = Cube(symbols('V')**(1.0 / 3.0)) actual = cube.generate_dict(constant_map={symbols('V'): 27.0}) assert actual == { "color": "grey", "type": "Cube", "name": "unnamed", "length": 3.0, "material": "default" } if p3js is not None: mesh = cube._p3js_mesh(constant_map={symbols('V'): 27.0}) expected_mesh = p3js.Mesh(p3js.BoxBufferGeometry(width=3.0, height=3.0, depth=3.0), p3js.MeshStandardMaterial(color='gray'), name='unnamed') assert repr(mesh) == repr(expected_mesh)
# delta = cloth1.time_step() # mesh.geometry.attributes['position'].array = mesh.geometry.attributes['position'].array + delta # t += 1 # %% # mesh.geometry.attributes['position'].array = x0 # cloth2 = cloth(x0, N, t2=True, d=False) # cloth2.add_springs() # cloth2.cuff_cloth() # t = 0 # while t < 500: # delta = cloth2.time_step() # mesh.geometry.attributes['position'].array = mesh.geometry.attributes['position'].array + delta # t += 1 # %% mesh.geometry.attributes['position'].array = x0 cloth3 = cloth(x0, N, t2=True, d=True) cloth3.add_springs() cloth3.cuff_cloth() cloth3.add_ball() t = 0 sphere_geo = THREE.SphereGeometry(2.5, 8, 8) sphere = THREE.Mesh(sphere_geo, THREE.MeshStandardMaterial(wireframe=True)) sphere.position = (5, -5, 5) viewer.scene.add(sphere) while t < 300: delta = cloth3.time_step() mesh.geometry.attributes[ 'position'].array = mesh.geometry.attributes['position'].array + delta t += 1 # %%