docs: def landm(self, val):
          '''
          Sets landmarks given any of:
           - ppfile
           - ldmk file
           - dict of {name:inds} (i.e. mesh.landm)
           - dict of {name:xyz} (i.e. mesh.landm_xyz)
           - Nx1 array or list of ints (treated as landm, given sequential integers as names)
           - Nx3 array or list of floats (treated as landm_xyz, given sequential integers as names)
           - pkl, json, yaml file containing either of the above dicts or arrays
          '''
          import numpy as np
  
          if val is None:
              self._landm = None
              self._raw_landmarks = None
          elif isinstance(val, basestring):
              self.landm = load_landmarks(val)
          else:
              if not hasattr(val, 'keys'):
                  val = {str(ii): v for ii, v in enumerate(val)}
              landm = {}
              landm_xyz = {}
              filtered_landmarks = []
              for k, v in val.iteritems():
                  if isinstance(v, (int, long)):
                      landm[k] = v
                  elif len(v) == 3:
                      if np.all(v == [0.0, 0.0, 0.0]):
                          filtered_landmarks.append(k)
                      landm_xyz[k] = v
                  else:
                      raise Exception("Can't parse landmark %s: %s" % (k, v))
              if len(filtered_landmarks) > 0:
                  import warnings
                  warnings.warn("WARNING: the following landmarks are positioned at (0.0, 0.0, 0.0) and were ignored: %s" % ", ".join(filtered_landmarks))
              # We preserve these and calculate everything seperately so that we can recompute_landmarks if v changes
              self._raw_landmarks = {
                  'landm': landm,
                  'landm_xyz': landm_xyz
              }
              self.recompute_landmarks()