pascal-editor
Pascal Editorの仕組み(React Three Fiber + Zustand)を使って、3D建築エディタアプリを開発・拡張したり、BIMのようなエディタを作ったり、フロアプラン自動生成ツールを構築したりするSkill。
📜 元の英語説明(参考)
Build and extend 3D building editor apps using Pascal Editor's architecture (React Three Fiber + Zustand scene graph). Use when: building 3D architectural tools, creating BIM-like editors, extending Pascal Editor with custom features, building floor plan generators.
🇯🇵 日本人クリエイター向け解説
Pascal Editorの仕組み(React Three Fiber + Zustand)を使って、3D建築エディタアプリを開発・拡張したり、BIMのようなエディタを作ったり、フロアプラン自動生成ツールを構築したりするSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o pascal-editor.zip https://jpskill.com/download/15235.zip && unzip -o pascal-editor.zip && rm pascal-editor.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/15235.zip -OutFile "$d\pascal-editor.zip"; Expand-Archive "$d\pascal-editor.zip" -DestinationPath $d -Force; ri "$d\pascal-editor.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
pascal-editor.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
pascal-editorフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Pascal Editorの統合
概要
Pascal Editor (pascalorg/editor) は、React Three Fiber と WebGPU で構築されたオープンソースの3D建物エディタです。ノードベースのシーングラフ、Zustand による状態管理、そしてAI駆動の建築生成に最適なシステムアーキテクチャを提供します。このスキルでは、建物のジオメトリを作成、操作、およびエクスポートするためのコアAPIについて説明します。
手順
クイックスタート
npx create-next-app@latest my-building-app
cd my-building-app
npm install @pascal-app/core @pascal-app/ui @react-three/fiber @react-three/drei three zustand
ノードの階層
Pascal は、型付きノードのツリーを使用します。
Site -> Building -> Level -> Wall -> Opening (door/window)
-> Slab (floor/ceiling)
-> Zone (room boundary)
-> Item (furniture, fixture)
すべてのノードは、id (UUID)、type、parentId、children (子ID)、props (型固有)、および dirty (再構築のマーク) を持ちます。
Zustand ストア
import { useScene, useViewer, useEditor } from '@pascal-app/core'
// useScene -- シーングラフ (ノード、関係)
const { nodes, createNode, updateNode, deleteNode } = useScene()
// useViewer -- ビューポートの状態 (カメラ、選択)
const { selectedIds, camera, setSelection } = useViewer()
// useEditor -- ツールモードとUIの状態
const { activeTool, setTool, history } = useEditor()
開口部を持つ壁の作成
const scene = useScene.getState()
// 外壁: 長さ4.5m、厚さ200mm、天井高2.7m
const wall = await scene.createNode({
type: 'wall',
props: {
start: { x: 0, y: 0 }, end: { x: 4.5, y: 0 },
thickness: 0.20, height: 2.7,
isExterior: true, material: 'masonry',
}
}, levelId)
// 窓の追加: 幅1.2m、窓台高さ900mm
await scene.createNode({
type: 'item',
props: {
itemType: 'window', wallId: wall.id,
offsetFromStart: 1.5, width: 1.2, height: 1.2, sillHeight: 0.9,
}
}, wall.id)
// ドアの追加: 幅900mm
await scene.createNode({
type: 'item',
props: {
itemType: 'door', wallId: wall.id,
offsetFromStart: 3.0, width: 0.9, height: 2.1, sillHeight: 0,
}
}, wall.id)
レベルと部屋の作成
const level = await scene.createNode({
type: 'level',
props: { name: 'Ground Floor', elevation: 0, height: 2.7, index: 0 }
}, buildingId)
// 床スラブ
await scene.createNode({
type: 'slab',
props: {
polygon: [{ x: 0, y: 0 }, { x: 10, y: 0 }, { x: 10, y: 8 }, { x: 0, y: 8 }],
thickness: 0.25, isRoof: false,
}
}, level.id)
// ラベリングと面積計算のための部屋のゾーン
await scene.createNode({
type: 'zone',
props: {
name: 'Living Room', roomType: 'living',
polygon: [{ x: 0.1, y: 0.1 }, { x: 5.4, y: 0.1 }, { x: 5.4, y: 7.9 }, { x: 0.1, y: 7.9 }],
}
}, level.id)
シーンの JSON へのエクスポート
function exportScene(): BuildingExport {
const { nodes } = useScene.getState()
const allNodes = Object.values(nodes)
const site = allNodes.find(n => n.type === 'site')
const building = allNodes.find(n => n.type === 'building')
const levels = allNodes
.filter(n => n.type === 'level' && n.parentId === building.id)
.sort((a, b) => a.props.elevation - b.props.elevation)
return {
units: 'meters',
site: { width: site.props.width, depth: site.props.depth },
building: {
levels: levels.map(level => ({
name: level.props.name,
elevation: level.props.elevation,
height: level.props.height,
walls: getChildrenByType(level.id, 'wall', allNodes),
rooms: getChildrenByType(level.id, 'zone', allNodes),
}))
}
}
}
React Three Fiber でのレンダリング
import { Canvas } from '@react-three/fiber'
import { PascalScene, PascalCamera, PascalControls } from '@pascal-app/ui'
export function BuildingViewer() {
return (
<Canvas camera={{ position: [0, 20, 20], fov: 45 }}>
<PascalScene />
<PascalCamera />
<PascalControls />
<ambientLight intensity={0.5} />
<directionalLight position={[10, 20, 10]} castShadow />
</Canvas>
)
}
グリッドスナップ
Pascal はデフォルトで 100 mm グリッド (0.1 m) を使用します。
const snapToGrid = (value: number, gridSize = 0.1) =>
Math.round(value / gridSize) * gridSize
例
例 1: 10m x 8m の1階を構築する
外壁、リビングと寝室を区切る内壁、および適切な開口部を備えた完全な1階を作成します。
- 高さ 0、高さ 2.7 m のレベルノードを作成します。
- 床スラブを作成します: 10 m x 8 m のポリゴン、厚さ 0.25 m
- 4つの外壁を作成します (厚さ 0.20 m、石造): 北 (10 m)、東 (8 m)、南 (10 m)、西 (8 m)
- x=5.5 に、奥行き全体にわたる内壁 (厚さ 0.10 m、木材) を追加します。
- 北側の壁にエントランスドアを追加します: 1.0 m x 2.1 m、オフセット 3.5 m
- 東側の壁に窓を追加します: 2つの 1.2 m x 1.2 m、窓台高さ 0.9 m、オフセット 1.2 m および 4.5 m
- ゾーンを作成します: リビングルーム (5.3 m x 7.8 m = 41.3 m2)、寝室エリア (4.3 m x 7.8 m = 33.5 m2)
architectural-dimensionsルールに対する検証のために JSON にエクスポートします。
例 2: カスタム検証システムの登録
壁ノードが変更されるたびに壁の厚さをチェックするシステムを作成します。
import { registerSystem, useScene } from '@pascal-app/core'
registerSystem({
name: 'wall-validator',
nodeTypes: ['wall'],
priority: 100,
process(dirtyNodes) {
for (const node of dirtyNodes) {
const { thickness, isExterior, height } = node.props
if (isExterior && thickness < 0.14)
console.warn(`Wall ${node.id}: exterior ${thickness}m < 0.14m minimum`)
if (height < 2.1)
console.warn(`Wall ${node.id}: height ${height}m < 2.1m minimum`)
}
}
})
これは、ジオメトリシステムがメッシュを再構築する前に、壁ノードがダーティとしてマークされるたびに自動的に実行されます。
ガイドライン
- すべての寸法はメートル単位です -- Pascal は内部的にメートル法を使用します。
useSceneを使用してください
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Pascal Editor Integration
Overview
Pascal Editor (pascalorg/editor) is an open-source 3D building editor built with React Three Fiber and WebGPU. It provides a node-based scene graph, Zustand state management, and a systems architecture ideal for AI-driven architectural generation. This skill covers the core API for creating, manipulating, and exporting building geometry.
Instructions
Quick Start
npx create-next-app@latest my-building-app
cd my-building-app
npm install @pascal-app/core @pascal-app/ui @react-three/fiber @react-three/drei three zustand
Node Hierarchy
Pascal uses a tree of typed nodes:
Site -> Building -> Level -> Wall -> Opening (door/window)
-> Slab (floor/ceiling)
-> Zone (room boundary)
-> Item (furniture, fixture)
Every node has: id (UUID), type, parentId, children (child IDs), props (type-specific), and dirty (marks for rebuild).
Zustand Stores
import { useScene, useViewer, useEditor } from '@pascal-app/core'
// useScene -- scene graph (nodes, relations)
const { nodes, createNode, updateNode, deleteNode } = useScene()
// useViewer -- viewport state (camera, selection)
const { selectedIds, camera, setSelection } = useViewer()
// useEditor -- tool mode and UI state
const { activeTool, setTool, history } = useEditor()
Creating Walls with Openings
const scene = useScene.getState()
// Exterior wall: 4.5m long, 200mm thick, 2.7m ceiling
const wall = await scene.createNode({
type: 'wall',
props: {
start: { x: 0, y: 0 }, end: { x: 4.5, y: 0 },
thickness: 0.20, height: 2.7,
isExterior: true, material: 'masonry',
}
}, levelId)
// Add a window: 1.2m wide, sill at 900mm
await scene.createNode({
type: 'item',
props: {
itemType: 'window', wallId: wall.id,
offsetFromStart: 1.5, width: 1.2, height: 1.2, sillHeight: 0.9,
}
}, wall.id)
// Add a door: 900mm wide
await scene.createNode({
type: 'item',
props: {
itemType: 'door', wallId: wall.id,
offsetFromStart: 3.0, width: 0.9, height: 2.1, sillHeight: 0,
}
}, wall.id)
Creating Levels and Rooms
const level = await scene.createNode({
type: 'level',
props: { name: 'Ground Floor', elevation: 0, height: 2.7, index: 0 }
}, buildingId)
// Floor slab
await scene.createNode({
type: 'slab',
props: {
polygon: [{ x: 0, y: 0 }, { x: 10, y: 0 }, { x: 10, y: 8 }, { x: 0, y: 8 }],
thickness: 0.25, isRoof: false,
}
}, level.id)
// Room zone for labeling and area calculation
await scene.createNode({
type: 'zone',
props: {
name: 'Living Room', roomType: 'living',
polygon: [{ x: 0.1, y: 0.1 }, { x: 5.4, y: 0.1 }, { x: 5.4, y: 7.9 }, { x: 0.1, y: 7.9 }],
}
}, level.id)
Exporting Scene to JSON
function exportScene(): BuildingExport {
const { nodes } = useScene.getState()
const allNodes = Object.values(nodes)
const site = allNodes.find(n => n.type === 'site')
const building = allNodes.find(n => n.type === 'building')
const levels = allNodes
.filter(n => n.type === 'level' && n.parentId === building.id)
.sort((a, b) => a.props.elevation - b.props.elevation)
return {
units: 'meters',
site: { width: site.props.width, depth: site.props.depth },
building: {
levels: levels.map(level => ({
name: level.props.name,
elevation: level.props.elevation,
height: level.props.height,
walls: getChildrenByType(level.id, 'wall', allNodes),
rooms: getChildrenByType(level.id, 'zone', allNodes),
}))
}
}
}
Rendering with React Three Fiber
import { Canvas } from '@react-three/fiber'
import { PascalScene, PascalCamera, PascalControls } from '@pascal-app/ui'
export function BuildingViewer() {
return (
<Canvas camera={{ position: [0, 20, 20], fov: 45 }}>
<PascalScene />
<PascalCamera />
<PascalControls />
<ambientLight intensity={0.5} />
<directionalLight position={[10, 20, 10]} castShadow />
</Canvas>
)
}
Grid Snapping
Pascal uses a 100 mm grid (0.1 m) by default:
const snapToGrid = (value: number, gridSize = 0.1) =>
Math.round(value / gridSize) * gridSize
Examples
Example 1: Build a 10m x 8m Ground Floor
Create a complete ground floor with exterior walls, an interior partition dividing living from bedrooms, and appropriate openings:
- Create level node with elevation 0, height 2.7 m
- Create floor slab: 10 m x 8 m polygon, 0.25 m thick
- Create 4 exterior walls (0.20 m thick, masonry): north (10 m), east (8 m), south (10 m), west (8 m)
- Add interior partition at x=5.5 (0.10 m thick, timber) running full depth
- Add entry door on north wall: 1.0 m x 2.1 m at offset 3.5 m
- Add windows on east wall: two 1.2 m x 1.2 m at sill 0.9 m, offsets 1.2 m and 4.5 m
- Create zones: Living Room (5.3 m x 7.8 m = 41.3 m2), Bedroom area (4.3 m x 7.8 m = 33.5 m2)
- Export to JSON for validation against
architectural-dimensionsrules
Example 2: Register a Custom Validation System
Create a system that checks wall thickness whenever a wall node changes:
import { registerSystem, useScene } from '@pascal-app/core'
registerSystem({
name: 'wall-validator',
nodeTypes: ['wall'],
priority: 100,
process(dirtyNodes) {
for (const node of dirtyNodes) {
const { thickness, isExterior, height } = node.props
if (isExterior && thickness < 0.14)
console.warn(`Wall ${node.id}: exterior ${thickness}m < 0.14m minimum`)
if (height < 2.1)
console.warn(`Wall ${node.id}: height ${height}m < 2.1m minimum`)
}
}
})
This runs automatically whenever wall nodes are marked dirty, before geometry systems rebuild meshes.
Guidelines
- All dimensions are in meters -- Pascal uses metric internally
- Use
useScenefor all node CRUD operations,useViewerfor selection/camera,useEditorfor tools - Snap coordinates to 0.1 m grid for clean geometry
- Wall thickness: 0.20 m for exterior, 0.10 m for interior partitions
- Door sill height is always 0 (floor level); window sill height defaults to 0.9 m
- Register custom systems with priority > 50 to run before geometry rebuild (0-50)
- Combine with
architectural-dimensionsskill for real-world measurement validation - Key packages:
@pascal-app/core,@pascal-app/ui,@react-three/fiber,three,zustand - GitHub: github.com/pascalorg/editor