Skip to content

コア技術 ​

OpenFitterで使用されている主要な技術とアルゴリズムについて説明します。

概要 ​

OpenFitterは、3Dアバター間での衣装フィッティングを実現するために、複数の技術を組み合わせています。Unity Editor拡張としてのフロントエンドと、Blenderをバックエンドとして使用する処理エンジンで構成されています。

フィッティングアルゴリズム ​

RBF(放射基底関数)変形 ​

コアフィッティングアルゴリズムは RBF(Radial Basis Function)変形 を使用しています。

RBFとは ​

RBFは、限られた制御点から滑らかな変形を生成する数学的手法です。以下のような特徴があります:

  • 局所的な影響: 各制御点は周囲の領域に主に影響を与えます
  • 滑らかな補間: 制御点間の変形が自然で滑らかです
  • 非線形変形: 複雑な体型の違いにも対応できます

フィッティングプロセスでの使用 ​

  1. 制御点の設定: ソースとターゲットのボーン位置を制御点として使用
  2. RBF計算: ソースからターゲットへの変形を計算
  3. メッシュ変形: 衣装メッシュの各頂点にRBF変形を適用

ボーンポーズ転送 ​

アバター間でボーンの姿勢(ポーズ)を転送します。

プロセス ​

  1. ボーンマッピング: ソースとターゲットのボーン構造を対応付け
  2. ポーズ抽出: ソースアバターのボーンポーズを抽出
  3. ポーズ適用: ターゲットアバターにポーズを適用
  4. ウェイト転送: スキニングウェイトを適切に転送

メッシュトポロジーの保持 ​

フィッティング後もメッシュの基本構造を維持します:

  • 頂点順序: 元の頂点順序を保持
  • ポリゴン構造: ポリゴンの接続関係を維持
  • UV座標: テクスチャ座標を保持
  • マテリアル: マテリアル割り当てを維持

Blender統合 ​

Blenderをバックエンドとして使用する理由 ​

OpenFitterはBlenderを3D処理エンジンとして使用しています:

  • 強力な3D処理: Blenderの成熟した3D処理機能を活用
  • Pythonスクリプティング: 柔軟な自動化が可能
  • GPL-3コードの互換性: open-fitter-coreのコードをそのまま使用可能
  • オープンソース: 無料で再配布可能

ポータブルBlender ​

ユーザーの既存環境に影響を与えないよう、ポータブル版のBlenderを使用:

  • 独立したインストール: システムのBlenderと干渉しない
  • 自動ダウンロード: 初回セットアップ時に自動取得
  • バージョン管理: 特定のバージョンを使用して互換性を保証

Pythonラッパースクリプト ​

Unity(C#)とBlender(Python)間の橋渡しを行います:

openfitter_wrapper.py ​

メインのラッパースクリプト:

python
# コマンドライン引数からパラメータを受け取る
# open-fitter-coreのフィッティング関数を呼び出す
# 進捗情報を標準出力に出力
# 結果をファイルに保存

check_addon_status.py ​

アドオンのインストール状態を確認:

python
# Blenderアドオンが正しくインストールされているか確認
# バージョン情報を取得
# 結果をJSON形式で出力

install_addon_dependencies.py ​

アドオンの依存関係をインストール:

python
# pipを使用して必要なPythonパッケージをインストール
# Blenderの内蔵Python環境にインストール
# インストール結果を報告

コマンドライン実行 ​

UnityからBlenderをコマンドラインで起動:

bash
blender.exe --background --python openfitter_wrapper.py -- [arguments]
  • --background: UIなしのバックグラウンドモード
  • --python: 実行するPythonスクリプト
  • --: 以降の引数をスクリプトに渡す

OpenFitterCore パラメータ ​

Blenderバックエンド(openfitter_wrapper.pyを介したコアスクリプト)が受け取る主要な引数は以下の通りです。

引数形式必須説明
--inputパスYES入力となる衣装FBXの絶対パス。
--outputパスYES出力先FBXの絶対パス。
--baseパスYES基準となる .blend ファイルのパス。
--base-fbxパスリストYESベースキャラクターのFBXパス。複数ある場合は ; で区切ります。
--configパスリストYES設定JSONのパス。複数ある場合は ; で区切ります。
--init-poseパスYES初期ポーズ情報のJSONパス。
--hips-position文字列NOHipsボーンの位置指定。
--blend-shapes文字列リストNO適用するブレンドシェイプ名のリスト(; 区切り)。
--blend-shape-values数値リストNO各ブレンドシェイプの適用値(; 区切り)。
--blend-shape-mappings文字列リストNOブレンドシェイプのマッピング定義。
--target-meshes文字列リストNO処理対象とするメッシュ名のリスト。
--mesh-renderers文字列リストNOメッシュレンダラーの対応設定。
--name-conv文字列リストNO名称変換ルールのリスト。
--preserve-bone-namesフラグNOボーン名を維持するかどうかの指定。
--no-subdivisionフラグNOメッシュの自動細分化を無効にします。
--no-triangleフラグNO三角面化を無効にします。

Unity Editor統合 ​

UIToolkit ​

モダンなUI開発フレームワークを使用:

UXML(UIレイアウト) ​

XMLベースのレイアウト記述:

xml
<ui:UXML>
    <ui:VisualElement class="step-container">
        <ui:Label text="Source Selection" class="step-title"/>
        <ui:ObjectField name="source-field" type="UnityEngine.GameObject"/>
    </ui:VisualElement>
</ui:UXML>

USS(スタイル) ​

CSSライクなスタイリング:

css
.step-container {
    padding: 10px;
    margin: 5px;
}

.step-title {
    font-size: 16px;
    -unity-font-style: bold;
}

C#バインディング ​

C#からUIを操作:

csharp
var sourceField = rootElement.Q<ObjectField>("source-field");
sourceField.RegisterValueChangedCallback(evt => {
    // 値変更時の処理
});

非同期処理 ​

長時間実行される操作には非同期処理を使用:

csharp
public async Task<bool> ExecuteFittingAsync()
{
    await Task.Run(() => {
        // Blenderプロセスの実行
    });
    return true;
}

進捗パーシング ​

Blenderからの出力をパースして進捗を表示:

csharp
public class FittingProgressParser
{
    public void ParseLine(string line)
    {
        // "PROGRESS: 50%" のような出力をパース
        // 進捗イベントを発火
    }
}

データ形式 ​

FBXフォーマット ​

入出力に使用する3Dモデルフォーマット:

  • 互換性: 多くの3Dツールでサポート
  • 完全な情報: メッシュ、ボーン、アニメーション、マテリアルを含む
  • Unity統合: Unityのネイティブサポート

JSON設定ファイル ​

フィッティング設定の保存:

json
{
  "sourceAvatar": "Assets/Avatars/Source.fbx",
  "targetAvatar": "Assets/Avatars/Target.fbx",
  "blendShapes": [
    {"name": "vrc.blink_left", "preserve": true},
    {"name": "vrc.blink_right", "preserve": true}
  ]
}

MochiFitterデータ互換性 ​

MochiFitterのデータフォーマットに準拠:

  • 設定ファイル: 同じJSON構造を使用
  • 出力形式: 互換性のあるFBX出力
  • ブレンドシェイプ命名: VRChat標準に準拠

最適化技術 ​

並列処理 ​

複数のタスクを並列実行:

csharp
var tasks = new List<Task<SetupResult>>
{
    downloadBlenderTask,
    downloadCoreTask,
    downloadAddonTask
};

await Task.WhenAll(tasks);

キャッシング ​

ダウンロードしたファイルをキャッシュ:

  • ローカルキャッシュ: BlenderTools/ディレクトリに保存
  • バージョンチェック: ファイルが最新か確認
  • 再利用: 既にダウンロード済みの場合はスキップ

メモリ管理 ​

大きなメッシュデータの効率的な処理:

  • ストリーミング: ファイルをストリーミングで読み込み
  • 早期解放: 不要になったデータは即座に解放
  • プロセス分離: Blenderを別プロセスで実行してUnityのメモリ使用を抑制

セキュリティ ​

サンドボックス化 ​

Blenderプロセスを制限:

  • 別プロセス: Unityとは独立したプロセスで実行
  • 作業ディレクトリ制限: 特定のディレクトリ内でのみ動作
  • タイムアウト: 長時間実行をタイムアウトで制限

入力検証 ​

ユーザー入力の検証:

csharp
public bool ValidateSourceAvatar(GameObject avatar)
{
    if (avatar == null) return false;
    if (!HasValidMesh(avatar)) return false;
    if (!HasValidArmature(avatar)) return false;
    return true;
}

国際化(i18n) ​

ローカリゼーションシステム ​

多言語サポート:

csharp
public static class I18n
{
    public static string Get(string key)
    {
        // 現在の言語設定に基づいて文字列を取得
        return translations[currentLanguage][key];
    }
}

サポート言語 ​

  • 日本語
  • 英語

テスト技術 ​

Unity Test Framework ​

ユニットテストとインテグレーションテスト:

csharp
[Test]
public void TestSourceSelection()
{
    var presenter = new SourceSelectionStepPresenter(mockView, state);
    presenter.OnSourceSelected(testAvatar);
    Assert.AreEqual(testAvatar, state.Config.SourceAvatar);
}

モックオブジェクト ​

テスト用のモック実装:

csharp
public class MockWizardView : IWizardView
{
    public bool NextButtonWasCalled { get; private set; }

    public void ShowNextButton()
    {
        NextButtonWasCalled = true;
    }
}

ビルドとデプロイ ​

TypeScriptビルドスクリプト ​

Node.jsとTypeScriptでビルドツールを作成:

typescript
// create-unitypackage.ts
import * as fs from 'fs';
import * as path from 'path';

async function createUnityPackage() {
    // Unityパッケージを作成する処理
}

VitePressドキュメント ​

ドキュメントサイトの生成:

bash
npm run docs:build
# docs/.vitepress/dist/にビルド結果が生成される

まとめ ​

OpenFitterは以下の技術を組み合わせて実現されています:

  • RBF変形: 滑らかで自然な衣装フィッティング
  • Blender統合: 強力な3D処理エンジン
  • Unity Editor拡張: ユーザーフレンドリーなインターフェース
  • 非同期処理: レスポンシブなユーザー体験
  • モジュラー設計: 保守しやすく拡張可能な構造

これらの技術により、高品質な自動衣装フィッティングを実現しています。


English ​

Core Technology ​

This document explains the key technologies and algorithms used in OpenFitter.

Overview ​

OpenFitter combines multiple technologies to achieve clothing fitting between 3D avatars. It consists of a frontend as a Unity Editor extension and a processing engine using Blender as a backend.

Fitting Algorithm ​

RBF (Radial Basis Function) Deformation ​

The core fitting algorithm uses RBF (Radial Basis Function) deformation.

What is RBF ​

RBF is a mathematical technique that generates smooth deformation from limited control points. It has the following characteristics:

  • Local Influence: Each control point primarily affects its surrounding area
  • Smooth Interpolation: Deformation between control points is natural and smooth
  • Nonlinear Deformation: Can handle complex body shape differences

Use in Fitting Process ​

  1. Control Point Setup: Use bone positions of source and target as control points
  2. RBF Calculation: Calculate deformation from source to target
  3. Mesh Deformation: Apply RBF deformation to each vertex of clothing mesh

Bone Pose Transfer ​

Transfers bone pose between avatars.

Process ​

  1. Bone Mapping: Map bone structures between source and target
  2. Pose Extraction: Extract bone pose from source avatar
  3. Pose Application: Apply pose to target avatar
  4. Weight Transfer: Appropriately transfer skinning weights

Mesh Topology Preservation ​

Maintains basic mesh structure after fitting:

  • Vertex Order: Preserves original vertex order
  • Polygon Structure: Maintains polygon connectivity
  • UV Coordinates: Preserves texture coordinates
  • Materials: Maintains material assignments

Blender Integration ​

Why Use Blender as Backend ​

OpenFitter uses Blender as its 3D processing engine:

  • Powerful 3D Processing: Leverages Blender's mature 3D processing capabilities
  • Python Scripting: Enables flexible automation
  • GPL-3 Code Compatibility: Can use open-fitter-core code directly
  • Open Source: Free and redistributable

Portable Blender ​

Uses portable version of Blender to avoid affecting user's existing environment:

  • Independent Installation: Doesn't interfere with system Blender
  • Automatic Download: Automatically retrieved during initial setup
  • Version Management: Uses specific version to ensure compatibility

Python Wrapper Scripts ​

Bridges between Unity (C#) and Blender (Python):

openfitter_wrapper.py ​

Main wrapper script:

python
# Receive parameters from command line arguments
# Call fitting function of open-fitter-core
# Output progress information to stdout
# Save results to file

check_addon_status.py ​

Check add-on installation status:

python
# Check if Blender add-on is correctly installed
# Get version information
# Output results in JSON format

install_addon_dependencies.py ​

Install add-on dependencies:

python
# Install required Python packages using pip
# Install into Blender's built-in Python environment
# Report installation results

Command Line Execution ​

Launch Blender from Unity via command line:

bash
blender.exe --background --python openfitter_wrapper.py -- [arguments]
  • --background: Background mode without UI
  • --python: Python script to execute
  • --: Pass subsequent arguments to script

OpenFitterCore Parameters ​

The primary arguments accepted by the Blender backend (the core script via openfitter_wrapper.py) are as follows:

ArgumentFormatRequiredDescription
--inputPathYESAbsolute path to the input clothing FBX.
--outputPathYESAbsolute path to the output FBX.
--basePathYESPath to the base .blend file.
--base-fbxPath ListYESPath to the base character FBX. Semicolon-separated if multiple.
--configPath ListYESPath to the config JSON. Semicolon-separated if multiple.
--init-posePathYESPath to the initial pose JSON.
--hips-positionStringNOSpecifies the Hips bone position.
--blend-shapesString ListNOList of blend shape names to apply (semicolon-separated).
--blend-shape-valuesValue ListNOApplication values for each blend shape (semicolon-separated).
--blend-shape-mappingsString ListNOBlend shape mapping definitions.
--target-meshesString ListNOList of mesh names to be processed.
--mesh-renderersString ListNOMesh renderer correspondence settings.
--name-convString ListNOList of name conversion rules.
--preserve-bone-namesFlagNOSpecifies whether to preserve bone names.
--no-subdivisionFlagNODisables automatic mesh subdivision.
--no-triangleFlagNODisables triangulation.

Unity Editor Integration ​

UIToolkit ​

Uses modern UI development framework:

UXML (UI Layout) ​

XML-based layout description:

xml
<ui:UXML>
    <ui:VisualElement class="step-container">
        <ui:Label text="Source Selection" class="step-title"/>
        <ui:ObjectField name="source-field" type="UnityEngine.GameObject"/>
    </ui:VisualElement>
</ui:UXML>

USS (Styles) ​

CSS-like styling:

css
.step-container {
    padding: 10px;
    margin: 5px;
}

.step-title {
    font-size: 16px;
    -unity-font-style: bold;
}

C# Binding ​

Manipulate UI from C#:

csharp
var sourceField = rootElement.Q<ObjectField>("source-field");
sourceField.RegisterValueChangedCallback(evt => {
    // Handle value change
});

Asynchronous Processing ​

Uses asynchronous processing for long-running operations:

csharp
public async Task<bool> ExecuteFittingAsync()
{
    await Task.Run(() => {
        // Execute Blender process
    });
    return true;
}

Progress Parsing ​

Parse output from Blender to display progress:

csharp
public class FittingProgressParser
{
    public void ParseLine(string line)
    {
        // Parse output like "PROGRESS: 50%"
        // Fire progress event
    }
}

Data Formats ​

FBX Format ​

3D model format used for input/output:

  • Compatibility: Supported by many 3D tools
  • Complete Information: Includes mesh, bones, animations, materials
  • Unity Integration: Native Unity support

JSON Configuration Files ​

Save fitting configuration:

json
{
  "sourceAvatar": "Assets/Avatars/Source.fbx",
  "targetAvatar": "Assets/Avatars/Target.fbx",
  "blendShapes": [
    {"name": "vrc.blink_left", "preserve": true},
    {"name": "vrc.blink_right", "preserve": true}
  ]
}

MochiFitter Data Compatibility ​

Complies with MochiFitter data format:

  • Configuration Files: Uses same JSON structure
  • Output Format: Compatible FBX output
  • Blendshape Naming: Complies with VRChat standards

Optimization Techniques ​

Parallel Processing ​

Execute multiple tasks in parallel:

csharp
var tasks = new List<Task<SetupResult>>
{
    downloadBlenderTask,
    downloadCoreTask,
    downloadAddonTask
};

await Task.WhenAll(tasks);

Caching ​

Cache downloaded files:

  • Local Cache: Saved in BlenderTools/ directory
  • Version Check: Verify if files are up-to-date
  • Reuse: Skip if already downloaded

Memory Management ​

Efficient processing of large mesh data:

  • Streaming: Stream file loading
  • Early Release: Immediately release unnecessary data
  • Process Separation: Run Blender in separate process to reduce Unity memory usage

Security ​

Sandboxing ​

Restrict Blender process:

  • Separate Process: Runs independently from Unity
  • Working Directory Restriction: Operates only within specific directory
  • Timeout: Limit long-running execution with timeout

Input Validation ​

Validate user input:

csharp
public bool ValidateSourceAvatar(GameObject avatar)
{
    if (avatar == null) return false;
    if (!HasValidMesh(avatar)) return false;
    if (!HasValidArmature(avatar)) return false;
    return true;
}

Internationalization (i18n) ​

Localization System ​

Multi-language support:

csharp
public static class I18n
{
    public static string Get(string key)
    {
        // Get string based on current language setting
        return translations[currentLanguage][key];
    }
}

Supported Languages ​

  • Japanese
  • English

Testing Technologies ​

Unity Test Framework ​

Unit tests and integration tests:

csharp
[Test]
public void TestSourceSelection()
{
    var presenter = new SourceSelectionStepPresenter(mockView, state);
    presenter.OnSourceSelected(testAvatar);
    Assert.AreEqual(testAvatar, state.Config.SourceAvatar);
}

Mock Objects ​

Mock implementations for testing:

csharp
public class MockWizardView : IWizardView
{
    public bool NextButtonWasCalled { get; private set; }

    public void ShowNextButton()
    {
        NextButtonWasCalled = true;
    }
}

Build and Deploy ​

TypeScript Build Scripts ​

Create build tools with Node.js and TypeScript:

typescript
// create-unitypackage.ts
import * as fs from 'fs';
import * as path from 'path';

async function createUnityPackage() {
    // Process to create Unity package
}

VitePress Documentation ​

Generate documentation site:

bash
npm run docs:build
# Build results generated in docs/.vitepress/dist/

Summary ​

OpenFitter is realized by combining the following technologies:

  • RBF Deformation: Smooth and natural clothing fitting
  • Blender Integration: Powerful 3D processing engine
  • Unity Editor Extension: User-friendly interface
  • Asynchronous Processing: Responsive user experience
  • Modular Design: Maintainable and extensible structure

These technologies enable high-quality automatic clothing fitting.