parameters: (action, armature, options)
return_statement: return animation
docstring: :param action:
      :param armature:
      :param options:
function: def _parse_pose_action(action, armature, options):
      """
  
      :param action:
      :param armature:
      :param options:
  
      """
      try:
          current_context = context.area.type
      except AttributeError:
          for window in context.window_manager.windows:
              screen = window.screen
              for area in screen.areas:
                  if area.type != 'VIEW_3D':
                      continue
  
                  override = {
                      'window': window,
                      'screen': screen,
                      'area': area
                  }
                  ops.screen.screen_full_area(override)
                  break
          current_context = context.area.type
  
      context.scene.objects.active = armature
      context.area.type = 'DOPESHEET_EDITOR'
      context.space_data.mode = 'ACTION'
      context.area.spaces.active.action = action
  
      armature_matrix = armature.matrix_world
      fps = context.scene.render.fps
  
      end_frame = action.frame_range[1]
      start_frame = action.frame_range[0]
      frame_length = end_frame - start_frame
  
      frame_step = options.get(constants.FRAME_STEP, 1)
      used_frames = int(frame_length / frame_step) + 1
  
      keys = []
      channels_location = []
      channels_rotation = []
      channels_scale = []
  
      for pose_bone in armature.pose.bones:
          logger.info("Processing channels for %s",
                      pose_bone.bone.name)
          keys.append([])
          channels_location.append(
              _find_channels(action,
                             pose_bone.bone,
                             'location'))
          channels_rotation.append(
              _find_channels(action,
                             pose_bone.bone,
                             'rotation_quaternion'))
          channels_rotation.append(
              _find_channels(action,
                             pose_bone.bone,
                             'rotation_euler'))
          channels_scale.append(
              _find_channels(action,
                             pose_bone.bone,
                             'scale'))
  
      frame_step = options[constants.FRAME_STEP]
      frame_index_as_time = options[constants.FRAME_INDEX_AS_TIME]
      for frame_index in range(0, used_frames):
          if frame_index == used_frames - 1:
              frame = end_frame
          else:
              frame = start_frame + frame_index * frame_step
  
          logger.info("Processing frame %d", frame)
  
          time = frame - start_frame
          if frame_index_as_time is False:
              time = time / fps
  
          context.scene.frame_set(frame)
  
          bone_index = 0
  
          def has_keyframe_at(channels, frame):
              """
  
              :param channels:
              :param frame:
  
              """
              def find_keyframe_at(channel, frame):
                  """
  
                  :param channel:
                  :param frame:
  
                  """
                  for keyframe in channel.keyframe_points:
                      if keyframe.co[0] == frame:
                          return keyframe
                  return None
  
              for channel in channels:
                  if not find_keyframe_at(channel, frame) is None:
                      return True
              return False
  
          for pose_bone in armature.pose.bones:
  
              logger.info("Processing bone %s", pose_bone.bone.name)
              if pose_bone.parent is None:
                  bone_matrix = armature_matrix * pose_bone.matrix
              else:
                  parent_matrix = armature_matrix * pose_bone.parent.matrix
                  bone_matrix = armature_matrix * pose_bone.matrix
                  bone_matrix = parent_matrix.inverted() * bone_matrix
  
              pos, rot, scl = bone_matrix.decompose()
              rot = _normalize_quaternion(rot)
  
              pchange = True or has_keyframe_at(
                  channels_location[bone_index], frame)
              rchange = True or has_keyframe_at(
                  channels_rotation[bone_index], frame)
              schange = True or has_keyframe_at(
                  channels_scale[bone_index], frame)
  
              pos = (pos.x, pos.z, -pos.y)
              rot = (rot.x, rot.z, -rot.y, rot.w)
              scl = (scl.x, scl.z, scl.y)
  
              keyframe = {constants.TIME: time}
              if frame == start_frame or frame == end_frame:
                  keyframe.update({
                      constants.POS: pos,
                      constants.ROT: rot,
                      constants.SCL: scl
                  })
              elif any([pchange, rchange, schange]):
                  if pchange is True:
                      keyframe[constants.POS] = pos
                  if rchange is True:
                      keyframe[constants.ROT] = rot
                  if schange is True:
                      keyframe[constants.SCL] = scl
  
              if len(keyframe.keys()) > 1:
                  logger.info("Recording keyframe data for %s %s",
                              pose_bone.bone.name, str(keyframe))
                  keys[bone_index].append(keyframe)
              else:
                  logger.info("No anim data to record for %s",
                              pose_bone.bone.name)
  
              bone_index += 1
  
      hierarchy = []
      bone_index = 0
      for pose_bone in armature.pose.bones:
          hierarchy.append({
              constants.PARENT: bone_index - 1,
              constants.KEYS: keys[bone_index]
          })
          bone_index += 1
  
      if frame_index_as_time is False:
          frame_length = frame_length / fps
  
      context.scene.frame_set(start_frame)
      context.area.type = current_context
  
      animation = {
          constants.HIERARCHY: hierarchy,
          constants.LENGTH: frame_length,
          constants.FPS: fps,
          constants.NAME: action.name
      }
  
      return animation
function_tokens: def _parse_pose_action ( action , armature , options ) : try : current_context = context . area . type except AttributeError : for window in context . window_manager . windows : screen = window . screen for area in screen . areas : if area . type != 'VIEW_3D' : continue override = { 'window' : window , 'screen' : screen , 'area' : area } ops . screen . screen_full_area ( override ) break current_context = context . area . type context . scene . objects . active = armature context . area . type = 'DOPESHEET_EDITOR' context . space_data . mode = 'ACTION' context . area . spaces . active . action = action armature_matrix = armature . matrix_world fps = context . scene . render . fps end_frame = action . frame_range [ 1 ] start_frame = action . frame_range [ 0 ] frame_length = end_frame - start_frame frame_step = options . get ( constants . FRAME_STEP , 1 ) used_frames = int ( frame_length / frame_step ) + 1 keys = [ ] channels_location = [ ] channels_rotation = [ ] channels_scale = [ ] for pose_bone in armature . pose . bones : logger . info ( "Processing channels for %s" , pose_bone . bone . name ) keys . append ( [ ] ) channels_location . append ( _find_channels ( action , pose_bone . bone , 'location' ) ) channels_rotation . append ( _find_channels ( action , pose_bone . bone , 'rotation_quaternion' ) ) channels_rotation . append ( _find_channels ( action , pose_bone . bone , 'rotation_euler' ) ) channels_scale . append ( _find_channels ( action , pose_bone . bone , 'scale' ) ) frame_step = options [ constants . FRAME_STEP ] frame_index_as_time = options [ constants . FRAME_INDEX_AS_TIME ] for frame_index in range ( 0 , used_frames ) : if frame_index == used_frames - 1 : frame = end_frame else : frame = start_frame + frame_index * frame_step logger . info ( "Processing frame %d" , frame ) time = frame - start_frame if frame_index_as_time is False : time = time / fps context . scene . frame_set ( frame ) bone_index = 0 def has_keyframe_at ( channels , frame ) : """
  
              :param channels:
              :param frame:
  
              """ def find_keyframe_at ( channel , frame ) : """
  
                  :param channel:
                  :param frame:
  
                  """ for keyframe in channel . keyframe_points : if keyframe . co [ 0 ] == frame : return keyframe return None for channel in channels : if not find_keyframe_at ( channel , frame ) is None : return True return False for pose_bone in armature . pose . bones : logger . info ( "Processing bone %s" , pose_bone . bone . name ) if pose_bone . parent is None : bone_matrix = armature_matrix * pose_bone . matrix else : parent_matrix = armature_matrix * pose_bone . parent . matrix bone_matrix = armature_matrix * pose_bone . matrix bone_matrix = parent_matrix . inverted ( ) * bone_matrix pos , rot , scl = bone_matrix . decompose ( ) rot = _normalize_quaternion ( rot ) pchange = True or has_keyframe_at ( channels_location [ bone_index ] , frame ) rchange = True or has_keyframe_at ( channels_rotation [ bone_index ] , frame ) schange = True or has_keyframe_at ( channels_scale [ bone_index ] , frame ) pos = ( pos . x , pos . z , - pos . y ) rot = ( rot . x , rot . z , - rot . y , rot . w ) scl = ( scl . x , scl . z , scl . y ) keyframe = { constants . TIME : time } if frame == start_frame or frame == end_frame : keyframe . update ( { constants . POS : pos , constants . ROT : rot , constants . SCL : scl } ) elif any ( [ pchange , rchange , schange ] ) : if pchange is True : keyframe [ constants . POS ] = pos if rchange is True : keyframe [ constants . ROT ] = rot if schange is True : keyframe [ constants . SCL ] = scl if len ( keyframe . keys ( ) ) > 1 : logger . info ( "Recording keyframe data for %s %s" , pose_bone . bone . name , str ( keyframe ) ) keys [ bone_index ] . append ( keyframe ) else : logger . info ( "No anim data to record for %s" , pose_bone . bone . name ) bone_index += 1 hierarchy = [ ] bone_index = 0 for pose_bone in armature . pose . bones : hierarchy . append ( { constants . PARENT : bone_index - 1 , constants . KEYS : keys [ bone_index ] } ) bone_index += 1 if frame_index_as_time is False : frame_length = frame_length / fps context . scene . frame_set ( start_frame ) context . area . type = current_context animation = { constants . HIERARCHY : hierarchy , constants . LENGTH : frame_length , constants . FPS : fps , constants . NAME : action . name } return animation