def test_tags(self): """Tests proper tags for each event/tensor.""" tensor_data = test_utils.get_random_mesh(100, add_faces=True, add_colors=True) config_dict = {"foo": 1} name = "foo" events = self.mesh_events( name, tensor_data.vertices, faces=tensor_data.faces, colors=tensor_data.colors, config_dict=config_dict, step=333, ) expected_names_set = frozenset( name_tpl % name for name_tpl in ["%s_VERTEX", "%s_FACE", "%s_COLOR"]) actual_names_set = frozenset( [event.summary.value[0].tag for event in events]) self.assertEqual(expected_names_set, actual_names_set) expected_bitmask = metadata.get_components_bitmask([ plugin_data_pb2.MeshPluginData.VERTEX, plugin_data_pb2.MeshPluginData.FACE, plugin_data_pb2.MeshPluginData.COLOR, ]) for event in events: self.assertEqual(expected_bitmask, self.get_metadata(event).components)
def mesh_pb(tag, vertices, faces=None, colors=None, config_dict=None, description=None): """Create a mesh summary to save in pb format. Args: tag: String tag for the summary. vertices: numpy array of shape `[dim_1, ..., dim_n, 3]` representing the 3D coordinates of vertices. faces: numpy array of shape `[dim_1, ..., dim_n, 3]` containing indices of vertices within each triangle. colors: numpy array of shape `[dim_1, ..., dim_n, 3]` containing colors for each vertex. config_dict: Dictionary with ThreeJS classes names and configuration. description: Optional long-form description for this summary, as a constant `str`. Markdown is supported. Defaults to empty. Returns: Instance of tf.Summary class. """ json_config = _get_json_config(config_dict) summaries = [] tensors = [ metadata.MeshTensor(vertices, plugin_data_pb2.MeshPluginData.VERTEX, tf.float32), metadata.MeshTensor(faces, plugin_data_pb2.MeshPluginData.FACE, tf.int32), metadata.MeshTensor(colors, plugin_data_pb2.MeshPluginData.COLOR, tf.uint8), ] tensors = [tensor for tensor in tensors if tensor.data is not None] components = metadata.get_components_bitmask( [tensor.content_type for tensor in tensors]) for tensor in tensors: shape = tensor.data.shape shape = [dim if dim is not None else -1 for dim in shape] tensor_proto = tensor_util.make_tensor_proto(tensor.data, dtype=tensor.data_type) summary_metadata = metadata.create_summary_metadata( tag, None, # display_name tensor.content_type, components, shape, description, json_config=json_config, ) instance_tag = metadata.get_instance_name(tag, tensor.content_type) summaries.append((instance_tag, summary_metadata, tensor_proto)) summary = summary_pb2.Summary() for instance_tag, summary_metadata, tensor_proto in summaries: summary.value.add(tag=instance_tag, metadata=summary_metadata, tensor=tensor_proto) return summary
def op(name, vertices, faces=None, colors=None, display_name=None, description=None, collections=None, config_dict=None): """Creates a TensorFlow summary op for mesh rendering. Args: name: A name for this summary operation. vertices: Tensor of shape `[dim_1, ..., dim_n, 3]` representing the 3D coordinates of vertices. faces: Tensor of shape `[dim_1, ..., dim_n, 3]` containing indices of vertices within each triangle. colors: Tensor of shape `[dim_1, ..., dim_n, 3]` containing colors for each vertex. display_name: If set, will be used as the display name in TensorBoard. Defaults to `name`. description: A longform readable description of the summary data. Markdown is supported. collections: Which TensorFlow graph collections to add the summary op to. Defaults to `['summaries']`. Can usually be ignored. config_dict: Dictionary with ThreeJS classes names and configuration. Returns: Merged summary for mesh/point cloud representation. """ display_name = _get_display_name(name, display_name) json_config = _get_json_config(config_dict) # All tensors representing a single mesh will be represented as separate # summaries internally. Those summaries will be regrouped on the client before # rendering. summaries = [] tensors = [ metadata.MeshTensor(vertices, plugin_data_pb2.MeshPluginData.VERTEX, tf.float32), metadata.MeshTensor(faces, plugin_data_pb2.MeshPluginData.FACE, tf.int32), metadata.MeshTensor(colors, plugin_data_pb2.MeshPluginData.COLOR, tf.uint8) ] tensors = [tensor for tensor in tensors if tensor.data is not None] components = metadata.get_components_bitmask( [tensor.content_type for tensor in tensors]) for tensor in tensors: summaries.append( _get_tensor_summary(name, display_name, description, tensor.data, tensor.content_type, components, json_config, collections)) all_summaries = tf.compat.v1.summary.merge(summaries, collections=collections, name=name) return all_summaries
def mesh(name, vertices, faces=None, colors=None, config_dict=None, step=None, description=None): """Writes a TensorFlow mesh summary. Args: name: A name for this summary. The summary tag used for TensorBoard will be this name prefixed by any active name scopes. vertices: Tensor of shape `[dim_1, ..., dim_n, 3]` representing the 3D coordinates of vertices. faces: Tensor of shape `[dim_1, ..., dim_n, 3]` containing indices of vertices within each triangle. colors: Tensor of shape `[dim_1, ..., dim_n, 3]` containing colors for each vertex. config_dict: Dictionary with ThreeJS classes names and configuration. step: Explicit `int64`-castable monotonic step value for this summary. If omitted, this defaults to `tf.summary.experimental.get_step()`, which must not be None. description: Optional long-form description for this summary, as a constant `str`. Markdown is supported. Defaults to empty. Returns: True if all components of the mesh were saved successfully and False otherwise. """ json_config = _get_json_config(config_dict) # All tensors representing a single mesh will be represented as separate # summaries internally. Those summaries will be regrouped on the client before # rendering. tensors = [ metadata.MeshTensor(vertices, plugin_data_pb2.MeshPluginData.VERTEX, tf.float32), metadata.MeshTensor(faces, plugin_data_pb2.MeshPluginData.FACE, tf.int32), metadata.MeshTensor(colors, plugin_data_pb2.MeshPluginData.COLOR, tf.uint8) ] tensors = [tensor for tensor in tensors if tensor.data is not None] components = metadata.get_components_bitmask( [tensor.content_type for tensor in tensors]) summary_scope = (getattr(tf.summary.experimental, 'summary_scope', None) or tf.summary.summary_scope) all_success = True with summary_scope(name, 'mesh_summary', values=tensors): for tensor in tensors: all_success = all_success and _write_summary( name, description, tensor.data, tensor.content_type, components, json_config, step) return all_success
def mesh(tag, vertices, colors, faces, config_dict, display_name=None, description=None): """Outputs a merged `Summary` protocol buffer with a mesh/point cloud. Args: tag: A name for this summary operation. vertices: Tensor of shape `[dim_1, ..., dim_n, 3]` representing the 3D coordinates of vertices. faces: Tensor of shape `[dim_1, ..., dim_n, 3]` containing indices of vertices within each triangle. colors: Tensor of shape `[dim_1, ..., dim_n, 3]` containing colors for each vertex. display_name: If set, will be used as the display name in TensorBoard. Defaults to `name`. description: A longform readable description of the summary data. Markdown is supported. config_dict: Dictionary with ThreeJS classes names and configuration. Returns: Merged summary for mesh/point cloud representation. """ from tensorboard.plugins.mesh.plugin_data_pb2 import MeshPluginData from tensorboard.plugins.mesh import metadata json_config = _get_json_config(config_dict) summaries = [] tensors = [ (vertices, MeshPluginData.VERTEX), (faces, MeshPluginData.FACE), (colors, MeshPluginData.COLOR), ] tensors = [tensor for tensor in tensors if tensor[0] is not None] components = metadata.get_components_bitmask( [content_type for (tensor, content_type) in tensors]) for tensor, content_type in tensors: summaries.append( _get_tensor_summary( tag, display_name, description, tensor, content_type, components, json_config, )) return Summary(value=summaries)
def pb(name, vertices, faces=None, colors=None, display_name=None, description=None, config_dict=None): """Create a mesh summary to save in pb format. Args: name: A name for this summary operation. vertices: numpy array of shape `[dim_1, ..., dim_n, 3]` representing the 3D coordinates of vertices. faces: numpy array of shape `[dim_1, ..., dim_n, 3]` containing indices of vertices within each triangle. colors: numpy array of shape `[dim_1, ..., dim_n, 3]` containing colors for each vertex. display_name: If set, will be used as the display name in TensorBoard. Defaults to `name`. description: A longform readable description of the summary data. Markdown is supported. config_dict: Dictionary with ThreeJS classes names and configuration. Returns: Instance of tf.Summary class. """ display_name = _get_display_name(name, display_name) json_config = _get_json_config(config_dict) summaries = [] tensors = [ metadata.MeshTensor( vertices, plugin_data_pb2.MeshPluginData.VERTEX, tf.float32), metadata.MeshTensor(faces, plugin_data_pb2.MeshPluginData.FACE, tf.int32), metadata.MeshTensor( colors, plugin_data_pb2.MeshPluginData.COLOR, tf.uint8) ] tensors = [tensor for tensor in tensors if tensor.data is not None] components = metadata.get_components_bitmask([ tensor.content_type for tensor in tensors]) for tensor in tensors: shape = tensor.data.shape shape = [dim if dim is not None else -1 for dim in shape] tensor_proto = tf.compat.v1.make_tensor_proto( tensor.data, dtype=tensor.data_type) summary_metadata = metadata.create_summary_metadata( name, display_name, tensor.content_type, components, shape, description, json_config=json_config) tag = metadata.get_instance_name(name, tensor.content_type) summaries.append((tag, summary_metadata, tensor_proto)) summary = tf.Summary() for tag, summary_metadata, tensor_proto in summaries: tf_summary_metadata = tf.SummaryMetadata.FromString( summary_metadata.SerializeToString()) summary.value.add( tag=tag, metadata=tf_summary_metadata, tensor=tensor_proto) return summary