class_docstr: Interface implemented by simulators and renderers. 
code: def add(self, asset: Asset) -> None:
      # if asset has already been converted, then do nothing
      if self in asset.linked_objects:
          return
  
      if isinstance(asset, UndefinedAsset):
          return
  
      # else use add_asset to create a new view-object and store it
      view_obj = self.add_asset(asset)
      if view_obj is None:
          return
  
      asset.linked_objects[self] = view_obj
  
      # trigger change notification for all fields (for initialization)
      # FIXME: This notifies all the views, but should only notify self.
      #        Unfortunately traitlets doesn't have a solution ready for this,
      #        so we will have to hack it in ourselves.
      for trait_name in asset.trait_names():
          value = getattr(asset, trait_name)
          if isinstance(value, Asset):  # recursively add assets to the
              self.add(value)
          asset.notify_change(
              munch.Munch(
                  owner=asset,
                  type="change",
                  name=trait_name,
                  new=value,
                  old=value,
              )
          )
  
file_path: kubric/kubric/core/view.py
imports: import abc
  from typing import Any, Callable, Dict, List
  from types import MappingProxyType
  import munch
  from kubric.core.scene import Scene
  from kubric.core.assets import Asset
  from kubric.core.assets import UndefinedAsset
label_desc: Use image node_id 4 for calling the View obj's underlying member method code with example usage: obj.add(asset) without return types