了解した。
ここからは DB が唯一の真実であり、
combo / combo_sub を上位キーとして 2000 プロジェクトを扱える MeshDB を
OS 設計として正しく構築する。
あなたの OS 思想(階層・分離・責務の明確化)に完全に沿うように、
combo(最大100) × combo_sub(最大20)=2000 プロジェクト
を自然に扱えるスキーマを提示する。
🧩 1. なぜ combo / combo_sub を上位に置くべきか
あなたの OS では:
- combo = 大分類(プロジェクトの「世界」)
- combo_sub = 中分類(プロジェクトの「章」)
- mesh_id = その中の個別メッシュ
という階層構造が自然。
つまり、
combo / combo_sub が “プロジェクト空間” を定義し、
その中に Mesh / Face / Vertex が存在する
という構造が最も OS 的に正しい。
🧩 2. 最小構成の MySQL スキーマ(combo / combo_sub 上位版)
H2: meshes(メッシュ本体)
meshes (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL, -- 0〜99
combo_sub INT NOT NULL, -- 0〜19
name VARCHAR(255),
parent_id BIGINT NULL, -- 階層メッシュ or LinkNode
created_at DATETIME,
updated_at DATETIME
);
✔ combo / combo_sub が上位キー
✔ 2000 プロジェクトを自然に扱える
✔ MeshNode / LinkNode の階層構造も parent_id で表現可能
H2: vertices(頂点)
vertices (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
mesh_id BIGINT NOT NULL,
x DOUBLE,
y DOUBLE,
z DOUBLE
);
✔ combo / combo_sub を持つことで「プロジェクト空間」に属する
✔ mesh_id とセットで完全に一意な頂点集合になる
H2: faces(三角面)
faces (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
mesh_id BIGINT NOT NULL,
v1_id BIGINT NOT NULL,
v2_id BIGINT NOT NULL,
v3_id BIGINT NOT NULL
);
✔ combo / combo_sub を持つことで「プロジェクト空間」に属する
✔ mesh_id に属する三角面
H2: instances(LinkNode)
instances (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
mesh_id BIGINT NOT NULL, -- 参照先メッシュ
parent_id BIGINT NULL, -- 配置先メッシュ
tx DOUBLE,
ty DOUBLE,
tz DOUBLE,
rx DOUBLE,
ry DOUBLE,
rz DOUBLE,
sx DOUBLE,
sy DOUBLE,
sz DOUBLE
);
✔ combo / combo_sub に属するインスタンス
✔ Three.js はこれを InstancedMesh として描画
H2: face_groups(選択結果)
face_groups (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
name VARCHAR(255)
);
face_group_items (
group_id BIGINT,
face_id BIGINT
);
✔ DSL の groupA / groupB を保持
✔ BFS や SHAPE 選択の結果を格納
✔ extractMeshFromFaces の入力になる
🧩 3. combo / combo_sub を上位に置くメリット
✔ 2000 プロジェクトを完全に分離できる
✔ Mesh / Face / Vertex が「プロジェクト空間」に属する
✔ DSL の実行時に combo / combo_sub を自動で付与できる
✔ Three.js は combo / combo_sub を指定して DB を読むだけ
✔ Flask は combo / combo_sub をキーにして安全に DML を実行できる
✔ OS 的に「プロセス空間」が明確になる
あなたの OS 設計(階層・分離・責務の明確化)に完全一致する。
🧩 4. extractMeshFromFaces は DB DML としてこうなる
combo / combo_sub を含めた形で:
INSERT INTO meshes (combo, combo_sub, name, parent_id)
VALUES (:combo, :combo_sub, 'part1', NULL);
SET @new_mesh_id = LAST_INSERT_ID();
頂点コピー:
INSERT INTO vertices (combo, combo_sub, mesh_id, x, y, z)
SELECT :combo, :combo_sub, @new_mesh_id, x, y, z
FROM vertices
WHERE id IN ( ...face に含まれる頂点... );
面コピー:
INSERT INTO faces (combo, combo_sub, mesh_id, v1_id, v2_id, v3_id)
VALUES (... old_to_new_vid マッピング ...);
✔ すべて combo / combo_sub を持つ
✔ プロジェクト空間内で完結する
✔ Three.js は new_mesh_id を読み込むだけ
🧩 5. 次にやるべきこと(あなたへの提案)
combo / combo_sub を上位に置いたので、
次に OS として決めるべきは:
① DSL に combo / combo_sub をどう反映させるか
- DSL 内に combo を書かせる?
- それとも Flask がセッションで保持する?
② LinkNode(instances)の扱い
- combo / combo_sub を持つ
- 参照先 mesh_id は同じ combo 内に限定する?
③ Three.js の API
/mesh/{combo}/{combo_sub}/{mesh_id}/instances/{combo}/{combo_sub}
など
次は DSL に combo / combo_sub をどう扱わせるか を決めると、
OS 全体が一気に完成形に近づくよ。
了解。
combo=i、combo_sub=j を「編集中のプロジェクト空間」として Flask と Three.js の両方で共有するという前提なら、
DB スキーマは combo / combo_sub を最上位キーとして持つだけで十分で、
アプリ側は常に「現在の i, j を使う」だけで OS として破綻しない。
つまり:
- DB は combo / combo_sub を持つ
- Flask は i, j をセッション or DSL 実行コンテキストで保持
- Three.js は i, j を API パラメータとして送る
これで 2000 プロジェクト空間が自然に扱える。
以下に 最小構成の MeshDB(combo / combo_sub 上位版) をまとめる。
🗂 MeshDB(combo / combo_sub 上位の最小スキーマ)
1. meshes(メッシュ本体)
meshes (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL, -- i
combo_sub INT NOT NULL, -- j
name VARCHAR(255),
parent_id BIGINT NULL, -- 階層メッシュ or LinkNode
created_at DATETIME,
updated_at DATETIME
);
役割
- combo / combo_sub が プロジェクト空間
- parent_id で階層構造(MeshNode / LinkNode)を表現
2. vertices(頂点)
vertices (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
mesh_id BIGINT NOT NULL,
x DOUBLE,
y DOUBLE,
z DOUBLE
);
役割
- 頂点は combo=i, combo_sub=j の空間に属する
- mesh_id とセットで完全に一意
3. faces(三角面)
faces (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
mesh_id BIGINT NOT NULL,
v1_id BIGINT NOT NULL,
v2_id BIGINT NOT NULL,
v3_id BIGINT NOT NULL
);
役割
- 面も combo=i, combo_sub=j に属する
- 頂点は vertices.id を参照
4. instances(LinkNode)
instances (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
mesh_id BIGINT NOT NULL, -- 参照先メッシュ
parent_id BIGINT NULL, -- 配置先メッシュ
tx DOUBLE,
ty DOUBLE,
tz DOUBLE,
rx DOUBLE,
ry DOUBLE,
rz DOUBLE,
sx DOUBLE,
sy DOUBLE,
sz DOUBLE
);
役割
- LinkNode(InstanceMesh)
- combo=i, combo_sub=j の空間に属する
5. face_groups(選択結果)
face_groups (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
combo INT NOT NULL,
combo_sub INT NOT NULL,
name VARCHAR(255)
);
face_group_items (
group_id BIGINT,
face_id BIGINT
);
役割
- DSL の groupA / groupB を保持
- BFS や SHAPE 選択の結果を格納
- extractMeshFromFaces の入力になる
🧩 combo=i, combo_sub=j をどう扱うか(OS 的に正しい方法)
あなたの方針:
編集中の combo は i、combo_sub は j に入れるのを慣行とする
js側とpython側で合わせておけば良いだけ
これは OS 的に非常に正しい。
✔ Flask 側
- DSL 実行コンテキストに
i, jを保持 - すべての INSERT / SELECT / UPDATE / DELETE に自動付与
✔ Three.js 側
- API 呼び出し時に
i, jを付ける
例:/mesh/get?combo=i&combo_sub=j&mesh_id=123
✔ DB 側
- combo / combo_sub を最上位キーとして持つだけでよい
- 2000 プロジェクト空間が完全に分離される
🧩 extractMeshFromFaces は DB DML としてこうなる
combo=i, combo_sub=j を自動付与した形:
INSERT INTO meshes (combo, combo_sub, name, parent_id)
VALUES (:i, :j, 'part1', NULL);
SET @new_mesh_id = LAST_INSERT_ID();
頂点コピー:
INSERT INTO vertices (combo, combo_sub, mesh_id, x, y, z)
SELECT :i, :j, @new_mesh_id, x, y, z
FROM vertices
WHERE id IN ( ...face に含まれる頂点... );
面コピー:
INSERT INTO faces (combo, combo_sub, mesh_id, v1_id, v2_id, v3_id)
VALUES (... old_to_new_vid マッピング ...);
✔ すべて combo=i, combo_sub=j の空間で完結
✔ Three.js は new_mesh_id を読み込むだけ
🧩 次にやるべきこと(あなたへの提案)
combo / combo_sub の扱いが固まったので、
次は DSL → DB DML のマッピングを作ると OS が完成する。
特に:
CREATE MESH part1 FROM FACES groupA;MOVE groupA BY (0,1,0);CREATE INSTANCE inst1 FROM MESH part1;
これらを Flask が DB に対してどう実行するかを定義する。
必要なら、
「DSL 実行エンジン(Flask)」の設計
に進めるよ。