機能と特長

Aspose.3D FOSS for TypeScript は、MIT ライセンスの Node.js ライブラリで、3D シーンのロード、構築、エクスポートを行います。完全な TypeScript 型定義が同梱されており、ランタイム依存関係は 1 つだけです(xmldom), そして主要な 3D ファイル形式 6 種類をサポートしています。このページはすべての機能領域の主要なリファレンスであり、各機能について実行可能な TypeScript コード例が含まれています。.

インストールとセットアップ

npm からパッケージをインストールするには、次の単一コマンドを使用します:

npm install @aspose/3d

このパッケージは CommonJS を対象としており、Node.js 18 以降が必要です。インストール後、あなたの tsconfig.json には完全な互換性のために以下のコンパイラオプションが含まれていることを確認してください::

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "strict": true
  }
}

メインをインポートする Scene パッケージのルートからクラスが取得されます。フォーマット固有のオプションクラスは、それぞれのサブパスからインポートされます::

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

機能と特長

フォーマットのサポート

Aspose.3D FOSS for TypeScript は、主要な 3D ファイル形式 6 種類の読み書きをサポートします。ロード時にはバイナリのマジックナンバーから自動的にフォーマットを検出するため、ソースフォーマットを明示的に指定する必要はありません。.

フォーマット読み取り書くメモ
OBJ (Wavefront)はいはい読み取り/書き込み .mtl マテリアル; 使用 ObjLoadOptions.enableMaterials インポート用
glTF 2.0はいはいJSONテキスト形式; PBRマテリアル
GLBはいはいBinary glTF; 設定 GltfSaveOptions.binaryMode = true
STLはいはいバイナリと ASCII; 完全な往復が検証済み
3MFはいはい3D Manufacturing Format with color and material metadata
FBXいいえ*いいえ*インポーター/エクスポーターは存在しますが、フォーマット自動検出は未実装です
COLLADA (DAE)はいはいユニットスケーリング、ジオメトリ、マテリアル、そしてアニメーションクリップ

マテリアル付き OBJ のロード:

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';

const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
options.flipCoordinateSystem = false;
options.scale = 1.0;
options.normalizeNormal = true;
scene.open('model.obj', options);

GLB(バイナリ glTF)への保存:

import { Scene } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
// ... build or load scene content

const opts = new GltfSaveOptions();
opts.binaryMode = true;
scene.save('output.glb', GltfFormat.getInstance(), opts);

シーングラフ

すべての3Dコンテンツはツリー構造として整理されています Node オブジェクトがルートとなる scene.rootNode.。各ノードは、 Entity (a Mesh, Camera, Light,、または他の SceneObject) と Transform それを親に対して相対的に配置するものです。.

主要なシーングラフクラス:

  • Scene::最上位コンテナ;保持します rootNodeanimationClips
  • Node::名前付きツリーノードで、 childNodes, entity, transform,、および materials
  • Entity: アタッチ可能オブジェクトの基底クラス(Mesh, Camera, Light)
  • SceneObject: 共有される基底クラス Node および Entity
  • A3DObject: ルート基底クラスで name およびプロパティバッグ
  • Transform: ローカル平行移動、回転(Euler と Quaternion)、およびスケール

シーングラフの走査:

import { Scene, Node, Mesh } from '@aspose/3d';

const scene = new Scene();
scene.open('model.obj');

function visit(node: Node, depth: number = 0): void {
  const indent = '  '.repeat(depth);
  console.log(`${indent}Node: ${node.name}`);
  if (node.entity) {
    console.log(`${indent}  Entity: ${node.entity.constructor.name}`);
  }
  for (const child of node.childNodes) {
    visit(child, depth + 1);
  }
}

visit(scene.rootNode);

シーン階層をプログラムで作成する:

import { Scene, Node } from '@aspose/3d';

const scene = new Scene();
const parent = scene.rootNode.createChildNode('chassis');
const wheel = parent.createChildNode('wheel_fl');
wheel.transform.translation.set(0.9, -0.3, 1.4);

ジオメトリとメッシュ

Mesh は主要なジオメトリタイプです。これが拡張します Geometry および制御点(頂点)、ポリゴンインデックス、法線、UV、頂点カラー用の頂点要素を公開します。.

主要なジオメトリクラス:

  • Mesh: を持つポリゴンメッシュ controlPoints および polygonCount
  • Geometry:頂点要素管理を行う基底クラス
  • VertexElementNormal:頂点単位またはポリゴン頂点単位の法線
  • VertexElementUV:テクスチャ座標(1つ以上のUVチャンネル)
  • VertexElementVertexColor:頂点単位のカラー データ
  • MappingMode:要素データがポリゴンにどのようにマッピングされるかを制御する(CONTROL_POINT, POLYGON_VERTEX, POLYGON, EDGE, ALL_SAME)
  • ReferenceMode:インデックス戦略を制御する(DIRECT, INDEX, INDEX_TO_DIRECT)
  • VertexElementType:頂点要素のセマンティクスを識別する
  • TextureMapping:テクスチャチャンネルの列挙

ロードされたシーンからメッシュデータを読み取る:

import { Scene, Mesh, VertexElementType } from '@aspose/3d';

const scene = new Scene();
scene.open('model.stl');

for (const node of scene.rootNode.childNodes) {
  if (node.entity instanceof Mesh) {
    const mesh = node.entity as Mesh;
    console.log(`Mesh "${node.name}": ${mesh.controlPoints.length} vertices, ${mesh.polygonCount} polygons`);

    const normals = mesh.getElement(VertexElementType.NORMAL);
    if (normals) {
      console.log(`  Normal mapping: ${normals.mappingMode}`);
    }
  }
}

マテリアルシステム

Aspose.3D FOSS for TypeScript は、レガシーな Phong シェーディングから物理ベースレンダリングまでの全範囲をカバーする 3 種類のマテリアルタイプをサポートしています:

  • LambertMaterial:拡散色と環境色;シンプルなOBJ/DAEマテリアルにマッピングされる
  • PhongMaterial:鏡面反射色、光沢、放射光を追加する;デフォルトのOBJマテリアルタイプ
  • PbrMaterial:物理ベースのラフネス/メタリックモデル;glTF 2.0 のインポートとエクスポートに使用される

ロードされたOBJシーンからマテリアルを読み取る:

import { Scene, PhongMaterial, LambertMaterial } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';

const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
scene.open('model.obj', options);

for (const node of scene.rootNode.childNodes) {
  for (const mat of node.materials) {
    if (mat instanceof PhongMaterial) {
      const phong = mat as PhongMaterial;
      console.log(`  Phong: diffuse=${JSON.stringify(phong.diffuseColor)}, shininess=${phong.shininess}`);
    } else if (mat instanceof LambertMaterial) {
      console.log(`  Lambert: diffuse=${JSON.stringify((mat as LambertMaterial).diffuseColor)}`);
    }
  }
}

glTFシーンを構築する際にPBRマテリアルを適用する:

import { Scene, Node, PbrMaterial } from '@aspose/3d';
import { Vector3 } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
const node = scene.rootNode.createChildNode('sphere');
const mat = new PbrMaterial();
mat.albedo = new Vector3(0.8, 0.2, 0.2);   // red-tinted albedo; albedo starts null, must assign
mat.metallicFactor = 0.0;
mat.roughnessFactor = 0.5;
node.material = mat;

const opts = new GltfSaveOptions();
opts.binaryMode = false;
scene.save('output.gltf', GltfFormat.getInstance(), opts);

数学ユーティリティ

このライブラリには、完全に型付けされた3D数学型のセットがすべて同梱されています:

  • Vector3: 3成分ベクトル; サポート minus(), times(), dot(), cross(), normalize(), length, angleBetween()
  • Vector4: 同次座標用の4成分ベクトル
  • Matrix4: 4×4 変換行列を使用した concatenate(), transpose, decompose, setTRS
  • Quaternion: 回転クォータニオンを使用した fromEulerAngle() (静的、単数)、, eulerAngles() (インスタンスメソッド)、, slerp(), normalize()
  • BoundingBox: 軸に平行なバウンディングボックス minimum, maximum, center, size, merge
  • FVector3: 単精度バリアント Vector3 頂点要素データで使用される

メッシュ頂点からバウンディングボックスを計算する:

import { Scene, Mesh, Vector3, BoundingBox } from '@aspose/3d';

const scene = new Scene();
scene.open('model.obj');

let box = new BoundingBox();
for (const node of scene.rootNode.childNodes) {
  if (node.entity instanceof Mesh) {
    for (const pt of (node.entity as Mesh).controlPoints) {
      box.merge(new Vector3(pt.x, pt.y, pt.z));
    }
  }
}
console.log('Center:', box.center);
console.log('Extents:', box.size);

オイラー角から変換行列を構築する:

import { Quaternion, Vector3, Matrix4 } from '@aspose/3d';

const rot = Quaternion.fromEulerAngle(0, Math.PI / 4, 0); // 45° around Y
const mat = new Matrix4();
mat.setTRS(new Vector3(0, 0, 0), rot, new Vector3(1, 1, 1));

アニメーションシステム

アニメーションAPIは、クリップ、ノード、チャンネル、キーフレームシーケンスをモデル化します:

  • AnimationClip: アニメーションノードの名前付きコレクション; アクセスは scene.animationClips; 公開する animations: AnimationNode[]
  • AnimationNode:名前付きグループの BindPoints; 経由で作成された clip.createAnimationNode(name),、アクセスは clip.animations
  • BindPoint::バインドする AnimationNode シーンオブジェクトの特定のプロパティへ; 露出する property および channelsCount
  • AnimationChannel::拡張する KeyframeSequence;;別個の keyframeSequence;;アクセスは bindPoint.getChannel(name)
  • KeyFrame::単一の時間/値ペア; キーフレームごとに保持する interpolation: Interpolation
  • KeyframeSequence::順序付きリスト KeyFrame オブジェクトを介して keyFrames; 持つ preBehavior および postBehavior (Extrapolation)
  • Interpolation: enum: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
  • Extrapolation: class with type: ExtrapolationType および repeatCount: number
  • ExtrapolationType: enum: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE

ロードされたシーンからアニメーションデータを読み取る:

import { Scene, AnimationNode, BindPoint } from '@aspose/3d';

const scene = new Scene();
scene.open('animated.dae');   // COLLADA animation import is supported

for (const clip of scene.animationClips) {
  console.log(`Clip: "${clip.name}"`);
  for (const animNode of clip.animations) {          // clip.animations, not clip.nodes
    console.log(`  AnimationNode: ${animNode.name}`);
    for (const bp of animNode.bindPoints) {           // animNode.bindPoints, not animNode.channels
      console.log(`  BindPoint: property="${bp.property.name}", channels=${bp.channelsCount}`);
    }
  }
}

ストリームとバッファのサポート

使用 scene.openFromBuffer() メモリ内から直接3Dシーンをロードするために Buffer.。これは、サーバーレス関数、ストリーミングパイプライン、およびディスクに書き込まずにHTTP経由で取得したアセットを処理する際に推奨されるパターンです。.

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import * as fs from 'fs';

// Load file into memory, then parse from buffer
const buffer: Buffer = fs.readFileSync('model.obj');
const scene = new Scene();
const options = new ObjLoadOptions();
options.enableMaterials = true;
scene.openFromBuffer(buffer, options);

for (const node of scene.rootNode.childNodes) {
  if (node.entity) {
    console.log(node.name, node.entity.constructor.name);
  }
}

バッファからロードする際にはバイナリマジックナンバーによるフォーマット自動検出が適用されるため、GLB、STL バイナリ、3MF ファイルはフォーマットパラメータを指定せずに認識されます。.

使用例

例 1: OBJ をロードして GLB にエクスポート

この例では、マテリアル付きの Wavefront OBJ ファイルをロードし、シーンをウェブやゲームエンジンで使用できるバイナリ glTF(GLB)ファイルとして再エクスポートします。.

import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

function convertObjToGlb(inputPath: string, outputPath: string): void {
  const scene = new Scene();

  const loadOpts = new ObjLoadOptions();
  loadOpts.enableMaterials = true;
  loadOpts.flipCoordinateSystem = false;
  loadOpts.normalizeNormal = true;
  scene.open(inputPath, loadOpts);

  // Report what was loaded
  for (const node of scene.rootNode.childNodes) {
    if (node.entity) {
      console.log(`Loaded: ${node.name} (${node.entity.constructor.name})`);
    }
  }

  const saveOpts = new GltfSaveOptions();
  saveOpts.binaryMode = true; // write .glb instead of .gltf + .bin
  scene.save(outputPath, GltfFormat.getInstance(), saveOpts);

  console.log(`Exported GLB to: ${outputPath}`);
}

convertObjToGlb('input.obj', 'output.glb');

例 2: 法線検証付き STL のラウンドトリップ

この例では、バイナリ STL ファイルをロードし、頂点ごとの法線情報を出力した後、シーンを ASCII STL として再エクスポートし、ラウンドトリップを検証します。.

import { Scene, Mesh, VertexElementNormal, VertexElementType } from '@aspose/3d';
import { StlLoadOptions, StlSaveOptions } from '@aspose/3d/formats/stl';

const scene = new Scene();
const loadOpts = new StlLoadOptions();
scene.open('model.stl', loadOpts);

let totalPolygons = 0;
for (const node of scene.rootNode.childNodes) {
  if (node.entity instanceof Mesh) {
    const mesh = node.entity as Mesh;
    totalPolygons += mesh.polygonCount;

    const normElem = mesh.getElement(VertexElementType.NORMAL) as VertexElementNormal | null;
    if (normElem) {
      console.log(`  Normals: ${normElem.data.length} entries, mapping=${normElem.mappingMode}`);
    }
  }
}
console.log(`Total polygons: ${totalPolygons}`);

// Re-export as ASCII STL
const saveOpts = new StlSaveOptions();
saveOpts.binaryMode = false; // ASCII output
scene.save('output_ascii.stl', saveOpts);

例 3: シーンをプログラムで構築し、glTF として保存する

この例では、PBR マテリアルをゼロから構築してシーンを作成し、JSON glTF ファイルとして保存します。.

import { Scene, Mesh, PbrMaterial, Vector4, Vector3 } from '@aspose/3d';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

const scene = new Scene();
const node = scene.rootNode.createChildNode('floor');

// Build a simple quad mesh (two triangles)
// controlPoints are Vector4 (x, y, z, w) where w=1 for positions
const mesh = new Mesh();
mesh.controlPoints.push(
  new Vector4(-1, 0, -1, 1),
  new Vector4( 1, 0, -1, 1),
  new Vector4( 1, 0,  1, 1),
  new Vector4(-1, 0,  1, 1),
);
mesh.createPolygon([0, 1, 2]);
mesh.createPolygon([0, 2, 3]);
node.entity = mesh;

// Apply a PBR material
const mat = new PbrMaterial();
mat.albedo = new Vector3(0.6, 0.6, 0.6);   // albedo starts null, must assign
mat.metallicFactor = 0.0;
mat.roughnessFactor = 0.8;
node.material = mat;

// Save as JSON glTF
const opts = new GltfSaveOptions();
opts.binaryMode = false;
scene.save('floor.gltf', GltfFormat.getInstance(), opts);
console.log('Scene written to floor.gltf');

ヒントとベストプラクティス

  • 使用 ObjLoadOptions.enableMaterials = true .mtl ファイルからマテリアルデータが必要なときはいつでも。これがないと、各ノードのマテリアルリストは空になります。.
  • 優先 binaryMode = true GLB 用 Web やゲームエンジン向けにアセットを生成する場合。バイナリ GLB は単一の自己完結型ファイルで、JSON + .bin に分割したものよりもブラウザやエンジンでの読み込みが速くなります。.
  • 使用 openFromBuffer() サーバーレス環境で 一時ファイルの I/O を回避するために。アセットを取得し、pass the Buffer 直接渡し、出力をストリームまたは別のバッファに書き込みます。.
  • 確認 node.entity キャストする前に::すべてのノードがエンティティを持つわけではありません。常に with an でガードしてください instanceof アクセスする前にチェック Mesh-specific プロパティなど controlPoints.
  • 設定 normalizeNormal = trueObjLoadOptions ソースの OBJ ファイルが信頼できない場所から来る場合。このようにすると、劣化した法線が下流のレンダリングや検証工程に伝播するのを防げます。.
  • 保持 strict: true tsconfig.json 内で::ライブラリは次で作成されています noImplicitAny および strictNullChecks.。無効化 strict 実際の型エラーを隠蔽し、型付けされた API の価値を損ないます。.
  • 次を経由して走査 childNodes, インデックスループではなく: その childNodes property はイテラブルを返します; 将来の互換性のために数値インデックスへの依存は避けてください。.

一般的な問題

症状考えられる原因修正
OBJ のロード後にマテリアルリストが空enableMaterials 未設定設定 options.enableMaterials = true
GLB ファイルは別個の .bin サイドカーを含んでいますbinaryMode デフォルトは false設定 opts.binaryMode = true
STL 出力で頂点法線が欠落していますSTL ASCII モードは面ごとの法線を省略しますに切り替える binaryMode = true またはエクスポート前に法線を計算する
node.entity は常に nullのみを走査 rootNode,、子要素は含まれません再帰的に入る node.childNodes
TypeScript エラー: プロパティが存在しません@types キャッシュ実行 npm install @aspose/3d 再度; 別々ではない @types パッケージが必要です
openFromBuffer フォーマットエラーをスローしますマジックから形式を自動検出できません明示的なフォーマットオプションクラスを第2引数として渡す

よくある質問

このライブラリはネイティブアドオンやシステムパッケージを必要としますか?? いいえ。Aspose.3D FOSS for TypeScript には単一のランタイム依存関係があります: xmldom, これは純粋な JavaScript で、npm によって自動的にインストールされます。依存はありません .node ネイティブアドオンで、インストールするシステムパッケージは不要です。.

サポートされている Node.js バージョンはどれですか?? Node.js 18、20、22 LTSです。ライブラリは CommonJS 出力を対象とし、内部では ES2020 の言語機能を使用しています。.

ライブラリをブラウザバンドル(webpack / esbuild)で使用できますか?? ライブラリは Node.js を対象とし、Node.js の fsBuffer API を使用します。ブラウザでのバンドリングは公式にはサポートされていません。ブラウザで使用する場合は、シーンをサーバー側でロードし、結果を(例:GLB として)クライアントに送信してください。.

次の違いは何ですか GltfSaveOptions.binaryMode = truefalse? binaryMode = false 生成されるのは .gltf JSON ファイルと別個の .bin バイナリバッファのサイドカー。. binaryMode = true 単一の自己完結型を生成します .glb ファイルです。使用 true 本番環境のアセット配信用に。.

HTTPレスポンスからファイルをディスクに保存せずにロードできますか?? はい。レスポンスを Buffer (例: 使用 node-fetch または組み込みの fetch Node 18+ で)、次に呼び出します scene.openFromBuffer(buffer, options).

FBX のサポートは完全ですか?? いいえ。ライブラリには FBX インポーターとエクスポーターのクラスが存在しますが、FBX は組み込まれていません Scene.open() または Scene.save() 自動検出。呼び出し scene.open('file.fbx') FBXインポーターは呼び出されません;ファイルはSTLフォールバックパスで処理されます。FBXの入出力が必要な場合は、FBX専用のインポーター/エクスポータークラスを直接使用してください。上記のフォーマットサポート表でFBXがとしてマークされているのをご覧ください。 No*.

このライブラリは TypeScript 4.x をサポートしていますか?? TypeScript 5.0 以上を推奨します。実際には TypeScript 4.7 以上でも動作するはずですが、ライブラリは 5.0 以上でテストおよび開発されています。.

API リファレンス概要

クラスモジュール目的
Scene@aspose/3dトップレベルのシーンコンテナ;; open(), openFromBuffer(), save(), rootNode, animationClips
Node@aspose/3dシーングラフノード;; childNodes, entity, transform, materials, createChildNode()
Entity@aspose/3dシーンにアタッチ可能なオブジェクトの基底クラス
SceneObject@aspose/3dベースクラス(共有) Node および Entity
A3DObject@aspose/3dルートベース(以下を含む) name およびプロパティバッグ
Transform@aspose/3dローカルの平行移動、回転、スケール
Mesh@aspose/3dポリゴンメッシュ;; controlPoints, polygonCount, createPolygon(),、頂点要素
Geometry@aspose/3dジオメトリタイプのベースクラス
Camera@aspose/3d視野角と投影設定を持つカメラエンティティ
Light@aspose/3dライトエンティティ(ポイント、ディレクショナル、スポット)
LambertMaterial@aspose/3d拡散 + 環境光シェーディングモデル
PhongMaterial@aspose/3dスペキュラとエミッシブを備えたPhongシェーディング
PbrMaterial@aspose/3dglTF 用の物理ベースラフネス/メタリックモデル
Vector3@aspose/3d3-component double-precision vector
Vector4@aspose/3d4-component vector for homogeneous math
Matrix4@aspose/3d4×4 transformation matrix
Quaternion@aspose/3d回転クォータニオン
BoundingBox@aspose/3d軸平行バウンディングボックス
FVector3@aspose/3d単精度版 Vector3
VertexElementNormal@aspose/3d頂点ごとまたはポリゴン頂点ごとの法線
VertexElementUV@aspose/3dテクスチャ座標頂点要素
VertexElementVertexColor@aspose/3d頂点ごとのカラー頂点要素
MappingMode@aspose/3d列挙型: CONTROL_POINT, POLYGON_VERTEX, POLYGON, ALL_SAME
ReferenceMode@aspose/3d列挙型: DIRECT, INDEX, INDEX_TO_DIRECT
AnimationClip@aspose/3d名前付きアニメーション; 公開 animations: AnimationNode[]; 作成元 scene.createAnimationClip(name)
AnimationNode@aspose/3d名前付きグループ BindPoints; 作成元 clip.createAnimationNode(name)
BindPoint@aspose/3dバインドする AnimationNode シーンオブジェクトのプロパティへ; 公開する propertychannelsCount
AnimationChannel@aspose/3d拡張する KeyframeSequence; 保持する keyframeSequence; でアクセス bindPoint.getChannel(name)
KeyFrame@aspose/3d単一の時間/値キーフレームペア; 搭載する interpolation: Interpolation
KeyframeSequence@aspose/3d順序付けられた keyFrames リスト; preBehavior/postBehavior です Extrapolation オブジェクト
Interpolation@aspose/3d列挙型: LINEAR, CONSTANT, BEZIER, B_SPLINE, CARDINAL_SPLINE, TCB_SPLINE
Extrapolation@aspose/3dクラス with type: ExtrapolationTyperepeatCount: number
ExtrapolationType@aspose/3d列挙型: CONSTANT, GRADIENT, CYCLE, CYCLE_RELATIVE, OSCILLATE
ObjLoadOptions@aspose/3d/formats/objOBJ インポートオプション: enableMaterials, flipCoordinateSystem, scale, normalizeNormal
GltfSaveOptions@aspose/3d/formats/gltfglTF/GLB エクスポートオプション: binaryMode
GltfFormat@aspose/3d/formats/gltfglTF/GLB 用の Format インスタンス; これを渡す scene.save()
StlLoadOptions@aspose/3d/formats/stlSTL インポートオプション
StlSaveOptions@aspose/3d/formats/stlSTL エクスポートオプション: binaryMode
StlImporter@aspose/3d/formats/stl低レベル STL リーダー
StlExporter@aspose/3d/formats/stl低レベル STL ライター
 日本語