You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OBJ数据生成PDF(Workshop):用户对象选择与导出功能咨询

实现OBJ对象选择、新建与PDF导出的方案

一、UI交互层实现

先搭建基础交互界面,让用户能直观选择目标对象,并触发新建/导出操作:

  • 用多选复选框组或下拉选择器展示所有OBJ对象列表,每个选项绑定对象的唯一ID或索引,方便后续获取对应数据
  • 放置两个操作按钮:「创建新OBJ文件」和「导出所选为PDF」,分别绑定对应的处理函数

示例HTML结构:

<div class="obj-selector">
  <h3>选择目标OBJ对象</h3>
  <div id="obj-list"></div>
</div>
<div class="actions">
  <button id="create-obj-btn">创建新OBJ文件</button>
  <button id="export-pdf-btn">导出所选为PDF</button>
</div>

用JavaScript动态渲染对象列表:

// 模拟存储的OBJ对象数据
const objDataList = [
  { id: 1, name: "模型A", content: "# OBJ模型A数据..." },
  { id: 2, name: "模型B", content: "# OBJ模型B数据..." }
];

// 渲染选择列表
const objListEl = document.getElementById('obj-list');
objDataList.forEach(obj => {
  const checkbox = document.createElement('input');
  checkbox.type = 'checkbox';
  checkbox.value = obj.id;
  checkbox.id = `obj-${obj.id}`;
  
  const label = document.createElement('label');
  label.htmlFor = checkbox.id;
  label.textContent = obj.name;
  
  objListEl.appendChild(checkbox);
  objListEl.appendChild(label);
  objListEl.appendChild(document.createElement('br'));
});

二、创建新OBJ文件的逻辑

点击「创建新OBJ文件」按钮时,完成以下步骤:

  1. 弹出输入框让用户输入新OBJ的名称
  2. 生成默认的OBJ模板内容(比如包含基础的顶点、面结构注释)
  3. 把新OBJ数据添加到对象列表,同时触发本地下载

示例实现:

document.getElementById('create-obj-btn').addEventListener('click', () => {
  const objName = prompt("请输入新OBJ文件名称:");
  if (!objName) return;
  
  // 生成默认OBJ模板
  const defaultObjContent = `# ${objName} 模型
v 0.0 0.0 0.0
v 1.0 0.0 0.0
v 1.0 1.0 0.0
v 0.0 1.0 0.0
f 1 2 3
f 1 3 4`;
  
  // 创建Blob并触发下载
  const blob = new Blob([defaultObjContent], { type: 'text/plain' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `${objName}.obj`;
  a.click();
  URL.revokeObjectURL(url);
  
  // 可选:将新对象添加到列表
  const newObj = { id: Date.now(), name: objName, content: defaultObjContent };
  objDataList.push(newObj);
  // 重新渲染列表(这里可以优化为只添加新项,不用全量渲染)
  objListEl.innerHTML = '';
  objDataList.forEach(obj => { /* 重复之前的渲染逻辑 */ });
});

三、导出所选对象为PDF的逻辑

导出PDF需要分两种场景处理:纯文本OBJ数据导出,或可视化模型导出。

场景1:导出OBJ文本内容到PDF

直接将选中对象的OBJ文本内容写入PDF,适合查看源码的需求:

import jsPDF from 'jspdf'; // 需引入jsPDF库

document.getElementById('export-pdf-btn').addEventListener('click', () => {
  // 获取选中的对象ID
  const selectedIds = Array.from(document.querySelectorAll('input[type="checkbox"]:checked'))
    .map(checkbox => parseInt(checkbox.value));
  
  if (selectedIds.length === 0) {
    alert("请至少选择一个OBJ对象");
    return;
  }
  
  // 获取选中对象的内容
  const selectedContents = objDataList
    .filter(obj => selectedIds.includes(obj.id))
    .map(obj => `--- ${obj.name} --- \n${obj.content}`)
    .join('\n\n');
  
  // 生成PDF
  const doc = new jsPDF();
  doc.setFontSize(12);
  // 处理长文本自动换行
  const lines = doc.splitTextToSize(selectedContents, 180);
  doc.text(lines, 10, 10);
  
  doc.save('selected-obj-files.pdf');
});

场景2:导出OBJ模型的可视化渲染图到PDF

如果需要将OBJ模型渲染成图像再导出PDF,需要用到3D渲染库(如Three.js):

  1. 用Three.js加载选中的OBJ模型,渲染到Canvas
  2. 将Canvas内容转为图片,插入到PDF中

示例核心代码:

import * as THREE from 'three';
import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
import jsPDF from 'jspdf';

async function renderObjToCanvas(objContent) {
  const canvas = document.createElement('canvas');
  canvas.width = 800;
  canvas.height = 600;
  const renderer = new THREE.WebGLRenderer({ canvas });
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, canvas.width/canvas.height, 0.1, 1000);
  
  // 添加光源
  scene.add(new THREE.AmbientLight(0xffffff));
  
  // 加载OBJ内容
  const loader = new OBJLoader();
  const object = loader.parse(objContent);
  scene.add(object);
  
  // 调整相机位置
  const box = new THREE.Box3().setFromObject(object);
  const center = box.getCenter(new THREE.Vector3());
  const size = box.getSize(new THREE.Vector3());
  const maxDim = Math.max(size.x, size.y, size.z);
  const cameraZ = maxDim * 1.5;
  camera.position.set(center.x, center.y, cameraZ);
  camera.lookAt(center);
  
  // 渲染
  renderer.render(scene, camera);
  return canvas.toDataURL('image/png');
}

// 导出按钮绑定逻辑
document.getElementById('export-pdf-btn').addEventListener('click', async () => {
  const selectedIds = Array.from(document.querySelectorAll('input[type="checkbox"]:checked'))
    .map(checkbox => parseInt(checkbox.value));
  
  if (selectedIds.length === 0) {
    alert("请至少选择一个OBJ对象");
    return;
  }
  
  const doc = new jsPDF('landscape');
  let yPos = 10;
  
  for (const id of selectedIds) {
    const obj = objDataList.find(o => o.id === id);
    const imgData = await renderObjToCanvas(obj.content);
    
    // 插入图片到PDF,调整尺寸适配页面
    doc.addImage(imgData, 'PNG', 10, yPos, 270, 200);
    doc.text(obj.name, 10, yPos - 5);
    yPos += 210;
    
    // 超过页面高度时添加新页
    if (yPos > 280) {
      doc.addPage();
      yPos = 10;
    }
  }
  
  doc.save('obj-models-preview.pdf');
});

四、关键注意事项

  • 确保用户选择验证:导出前检查是否有选中对象,避免空导出
  • 处理大文件:如果OBJ模型过大,渲染时要考虑性能优化(比如简化模型、分批渲染)
  • 兼容性:jsPDF和Three.js需要注意浏览器兼容性,针对旧浏览器可能需要降级处理

内容的提问来源于stack exchange,提问作者Foundry_Users

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 02:55:55