Como construir uma malha 3D programaticamente em TypeScript

Como construir uma malha 3D programaticamente em TypeScript

Aspose.3D FOSS para TypeScript permite que você construa geometria 3D inteiramente em código sem carregar nenhum arquivo. Você define posições de vértices como pontos de controle, especifica faces de polígonos por índice e anexa elementos opcionais de vertice, como normais, UVs ou cores do vértice. O resultado pode ser salvo em qualquer formato escrevível: glTF, GLB, STL, FBX ou COLLADA.

Precondições

  • Node.js 18 or later
  • TypeScript 5.0 ou posterior
  • @aspose/3d instalado (ver etapa 1)

Guia passo a passo

Passo 1: Instalar @aspose/3d

asposefoss/3d is not yet published — build from source until it ships. See the project README for build instructions.

Não são necessários adições nativas ou bibliotecas de sistema. O pacote inclui definições de tipos TypeScript.

Minimo de 1 a 2 anos tsconfig.json:

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

Passo 2: Criar uma cena e um nó

A. - Não . Scene O sistema de elevação do nível é o recipiente mais alto. Node dentro da árvore de cena:

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

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

createChildNode(name) cria um nó nomeado e cabos como filho do nó atual. O devolvido Node Objeto é onde você vai anexar a malha na Etapa 7.


Passo 3: Criar um objeto de malha

Mesh Construa um com nome opcional:

import { Mesh } from '@aspose/3d/entities';

const mesh = new Mesh('triangle');

A malha começa vazia: sem vértices e sem faces. Você as adiciona nas etapas seguintes.


Passo 4: Adicionar pontos de controle (vertices)

Os pontos de controlo são as posições dos vértices no espaço local. Vector4 valores em mesh.controlPoints.O quarto componente (w) é o seguinte: 1 para posições:

import { Vector4 } from '@aspose/3d/utilities';

mesh.controlPoints.push(new Vector4(0.0, 0.0, 0.0, 1.0)); // index 0
mesh.controlPoints.push(new Vector4(1.0, 0.0, 0.0, 1.0)); // index 1
mesh.controlPoints.push(new Vector4(0.5, 1.0, 0.0, 1.0)); // index 2

Você se refere a estas posições pelo seu índice baseado em zero quando define as faces de polígonos.


Passo 5: Criar faces de polígonos

createPolygon() define uma face listando os índices de vértices em ordem. Três índice fazem um triângulo:

mesh.createPolygon(0, 1, 2);

Você também pode definir quadrados (quatro índices) ou polígonos arbitrários para formatos que os suportam. Para glTF, a biblioteca triangulará automaticamente quadros e n-gons na exportação.


Passo 6: Adicionar Vertex Normal

Normal melhora a qualidade de renderização. mesh.createElement() para criar um VertexElementNormal, coletar vetores normais em uma matriz, então chamar setData() para armazená-los. data getter retorna uma cópia defensiva empurrá-lo não tem efeito. Use FVector3 (flutuante de precisão única) para dados normais, não Vector4.

import { VertexElementNormal } from '@aspose/3d/entities';
import { VertexElementType, MappingMode, ReferenceMode } from '@aspose/3d/entities';
import { FVector3 } from '@aspose/3d/utilities';

const normals = mesh.createElement(
    VertexElementType.NORMAL,
    MappingMode.CONTROL_POINT,
    ReferenceMode.DIRECT
) as VertexElementNormal;

// Build the normal array, then call setData() — do NOT push to normals.data
normals.setData([
    new FVector3(0, 0, 1), // normal for vertex 0 (pointing +Z)
    new FVector3(0, 0, 1), // normal for vertex 1
    new FVector3(0, 0, 1), // normal for vertex 2
]);

MappingMode.CONTROL_POINT significa um normal por vértice. ReferenceMode.DIRECT significa que a matriz de dados é indexada diretamente pelo índice do vértice do polígono.


Passo 7: Anexar a malha e salvar para glTF

Atribuir a malha ao nó via node.entity, então salve a cena:

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

node.entity = mesh;

const saveOpts = new GltfSaveOptions();
scene.save('triangle.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Triangle mesh saved to triangle.gltf');

Para produzir um único auto-contido .glb arquivo em vez, conjunto saveOpts.binaryMode = true e alterar a extensão de arquivo de saída para .glb.

Exemplo completo

A seguir está o script completo combinando todas as etapas acima:

import { Scene } from '@aspose/3d';
import { Mesh, VertexElementNormal } from '@aspose/3d/entities';
import { VertexElementType, MappingMode, ReferenceMode } from '@aspose/3d/entities';
import { Vector4, FVector3 } from '@aspose/3d/utilities';
import { GltfSaveOptions, GltfFormat } from '@aspose/3d/formats/gltf';

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

const mesh = new Mesh('triangle');

mesh.controlPoints.push(new Vector4(0.0, 0.0, 0.0, 1.0));
mesh.controlPoints.push(new Vector4(1.0, 0.0, 0.0, 1.0));
mesh.controlPoints.push(new Vector4(0.5, 1.0, 0.0, 1.0));

mesh.createPolygon(0, 1, 2);

const normals = mesh.createElement(
    VertexElementType.NORMAL,
    MappingMode.CONTROL_POINT,
    ReferenceMode.DIRECT
) as VertexElementNormal;

// setData() is the correct API — normals.data returns a defensive copy; pushing to it has no effect
normals.setData([
    new FVector3(0, 0, 1),
    new FVector3(0, 0, 1),
    new FVector3(0, 0, 1),
]);

node.entity = mesh;

const saveOpts = new GltfSaveOptions();
scene.save('triangle.gltf', GltfFormat.getInstance(), saveOpts);
console.log('Triangle mesh saved to triangle.gltf');

Corra com o meu amigo . ts-node:

npx ts-node triangle.ts

Problemas comuns

EmissãoCausa da morteCorreção
mesh.controlPoints.length é 0 após empurrarRede não referenciada por nenhum nóPressione antes de atribuir node.entity; a ordem não importa, mas verifique a referência.
A exportação produz uma geometria vazia.node.entity não atribuídoAssegurar a node.entity = mesh Antes de ligares. scene.save()
Desconcordância de contagem normalArray passado para setData() mais curto do que: controlPointsAdicione um. FVector3 entrada por ponto de controlo quando se utiliza o sistema: MappingMode.CONTROL_POINT
O visor glTF mostra uma malha preta.Normal apontando para dentro.Ordem de enrolamento inversa em: createPolygon (por exemplo,., 0, 2, 1) ou negam vetores normais.
TypeScript: propriedade ’normal.data’ não encontradaPercurso de importação incorretoImportação VertexElementNormal de: @aspose/3d/entities, não de @aspose/3d raiz

Perguntas Frequentes

Posso criar quadrados em vez de triângulos? Passa quatro índices para o meu amigo. createPolygon(0, 1, 2, 3).A biblioteca triangula quadrados durante a exportação para formatos que exigem triângulos (glTF, STL).

Qual é a diferença entre: MappingMode.CONTROL_POINT e a) MappingMode.POLYGON_VERTEX? CONTROL_POINT armazenar um valor por vértice único. POLYGON_VERTEX armazena um valor por par de vértices de polígonos, o que permite diferentes normais no mesmo vértice quando pertence a múltiplos polígonos (arestas duras).

Preciso triangular a malha antes de salvar para o STL? Não. A biblioteca lida com a triangulação automaticamente quando exporta para formatos que exigem triângulos. Você pode definir quadrados e n-gons na malha e salvar diretamente em STL.

Como adiciono as coordenadas UV? Utilização: mesh.createElementUV(TextureMapping.Diffuse, MappingMode.CONTROL_POINT, ReferenceMode.DIRECT) para criar um VertexElementUV,Então , liga-me . setData([...]) com uma série de: FVector2 ou a) FVector3 Os valores um por ponto de controlo. data getter retorna uma cópia; não empurrar diretamente para ele.

Posso construir várias malhas numa cena? Crie vários nós sob o código de um servidor. scene.rootNode e atribuir um número separado de Mesh para cada nó de entity propriedade.

Ver também:

 Português