<commit_before># For this script to work, you must first install the FBX SKD Python bindings
# Make sure your python version is supported by the bindings as well

import sys
import zipfile
import os
import io
from collections import namedtuple

FBXNode = namedtuple('FBXNode', 'name parent node')
ACLClip = namedtuple('ACLClip', 'name num_samples sample_rate error_threshold duration')
ACLBone = namedtuple('ACLBone', 'name parent vtx_distance obj_space_mtx bind_rotation bind_translation bind_scale')
ACLTrack = namedtuple('ACLTrack', 'name rotations translations scales')

ACL_FILE_FORMAT_VERSION = 1

def print_animation_stacks(scene):
	for i in range(scene.GetSrcObjectCount(FbxAnimStack.ClassId)):
		print('  "' + scene.GetSrcObject(FbxAnimStack.ClassId, i).GetName() + '"')

def get_animation_stack(scene, anim_stack_name):
	num_stacks = scene.GetSrcObjectCount(FbxAnimStack.ClassId)
	if num_stacks == 1:
		anim_stack = scene.GetSrcObject(FbxAnimStack.ClassId, 0)
		if len(anim_stack_name) > 0 and anim_stack_name != anim_stack.GetName():
			print('There is one animation stack, but it\'s called "' + anim_stack.GetName() + '".  Consider omitting the -stack option.')
			sys.exit(1)
	else:
		if len(anim_stack_name) == 0:
			print('You must provide the -stack="<animation stack name>" option for one of these:')
			print_animation_stacks(scene)
			sys.exit(1)
		
		found = False
		for i in range(scene.GetSrcObjectCount(FbxAnimStack.ClassId)):
			anim_stack = scene.GetSrcObject(FbxAnimStack.ClassId, i)
			if anim_stack.GetName() == anim_stack_name:
				found = True
				break
	
		if not found:
			print('Could not find the animation stack named "' + anim_stack_name + '"')
			print('Choose one of the following instead:')
			print_animation_stacks(scene)
			sys.exit(1)
	
	return anim_stack

def parse_clip(scene, anim_stack):
	clip_name = anim_stack.GetName()
	timespan = anim_stack.GetLocalTimeSpan()
	sample_rate = int(FbxTime.GetFrameRate(scene.GetGlobalSettings().GetTimeMode()))
	duration = timespan.GetDuration().GetFramedTime(False).GetSecondDouble()
	num_samples = int(duration * sample_rate) + 1
	error_threshold = 0.01

	return ACLClip(clip_name, num_samples, sample_rate, error_threshold, duration)

def parse_hierarchy(scene):
	nodes = []

	root_node = scene.GetRootNode()
	nodes.append(FBXNode(root_node.GetName(), "", root_node))

	for i in range(root_node.GetChildCount()):
		parse_hierarchy_node(root_node, root_node.GetChild(i), nodes)

	return nodes

def parse_hierarchy_node(parent_node, node, nodes):
	type = (node.GetNodeAttribute().GetAttributeType())
	if type != FbxNodeAttribute.eSkeleton:
		print('Ignoring node ' + node.GetName())
		return
	
	nodes.append(FBXNode(node.GetName(), parent_node.GetName(), node))

	for i in range(node.GetChildCount()):
		parse_hierarchy_node(node, node.GetChild(i), nodes)

def vector3_to_array(vec):
	return [ vec[0], vec[1], vec[2] ]
<commit_msg>Make sure to round and not truncate.<commit_after># For this script to work, you must first install the FBX SKD Python bindings
# Make sure your python version is supported by the bindings as well

import sys
import zipfile
import os
import io
from collections import namedtuple

FBXNode = namedtuple('FBXNode', 'name parent node')
ACLClip = namedtuple('ACLClip', 'name num_samples sample_rate error_threshold duration')
ACLBone = namedtuple('ACLBone', 'name parent vtx_distance obj_space_mtx bind_rotation bind_translation bind_scale')
ACLTrack = namedtuple('ACLTrack', 'name rotations translations scales')

ACL_FILE_FORMAT_VERSION = 1

def print_animation_stacks(scene):
	for i in range(scene.GetSrcObjectCount(FbxAnimStack.ClassId)):
		print('  "' + scene.GetSrcObject(FbxAnimStack.ClassId, i).GetName() + '"')

def get_animation_stack(scene, anim_stack_name):
	num_stacks = scene.GetSrcObjectCount(FbxAnimStack.ClassId)
	if num_stacks == 1:
		anim_stack = scene.GetSrcObject(FbxAnimStack.ClassId, 0)
		if len(anim_stack_name) > 0 and anim_stack_name != anim_stack.GetName():
			print('There is one animation stack, but it\'s called "' + anim_stack.GetName() + '".  Consider omitting the -stack option.')
			sys.exit(1)
	else:
		if len(anim_stack_name) == 0:
			print('You must provide the -stack="<animation stack name>" option for one of these:')
			print_animation_stacks(scene)
			sys.exit(1)
		
		found = False
		for i in range(scene.GetSrcObjectCount(FbxAnimStack.ClassId)):
			anim_stack = scene.GetSrcObject(FbxAnimStack.ClassId, i)
			if anim_stack.GetName() == anim_stack_name:
				found = True
				break
	
		if not found:
			print('Could not find the animation stack named "' + anim_stack_name + '"')
			print('Choose one of the following instead:')
			print_animation_stacks(scene)
			sys.exit(1)
	
	return anim_stack

def parse_clip(scene, anim_stack):
	clip_name = anim_stack.GetName()
	timespan = anim_stack.GetLocalTimeSpan()
	sample_rate = int(FbxTime.GetFrameRate(scene.GetGlobalSettings().GetTimeMode()) + 0.5)
	duration = timespan.GetDuration().GetFramedTime(False).GetSecondDouble()
	num_samples = int((duration * sample_rate) + 0.5) + 1
	error_threshold = 0.01

	return ACLClip(clip_name, num_samples, sample_rate, error_threshold, duration)

def parse_hierarchy(scene):
	nodes = []

	root_node = scene.GetRootNode()
	nodes.append(FBXNode(root_node.GetName(), "", root_node))

	for i in range(root_node.GetChildCount()):
		parse_hierarchy_node(root_node, root_node.GetChild(i), nodes)

	return nodes

def parse_hierarchy_node(parent_node, node, nodes):
	type = (node.GetNodeAttribute().GetAttributeType())
	if type != FbxNodeAttribute.eSkeleton:
		print('Ignoring node ' + node.GetName())
		return
	
	nodes.append(FBXNode(node.GetName(), parent_node.GetName(), node))

	for i in range(node.GetChildCount()):
		parse_hierarchy_node(node, node.GetChild(i), nodes)

def vector3_to_array(vec):
	return [ vec[0], vec[1], vec[2] ]

{'fraction_non_alphanumeric': 0.11270247229326513, 'fraction_numerical': 0.006138107416879796, 'mean_word_length': 5.650793650793651, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '889763', 'n_tokens_mistral': 2092, 'n_tokens_neox': 1933, 'n_words': 470}