Beispiel #1
0
    def update(self, state, time):
        # use 60 fps time codes
        time = time * 60.0

        try:
            self.stage.SetEndTimeCode(time)
        except:
            pass

        # convert to list
        particle_x = state.q.tolist()
        particle_orientations = [Gf.Quath(1.0, 0.0, 0.0, 0.0)] * self.model.particle_count

        self.particle_instancer.GetPositionsAttr().Set(particle_x, time)
        self.particle_instancer.GetOrientationsAttr().Set(particle_orientations, time)

        # update cloth
        if (self.cloth_mesh):

            for k, v in self.cloth_remap.items():
                self.cloth_verts[v] = particle_x[k]

            self.cloth_mesh.GetPointsAttr().Set(self.cloth_verts, time)

        # update springs
        if (self.model.spring_count > 0):

            line_positions = []
            line_rotations = []
            line_scales = []

            for i in range(self.model.spring_count):

                index0 = self.model.spring_indices[i * 2 + 0]
                index1 = self.model.spring_indices[i * 2 + 1]

                pos0 = particle_x[index0]
                pos1 = particle_x[index1]

                (pos, rot, scale) = self.compute_segment_xform(Gf.Vec3f(pos0), Gf.Vec3f(pos1))

                line_positions.append(pos)
                line_rotations.append(rot)
                line_scales.append(scale)

            self.line_instancer.GetPositionsAttr().Set(line_positions, time)
            self.line_instancer.GetOrientationsAttr().Set(line_rotations, time)
            self.line_instancer.GetScalesAttr().Set(line_scales, time)

        # rigids
        for b in range(self.model.rigid_count):

            #xform = UsdGeom.Xform.Define(self.stage, self.root.GetPath().AppendChild("body_" + str(b)))

            xform = UsdGeom.Xform(self.stage.GetPrimAtPath(self.root.GetPath().AppendChild("body_" + str(b))))

            x = state.rigid_x[b].tolist()
            r = state.rigid_r[b].tolist()

            usd_set_xform(xform, x, r, (1.0, 1.0, 1.0), time)
def sync_update(root_prim, obj_data: ObjectData, is_updated_geometry,
                is_updated_transform, **kwargs):
    """ Updates existing rpr object. Checks obj.type and calls corresponded sync_update() """

    log("sync_update", obj_data.object, obj_data.instance_id,
        is_updated_geometry, is_updated_transform)

    obj_prim = root_prim.GetChild(obj_data.sdf_name)
    if not obj_prim.IsValid():
        sync(root_prim, obj_data, **kwargs)
        return

    if is_updated_transform:
        xform = UsdGeom.Xform(obj_prim)
        xform.MakeMatrixXform().Set(Gf.Matrix4d(obj_data.transform))

    if is_updated_geometry:
        obj = obj_data.object
        if obj.type == 'MESH':
            if obj.mode == 'OBJECT':
                mesh.sync_update(obj_prim, obj, **kwargs)
            else:
                to_mesh.sync_update(obj_prim, obj, **kwargs)

        elif obj.type == 'LIGHT':
            light.sync_update(obj_prim, obj, **kwargs)

        elif obj.type == 'CAMERA':
            camera.sync_update(obj_prim, obj, **kwargs)

        elif obj.type in ('EMPTY', 'ARMATURE'):
            pass

        else:
            to_mesh.sync_update(obj_prim, obj, **kwargs)
    def sync_from_prim(self, prim, context):
        prim_obj = self.id_data

        if not prim or str(prim.GetTypeName()) != 'Xform':
            self.cached_stage.clear()
            prim_obj.name = self.sdf_path = "/"
            prim_obj.matrix_world = mathutils.Matrix.Identity(4)

            # hiding, deactivating and deselecting prim object
            prim_obj.hide_viewport = True
            prim_obj.select_set(False)
            if context.view_layer.objects.active == prim_obj:
                context.view_layer.objects.active = None
            return

        self.cached_stage.assign(prim.GetStage())
        prim_obj.name = self.sdf_path = str(prim.GetPath())
        xform = UsdGeom.Xform(prim)
        ops = xform.GetOrderedXformOps()
        if ops:
            prim_obj.matrix_world = mathutils.Matrix(ops[0].Get()).transposed()
        else:
            prim_obj.matrix_world = mathutils.Matrix.Identity(4)

        # showing, activating and selecting prim object
        prim_obj.hide_viewport = False
        context.view_layer.objects.active = prim_obj
        if len(context.selected_objects) < 2:
            if context.selected_objects:
                context.selected_objects[0].select_set(False)
            prim_obj.select_set(True)
def sync_update(root_prim, obj: bpy.types.Object, is_updated_geometry,
                is_updated_transform, **kwargs):
    """ Updates existing rpr object. Checks obj.type and calls corresponded sync_update() """

    log("sync_update", obj, is_updated_geometry, is_updated_transform)

    obj_prim = root_prim.GetChild(sdf_name(obj))
    if not obj_prim.IsValid():
        sync(root_prim, obj, **kwargs)
        return

    if is_updated_transform:
        xform = UsdGeom.Xform(obj_prim)
        xform.MakeMatrixXform().Set(Gf.Matrix4d(get_transform(obj)))

    if is_updated_geometry:
        if obj.type == 'MESH':
            if obj.mode == 'OBJECT':
                mesh.sync_update(obj_prim, obj, **kwargs)
            else:
                to_mesh.sync_update(obj_prim, obj, **kwargs)

        elif obj.type == 'LIGHT':
            light.sync_update(obj_prim, obj, **kwargs)

        elif obj.type in ('CURVE', 'FONT', 'SURFACE', 'META'):
            to_mesh.sync_update(obj_prim, obj, **kwargs)

        elif obj.type == 'EMPTY':
            pass

        else:
            log.warn("Not supported object to sync_update", obj, obj.type)
    def sync_to_prim(self):
        prim = self.get_prim()
        if not prim:
            return

        obj = self.id_data
        xform = UsdGeom.Xform(prim)
        xform.MakeMatrixXform().Set(Gf.Matrix4d(object.get_transform_local(obj)))
    def sync_to_prim(self):
        stage = self.cached_stage()
        if not stage:
            return

        obj = self.id_data
        prim = stage.GetPrimAtPath(self.sdf_path)

        xform = UsdGeom.Xform(prim)
        xform.MakeMatrixXform().Set(Gf.Matrix4d(get_transform(obj)))
    def sync_from_prim(self, root_obj, prim):
        prim_obj = self.id_data

        self.sdf_path = str(prim.GetPath())
        self.cached_stage.assign(prim.GetStage())

        prim_obj.name = prim.GetName()
        prim_obj.parent = root_obj
        prim_obj.matrix_local = usd_utils.get_xform_transform(UsdGeom.Xform(prim))
        prim_obj.hide_viewport = prim.GetTypeName() not in GEOM_TYPES
    def _ValidateXformPrim(self, stage, xformPrimPath,
            expectedTranslation=None):
        xformPrim = stage.GetPrimAtPath(xformPrimPath)
        self.assertTrue(xformPrim)

        xformSchema = UsdGeom.Xform(xformPrim)
        self.assertTrue(xformSchema)

        self._ValidateXformOps(xformPrim, expectedTranslation)

        return xformSchema
Beispiel #9
0
    def __init__(self, stroke, startVert, vertCount, startIndex, indexCount):  # pylint: disable=too-many-arguments
        self.stroke = stroke
        self.startVert = startVert
        self.vertCount = vertCount
        self.startIndex = startIndex
        self.indexCount = indexCount
        self.i = startVert
        self.step = 10
        self.radius = 0
        self.indicesWritten = 0
        self.growthVel = 1
        self.minHeight = self.GetVertex(0)[2]
        self.maxHeight = self.GetVertex(0)[2]
        self.avgHeight = self.GetVertex(0)[2]
        self.minLen = 10000000
        self.minPoint = self.GetVertex(0)

        minVal = (self.minPoint - worldCenter).GetLength()
        for i in range(vertCount):
            v = self.GetVertex(i)
            length = (v - worldCenter).GetLength()
            if length < minVal:
                minVal = length
                self.minPoint = v
            if Gf.IsClose(v, Gf.Vec3f(), 1e-7):
                continue
            length = Gf.Vec2f(v[0], v[2]).GetLength()
            self.minHeight = min(self.minHeight, v[1])
            self.maxHeight = max(self.minHeight, v[1])
            self.avgHeight = (self.maxHeight - self.minHeight) / 2.0
            self.minLen = min(self.minLen, length)

        # Debug visualization.
        self.minPtDebug = UsdGeom.Sphere.Define(
            stroke.prim.GetStage(),
            str(stroke.prim.GetPath()) + "/minPt" + str(startIndex),
        )
        self.minPtDebug.GetPrim().GetAttribute("purpose").Set("guide")
        attr = self.minPtDebug.GetPrim().GetAttribute(
            "primvars:displayOpacity")
        attr.Set([0.25])
        attr.SetMetadata("interpolation", "constant")
        attr = self.minPtDebug.GetPrim().GetAttribute("primvars:displayColor")
        attr.Set([Gf.Vec3f(1, 1, 1)], 0)
        attr.SetMetadata("interpolation", "constant")
        self.minPtDebug.CreateRadiusAttr(1.0)
        UsdGeom.Xform(self.minPtDebug.GetPrim()).AddTranslateOp().Set(
            self.minPoint)
Beispiel #10
0
def animate(stage):
  """The output from Tilt Brush is strokes with a growth velocity.
  This could be authored per vertex later (e.g. for easing).
  """
  # The current animation time, this will increase monotonicly to generate frames of animation.
  time = 1

  # The maximum number of animated strokes, for performance constraints.
  maxActive = 30

  # Filters dictate when a stroke becomes active, i.e. predicates for activation.
  activeFilter = isInRadius 
  activeFilterVert = isHigherVert
  
  # The target length of the animation.
  lengthInSeconds = 30 
  # The playback framerate.
  framesPerSecond = 30 
  # The number of frames we will generate based on target time and rate.
  numFrames = lengthInSeconds * framesPerSecond

  # Boundaries for activation.
  minHeight = 0 
  maxHeight = 20 
  radius = 17.0 
  maxRadius = 100.
  height = minHeight
 
  # Compute the actual radius of the world bounds.
  worldBounds = UsdGeom.Xform(stage.GetPrimAtPath("/")).ComputeWorldBound(0, "default")
  maxRadius = (worldBounds.GetRange().max - worldBounds.GetRange().min).GetLength()

  # Compute the centroid of the world.
  global worldCenter
  worldCenter = Gf.Vec3f(worldBounds.ComputeCentroid())
  # Just for newIntroSketch.tilt
  if "NewIntroSketch" in stage.GetRootLayer().identifier:
    worldCenter = Gf.Vec3f(0.73135, 19.92212, 33.2210311)
  worldCenter[1] = worldBounds.GetRange().min[1]

  print("World Center:", worldCenter)
  print("Max Radius:", maxRadius)

  # Visualize the radius.
  debugSphere = UsdGeom.Sphere(stage.DefinePrim("/debug", "Sphere"))
  debugSphere.CreateRadiusAttr(radius)
  debugSphere.GetPrim().GetAttribute("purpose").Set("guide")
  attr = debugSphere.GetPrim().GetAttribute("primvars:displayOpacity")
  attr.Set([0.125])
  attr.SetMetadata("interpolation", "constant")
  UsdGeom.Xform(attr.GetPrim()).AddTranslateOp().Set(worldCenter)
 

  # Initialize data structures.
  #   - strokes are Unity meshes (or Tilt Brush batches).
  #   - substrokes are the individual brush strokes within a single mesh.
  #   - activeSubstrokes are sub-strokes currently in-flight.
  #   - completeSubstrokes are sub-strokes that are done animating.
  strokes = MakeStrokes(stage)
  substrokes = MakeSubstrokes(strokes)
  activeStrokes = set()
  activeSubstrokes = set()
  completeSubstrokes = set() 

  # Compute step sizes based on target animation length.
  dRadius = (maxRadius - radius) / float(numFrames) / 1.5 
  dHeight = (maxHeight - minHeight) / float(numFrames)

  # Set USD animation start/end times.
  stage.SetStartTimeCode(time)
  stage.SetEndTimeCode(numFrames)

  # Zero out stroke opacities
  for s in strokes:
    s.Save(time)

  # Main animation loop.
  for time in range(0, numFrames):
    print()
    print("Time:", time, height, radius, smoothstep(1.0, float(numFrames), time))
    curActive = 0
    
    if len(activeStrokes) < maxActive:
      # On the final frame, increase activation volumes to "infinity" (and beyond ;)
      if time == numFrames - 1:
        height = 10000000
        radius = 10000000
      
      # Search for strokes to be activated.
      didAddStroke = 0
      for ss in substrokes:
        # Already animating, skip.
        if ss in activeSubstrokes:
          continue
        # Done animating, skip.
        if ss in completeSubstrokes:
          continue
        # Overloaded.
        if len(activeStrokes) >= maxActive:
          break
        # If this sub-stroke passes the filter, add it to the animating list.
        if activeFilter(ss.minPoint, radius):
          didAddStroke = 1
          activeSubstrokes.add(ss)
          activeStrokes.add(ss.stroke)        
          # Mark the stroke as dirty to save its initial state.
          ss.stroke.dirty = True
          ss.SetRadius(radius, time)
          print("+", end=' ')
      if not didAddStroke:
        # We didn't add any strokes, which means the radius needs to increase.
        # Grow the activation volumes (increase sphere size, raise floor plane height).
        height += dHeight 
        radius += dRadius * smoothstep(1.0, float(numFrames), time)



    # Update debug vis.
    debugSphere.GetRadiusAttr().Set(radius, time)

    # Call save on everything, but only dirty strokes will actually write data.
    # Save a key at the previous frame here so that when a stroke starts animating, when linearly
    # interpolated, it will not start animating from frame zero to the first key frame.
    #for s in strokes:
    #  s.Save(time - 1)

    # Update stroke animation.
    remove = []
    for ss in activeSubstrokes:
      print(".", end=' ')
      if not ss.Update(dRadius, smoothstep(1.0, float(numFrames), time)):
        if ss.indicesWritten != ss.indexCount:
          raise "Fail"
        remove.append(ss)
    
    # Remove all the completed strokes.
    for ss in remove:
      activeSubstrokes.remove(ss)
      completeSubstrokes.add(ss)

    # Save keyframes for the current time.
    for s in strokes:
      s.Save(time)

    # Rebuild the activeStrokes set.
    activeStrokes = set()
    for ss in activeSubstrokes:
      activeStrokes.add(ss.stroke)

  # Drainstop: we have leftover strokes that didn't finish animating within the target time, rather
  # than popping them, we let them finish animating and run over the target time.
  while len(activeSubstrokes) > 0:
    remove = []
    time += 1
    # Since we blew past the initial frame estimate, we also need to update the USD end time.
    stage.SetEndTimeCode(time)
    # Loop: update, remove, save, rinse, repeat.
    for ss in activeSubstrokes:
      if not ss.Update(dRadius, 2.0):
        if ss.indicesWritten != ss.indexCount:
          raise "Fail"
        remove.append(ss)
    for ss in remove:
      activeSubstrokes.remove(ss)
      completeSubstrokes.add(ss)
    for s in strokes:
      s.Save(time)
Beispiel #11
0
 def sync_transform_from_prim(self, prim):
     prim_obj = self.id_data
     prim_obj.matrix_local = usd_utils.get_xform_transform(
         UsdGeom.Xform(prim))