# Batch Export from Character Studio
## 10-16-23
- https://github.com/M3-org/character-assets/issues?q=is%3Aissue+is%3Aclosed+archived%3Afalse+reason%3Acompleted
Generated all the manifest.json and named them $id_manifest.json in this zip: https://cdn.discordapp.com/attachments/1041270464271622234/1163308582591275079/female_manifest_json.zip?ex=653f1a8b&is=652ca58b&hm=6284e176678f846b1649b5a73d4267c842e975bba669491c9145c354d222c2a1&
I also generated 800x1356 thumbnails for each, and put into folders in this zip: https://cdn.discordapp.com/attachments/1041270464271622234/1163309952610357338/thumbnails_female.zip?ex=653f1bd1&is=652ca6d1&hm=a8af77c485562349baa00e99bf31ceac30dbb84ad269bd12753b69cf28e148fa&
the scripts I used are being uploaded here: https://github.com/M3-org/anata/tree/main/vrm/scripts
---
## 10-24-23
Need to debug some vertices being glued together in female clothing blend files

### New export script
> I modified the code a bit so it export each glass model with the same armature for each, maybe this scripts is also helpful in your side 🙂 - memelotsqui
```python=!
import bpy
import os
import sys
# REMEMBER TO SET THE EXPORT PATH
export_path = "/home/$USER/Desktop/Exports"
view_layer_name = 'ViewLayer'
view_layer = bpy.context.scene.view_layers.get(view_layer_name)
if view_layer is None:
print(f"View Layer '{view_layer_name}' not found.")
sys.exit(1)
bpy.context.window.view_layer = view_layer
# Get a list of all visible objects in the scene
visible_objects = [obj for obj in bpy.context.scene.objects if obj.parent is None]
# Iterate over each visible object and export it as a separate VRM file
for obj in visible_objects:
# Skip objects not in the specified view layer
if obj.name not in view_layer.objects:
print(f"Object '{obj.name}' is not in view layer '{view_layer_name}'. Skipping.")
continue
# Search for a mesh in the hierarchy of children
mesh = None
for child in obj.children_recursive:
if child.type == 'MESH':
mesh = child
# If a mesh is found and it's in the view layer, select it for export
if mesh and mesh.name in view_layer.objects:
# Set the filename for the exported VRM file
armature = mesh.parent
armature.data.vrm_addon_extension.spec_version = "0.0"
filename = mesh.name + ".vrm"
filepath = os.path.join(export_path, filename)
# Select the mesh for export
bpy.context.view_layer.objects.active = mesh
mesh.select_set(True)
# Export the mesh (VRM)
bpy.ops.export_scene.vrm(
filepath=filepath,
export_invisibles=False,
enable_advanced_preferences=True,
export_fb_ngon_encoding=False,
export_only_selections=True,
armature_object_name=obj.name
)
```
---
## Prepping VRM Folder
First go into `vrm/male` or `vrm/female` and get all the JSON metadata from NFTs into current dir
`find ./ -iname "*.json" -exec cp '{}' . \;`
Now we need to convert the NFT metadata to a more simpler form. Copy convert_json.py from `vrm/scripts` and either the male or female renamed_traits.csv from `metadata/csv` in the Anata repo to current dir. It is a CSV that contains two columns, "Original","Rename".
Running convert_json.py will then copy new files to converted_json folder with the metadata matching the project directory / filename structure. I go into this folder then select / rename everything to be *_renamed.json for organization.
Then bring attributes2.sh from `vrm/scripts` and run in current directory to get simplified JSON per Anata, like below:
```json!=
{ "name": "1", "attributes": [
{
"trait_type": "BODY",
"value": "Masculine"
},
{
"trait_type": "CLOTHING",
"value": "Ragnarok_777_T_Shirt"
},
{
"trait_type": "HAIR",
"value": "Mid_Red-Black"
},
{
"trait_type": "TYPE",
"value": "Ragnarok"
},
{
"trait_type": "GLASSES",
"value": "Modern_Shades"
},
{
"trait_type": "NECK",
"value": "Silver_Links_Chain"
},
{
"trait_type": "BRACE",
"value": "Strobe_Light_Brace"
},
{
"trait_type": "SET",
"value": "Ragnarok"
}
] }
```
I want to get all the preview images into the VRM folders now for male, I'll fetch them from another place in Anata project repo this way (saved as `vrm/scripts/copy_previews.sh`):
```bash!
source_directory1="../../img/0-999"
source_directory2="../../img/1000-2000"
# Loop through the JSON files in the current directory
for json_file in *.json; do
# Extract the filename without the .json extension
filename=$(basename "$json_file" .json)
# Debug: Show the filenames being checked
echo "Checking for $filename.jpg in $source_directory1"
# Check if a corresponding JPEG file exists in the source directory
if [ -e "$source_directory1/$filename.jpg" ]; then
echo "Copying $filename.jpg"
cp "$source_directory1/$filename.jpg" "$filename.jpg"
else
echo "No matching JPEG file found for $filename.json"
fi
echo "Checking for $filename.jpg in $source_directory2"
if [ -e "$source_directory2/$filename.jpg" ]; then
echo "Copying $filename.jpg"
cp "$source_directory2/$filename.jpg" "$filename.jpg"
else
echo "No matching JPEG file found for $filename.json"
fi
done
```
I need to crop them a bit for the UI, using this command to make them the same portrait resolution across the app:
```bash!
mkdir -p output # Create an "output" directory if it doesn't exist
for file in *.jpg; do
output_file="output/t_$file"
convert "$file" -resize 800x1356^ -gravity center -extent 800x1356 "$output_file"
done
```
I want to move all the *_attribute.json files to each folder in `vrm/male`, I mv them from converted_json over to current dir and run this:
```bash!
for file in *_attributes.json; do
folder_name="${file%%_*}" # Extract the numerical value
mv "$file" "$folder_name/"
done
```
## Combine Skin + Eyes
I'm starting with priority Anata first, and all these share the same skin texture so I want to copy the skintone texture to each folder.
```bash!
source_file="/path/to/repo/anata/files/BODY/male_skintone/male_body_6.png"
# Define an array of destination folders
destination_folders=(1161 1183 1192 1297 1505 1524 1558 1562 1645 1736 195 32 338 412 718 867)
# Loop through the destination folders and copy the source file to each one
for folder in "${destination_folders[@]}"; do
cp "$source_file" "$folder"
done
```
Now to combine with eyes, this will 2x eyes resolution to match skin then composite. Just have to run against the folder, it will output skin-eyes_$dirname.png in that folder. Just need tattoos next and it's ready to be used.
```bash!
#!/bin/bash
# Check if an input directory argument is provided
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <input_directory>"
exit 1
fi
input_directory="$1"
# Check if the directory exists
if [ ! -d "$input_directory" ]; then
echo "Error: Directory $input_directory does not exist."
exit 1
fi
# Define the desired resolution
resolution="4096x4096"
# Loop through all images starting with "eyes_" in the input directory
for eyes_image in "$input_directory"/eyes_*.png; do
# Get the basename of the "eyes_" image (e.g., eyes_image.png)
base_eyes_image=$(basename "$eyes_image")
# Extract the filename without the extension (e.g., eyes_image)
eyes_filename="${base_eyes_image%.png}"
# Compose the output filename
output_filename="$input_directory/skin-$eyes_filename.png"
# Use a wildcard to find the male body image (e.g., male_body_*.png)
male_body_image=$(find "$input_directory" -name "male_body_*.png" -print -quit)
# Check if a male body image was found
if [ -n "$male_body_image" ]; then
# Upscale the "eyes_" image to 4096x4096
convert "$eyes_image" -resize "$resolution" temp_eyes.png
# Perform the image operations using the 'composite' command
composite -gravity center temp_eyes.png "$male_body_image" "$output_filename"
# Remove the temporary upscaled "eyes_" image
rm temp_eyes.png
echo "Processed $base_eyes_image"
else
echo "Error: Male body image not found for '$base_eyes_image'. Skipping."
fi
done
```
Can batch convert with this snippet:
```bash!
destination_folders=(1161 1183 1192 1297 1505 1524 1558 1562 1645 1736 195 32 338 412 718 867)
# Loop through the destination folders and copy the source file to each one
for folder in "${destination_folders[@]}"; do
bash combine_skin-eyes.sh "$folder"
done
```




Score