वास्तविक दुनिया के उपयोग केस

वास्तविक दुनिया के उपयोग केस

यह पृष्ठ व्यावहारिक, प्रोडक्शन-ग्रेड उपयोग मामलों को कवर करता है @aspose/3d TypeScript और Node.js में, HTTP API सेवाओं से लेकर CI वैलिडेशन पाइपलाइनों तक।.


उपयोग केस 1: 3D एसेट रूपांतरण के लिए HTTP सेवा

एक Express.js एंडपॉइंट बनाएं जो अपलोड की गई 3D फ़ाइल को स्वीकार करता है और परिवर्तित GLB लौटाता है:

// converter-service.ts
import express from 'express';
import multer from 'multer';
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions } from '@aspose/3d/formats/gltf';

const app = express();
const upload = multer({ storage: multer.memoryStorage() });

app.post('/convert/obj-to-glb', upload.single('file'), (req, res) => {
    if (!req.file) {
        return res.status(400).json({ error: 'No file uploaded' });
    }

    const scene = new Scene();
    const loadOpts = new ObjLoadOptions();
    loadOpts.enableMaterials = true;
    scene.openFromBuffer(req.file.buffer, loadOpts);

    const saveOpts = new GltfSaveOptions();
    saveOpts.binaryMode = true;

    const glbBuffer = scene.saveToBuffer('glb', saveOpts);

    res.setHeader('Content-Type', 'model/gltf-binary');
    res.setHeader('Content-Disposition', 'attachment; filename="output.glb"');
    res.send(glbBuffer);
});

app.listen(3000, () => console.log('Converter service listening on :3000'));

यह पैटर्न कोई अस्थायी फ़ाइलें नहीं मांगता और Docker कंटेनरों या सर्वरलेस वातावरण में काम करता है।.


उपयोग केस 2: CI पाइपलाइन: 3D एसेट की अखंडता सत्यापित करें

अपने CI पाइपलाइन में एक Node.js स्क्रिप्ट जोड़ें जो सभी कमिटेड 3D फ़ाइलों को सही ढंग से लोड होने और ज्यामिति शामिल करने की जाँच करती है:

// scripts/validate-assets.ts
import * as fs from 'fs';
import * as path from 'path';
import { Scene, Mesh } from '@aspose/3d';

const ASSET_DIR = './assets/3d';
const EXTENSIONS = ['.obj', '.fbx', '.glb', '.stl', '.dae'];

let failed = 0;

function countMeshes(node: any): number {
    let count = node.entity instanceof Mesh ? 1 : 0;
    for (const child of node.childNodes) count += countMeshes(child);
    return count;
}

for (const file of fs.readdirSync(ASSET_DIR)) {
    const ext = path.extname(file).toLowerCase();
    if (!EXTENSIONS.includes(ext)) continue;

    const filePath = path.join(ASSET_DIR, file);
    try {
        const scene = new Scene();
        scene.open(filePath);
        const meshCount = countMeshes(scene.rootNode);
        if (meshCount === 0) {
            console.error(`FAIL: ${file}: no meshes found`);
            failed++;
        } else {
            console.log(`OK: ${file}: ${meshCount} mesh(es)`);
        }
    } catch (err) {
        console.error(`ERROR: ${file}: ${(err as Error).message}`);
        failed++;
    }
}

if (failed > 0) {
    console.error(`\n${failed} asset(s) failed validation`);
    process.exit(1);
}
console.log('All assets validated successfully.');

अपने में जोड़ें package.json स्क्रिप्ट्स और अपने CI चरण से कॉल करें:

{
  "scripts": {
    "validate-assets": "npx ts-node scripts/validate-assets.ts"
  }
}

उपयोग केस 3: वर्कर थ्रेड्स के साथ बैच रूपांतरण

Node.js वर्कर थ्रेड्स का उपयोग करके OBJ फ़ाइलों की डायरेक्टरी को समानांतर में GLB में रूपांतरित करें:

// worker.ts
import { workerData, parentPort } from 'worker_threads';
import { Scene } from '@aspose/3d';
import { ObjLoadOptions } from '@aspose/3d/formats/obj';
import { GltfSaveOptions } from '@aspose/3d/formats/gltf';

const { inputPath, outputPath } = workerData as { inputPath: string; outputPath: string };

const scene = new Scene();
const loadOpts = new ObjLoadOptions();
loadOpts.enableMaterials = true;
loadOpts.normalizeNormal = true;
scene.open(inputPath);

const saveOpts = new GltfSaveOptions();
saveOpts.binaryMode = true;
scene.save(outputPath, saveOpts);

parentPort?.postMessage({ ok: true, output: outputPath });
// main.ts
import { Worker } from 'worker_threads';
import * as fs from 'fs';
import * as path from 'path';

const INPUT_DIR = './input';
const OUTPUT_DIR = './output';
const CONCURRENCY = 4;

fs.mkdirSync(OUTPUT_DIR, { recursive: true });

const files = fs.readdirSync(INPUT_DIR).filter(f => f.endsWith('.obj'));
let active = 0;
let index = 0;

function dispatch(): void {
    while (active < CONCURRENCY && index < files.length) {
        const file = files[index++];
        const inputPath = path.join(INPUT_DIR, file);
        const outputPath = path.join(OUTPUT_DIR, file.replace('.obj', '.glb'));

        active++;
        const worker = new Worker(path.resolve('./dist/worker.js'), {
            workerData: { inputPath, outputPath }
        });

        worker.on('message', msg => {
            console.log(`Converted: ${msg.output}`);
            active--;
            dispatch();
        });

        worker.on('error', err => {
            console.error(`Failed: ${inputPath}: ${err.message}`);
            active--;
            dispatch();
        });
    }
}

dispatch();

के साथ चलाएँ npx tsc && node dist/main.js. समायोजित करें CONCURRENCY उपलब्ध CPU कोरों से मेल खाने के लिए।.


उपयोग केस 4: 3D प्रिंटिंग के लिए मॉडल तैयार करें

स्लाइसर सॉफ़्टवेयर के लिए FBX स्रोत फ़ाइलों को 3MF फ़ॉर्मेट में रूपांतरित करें:

import * as fs from 'fs';
import * as path from 'path';
import { Scene } from '@aspose/3d';

const SOURCE_DIR = './models/fbx';
const PRINT_DIR = './models/print';

fs.mkdirSync(PRINT_DIR, { recursive: true });

for (const file of fs.readdirSync(SOURCE_DIR)) {
    if (!file.endsWith('.fbx')) continue;

    const inputPath = path.join(SOURCE_DIR, file);
    const outputPath = path.join(PRINT_DIR, file.replace('.fbx', '.3mf'));

    const scene = new Scene();
    scene.open(inputPath);
    scene.save(outputPath);

    const { size } = fs.statSync(outputPath);
    console.log(`${file}${path.basename(outputPath)} (${Math.round(size / 1024)} KB)`);
}

STL आउटपुट के लिए (अधिकतम स्लाइसर संगतता), आउटपुट एक्सटेंशन को बदलें .stl. ध्यान दें कि STL सामग्री और रंग डेटा खो देता है।.


उपयोग केस 5: एसेट डेटाबेस के लिए सीन आँकड़े निकालें

3D फ़ाइलों के रिपॉज़िटरी को स्कैन करें और एसेट मैनेजमेंट सिस्टम में इन्गेस्ट करने के लिए एक JSON सारांश उत्पन्न करें:

import * as fs from 'fs';
import * as path from 'path';
import { Scene, Mesh, Node } from '@aspose/3d';

interface AssetStats {
    file: string;
    format: string;
    meshCount: number;
    totalVertices: number;
    totalPolygons: number;
    animationClips: number;
    sizeBytes: number;
}

function collectStats(node: Node, stats: AssetStats): void {
    if (node.entity instanceof Mesh) {
        const mesh = node.entity as Mesh;
        stats.meshCount++;
        stats.totalVertices += mesh.controlPoints.length;
        stats.totalPolygons += mesh.polygonCount;
    }
    for (const child of node.childNodes) {
        collectStats(child, stats);
    }
}

const SCAN_DIR = './assets';
const results: AssetStats[] = [];
const EXTENSIONS = ['.obj', '.fbx', '.glb', '.gltf', '.stl', '.dae', '.3mf'];

for (const file of fs.readdirSync(SCAN_DIR)) {
    const ext = path.extname(file).toLowerCase();
    if (!EXTENSIONS.includes(ext)) continue;

    const filePath = path.join(SCAN_DIR, file);
    const stats: AssetStats = {
        file, format: ext.slice(1).toUpperCase(),
        meshCount: 0, totalVertices: 0, totalPolygons: 0,
        animationClips: 0, sizeBytes: fs.statSync(filePath).size
    };

    try {
        const scene = new Scene();
        scene.open(filePath);
        collectStats(scene.rootNode, stats);
        stats.animationClips = scene.animationClips.length;
    } catch {
        // skip unreadable files
    }

    results.push(stats);
}

fs.writeFileSync('asset-stats.json', JSON.stringify(results, null, 2));
console.log(`Scanned ${results.length} assets → asset-stats.json`);

संबंधित देखें

 हिन्दी