Files

210 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>STEP 模型查看器</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="./style.css?v=5">
<script type="importmap">
{
"imports": {
"three": "./libs/three.module.min.js",
"three/addons/": "./libs/"
}
}
</script>
<script src="./libs/occt-import-js.js"></script>
</head>
<body>
<script>
// 首帧渲染前应用 embed/menu-min 样式, 消除加载瞬间完整界面(顶栏/模型树/完整菜单)闪烁 (欧霓博目录专用补丁 2026-08-24)
(function () {
var q = new URLSearchParams(location.search);
if (q.get('embed') === '1') document.body.classList.add('embed');
if (q.get('menu') === 'min') document.body.classList.add('menu-min');
})();
</script>
<!-- 顶栏 -->
<div id="topbar">
<div class="logo">
<span class="logo-text">STEP 3D 查看器</span>
</div>
<button id="btnOpen" class="btn-primary" title="打开 STEP 文件">打开模型</button>
<label class="quality-label" title="网格细分精度(越高越精细,转换时间越长)">精度
<select id="qualitySelect">
<option value="low"></option>
<option value="medium"></option>
<option value="high" selected></option>
</select>
</label>
<button id="btnEmbed" class="btn-secondary" title="生成嵌入链接">嵌入</button>
<span id="fileName" class="file-name">未加载模型(支持拖拽 .step/.stp 文件到页面)</span>
<div class="top-right">
<button id="btnFullscreen" class="icon-btn" title="全屏"><img src="./icons/all-screen.png" alt="全屏"></button>
</div>
</div>
<div id="main">
<!-- 左侧模型树 -->
<div id="treePanel">
<div class="tree-header">
<span class="tree-title">模型树</span>
<button id="btnTreeClose" class="tree-close" title="关闭面板"></button>
<div class="tree-search">
<img src="./icons/ico-search.33e9e6a1.png" alt="搜索">
<input id="treeSearch" type="text" placeholder="搜索零件...">
</div>
</div>
<div id="tree" class="tree-body"><div class="tree-empty">加载模型后显示零件树</div></div>
</div>
<!-- 视口 -->
<div id="viewport">
<div id="canvasWrap"></div>
<!-- 底部工具栏 -->
<div id="toolbar">
<button class="tool-btn active" data-tool="select" title="选择"><img src="./icons/view-tool-select.png" alt="选择"><span>选择</span></button>
<button class="tool-btn" data-tool="measure" title="测量"><img src="./icons/view-tool-distance.png" alt="测量"><span>测量</span></button>
<button class="tool-btn" data-tool="drag" title="拖动零件"><img src="./icons/view-tool-drag.png" alt="拖动"><span>拖动</span></button>
<button class="tool-btn" data-tool="singalDrag" title="单件拖动"><img src="./icons/view-tool-singalDrag.png" alt="单件拖动"><span>单件</span></button>
<button class="tool-btn" data-tool="explode" title="爆炸"><img src="./icons/view-tool-blast.png" alt="爆炸"><span>爆炸</span></button>
<button class="tool-btn" data-tool="section" title="剖切"><img src="./icons/view-tool-slice.png" alt="剖切"><span>剖切</span></button>
<div class="tool-sep"></div>
<button class="tool-btn" id="btnTree" title="结构树显示/隐藏"><img src="./icons/view-tool-tree.png" alt="结构树"><span>结构树</span></button>
<button class="tool-btn" id="btnWireframe" title="线框(显示/隐藏轮廓线)"><img src="./icons/ico-set-wireframe.png" alt="线框"><span>线框</span></button>
<button class="tool-btn" id="btnColorPanel" title="上色"><img src="./icons/ico-set-color.png" alt="上色"><span>上色</span></button>
<button class="tool-btn" id="btnShowAll" title="全部显示"><img src="./icons/view-tool-hideShow.png" alt="全部显示"><span>显示</span></button>
<button class="tool-btn" id="btnTransparent" title="透明(选中零件)"><img src="./icons/view-tool-transparent.png" alt="透明"><span>透明</span></button>
<button class="tool-btn" id="btnBbox" title="包围盒"><img src="./icons/view-tool-coutBox.png" alt="包围盒"><span>包围盒</span></button>
<button class="tool-btn" id="btnClear" title="清除测量"><img src="./icons/view-tool-clear.png" alt="清除"><span>清除</span></button>
<button class="tool-btn" id="btnSingleReset" title="单件复位"><img src="./icons/view-tool-singalReset.png" alt="单件复位"><span>复位</span></button>
<button class="tool-btn" id="btnAllReset" title="全部复位"><img src="./icons/view-tool-allReset.png" alt="全部复位"><span>全复位</span></button>
<div class="tool-sep"></div>
<button class="tool-btn" id="btnVport" title="切换视角"><img src="./icons/view-tool-vport.png" alt="视角"><span>视角</span></button>
<button class="tool-btn" id="btnAxes" title="坐标系"><img src="./icons/view-tool-coordinate.png" alt="坐标系"><span>坐标</span></button>
<button class="tool-btn" id="btnFull" title="全屏"><img src="./icons/all-screen.png" alt="全屏"><span>全屏</span></button>
</div>
<!-- 爆炸面板 -->
<div id="explodePanel" class="float-panel hidden">
<div class="panel-title">爆炸 <img src="./icons/close.0fb8dc6e.png" class="panel-close" data-panel="explode" alt="关闭"></div>
<div class="panel-row">
<span>程度</span>
<input type="range" id="explodeSlider" min="0" max="100" value="0">
<span id="explodeVal" class="panel-val">0%</span>
</div>
</div>
<!-- 剖切面板 -->
<div id="sectionPanel" class="float-panel hidden">
<div class="panel-title">剖切 <img src="./icons/close.0fb8dc6e.png" class="panel-close" data-panel="section" alt="关闭"></div>
<div class="panel-row">
<button class="axis-btn" data-axis="x">X</button>
<button class="axis-btn" data-axis="y">Y</button>
<button class="axis-btn active" data-axis="z">Z</button>
<button id="btnSectionFlip" class="small-btn">翻转</button>
<button id="btnSectionToggle" class="small-btn on">开启</button>
</div>
<div class="panel-row">
<span>位置</span>
<input type="range" id="sectionSlider" min="-100" max="100" value="0">
<span id="sectionVal" class="panel-val">0</span>
</div>
</div>
<!-- 测量子面板(水平单行,激活时隐藏底部工具栏) -->
<div id="measurePanel" class="float-panel measure-panel hidden">
<div id="measureModes"></div>
<div class="measure-actions">
<button id="btnStats" class="measure-act" title="结果统计"><img src="./icons/view-tool-statisticalResult.png" alt="统计"></button>
<button id="btnMeasureClear" class="measure-act" title="清空"><img src="./icons/view-tool-clear.png" alt="清空"></button>
</div>
<button id="btnMeasureClose" class="measure-act" title="关闭测量,恢复工具栏"><img src="./icons/close.0fb8dc6e.png" alt="关闭"></button>
</div>
<!-- 结果统计面板 -->
<div id="statsPanel" class="float-panel hidden">
<div class="panel-title">结果统计 <img src="./icons/close.0fb8dc6e.png" class="panel-close" data-panel="stats" alt="关闭"></div>
<div id="statsList"><div class="stats-empty">暂无测量结果</div></div>
</div>
<!-- 上色面板 -->
<div id="colorPanel" class="float-panel hidden">
<div class="panel-title">上色 <img src="./icons/close.0fb8dc6e.png" class="panel-close" data-panel="color" alt="关闭"></div>
<div class="panel-row">
<input type="color" id="colorPicker" value="#2b9ae8" title="选择颜色">
<button id="btnColorApply" class="small-btn">应用到选中</button>
</div>
<div class="panel-row">
<button id="btnColorOneClick" class="small-btn" title="按零件自动分配颜色"><img src="./icons/one-click-color.0a5c28c0.png" alt="一键上色">一键上色</button>
<button id="btnColorReset" class="small-btn">恢复原色</button>
</div>
<div class="panel-row">
<span>亮度</span>
<input type="range" id="brightnessSlider" min="50" max="200" value="100">
<span id="brightnessVal" class="panel-val">100%</span>
</div>
</div>
<!-- 嵌入链接面板 -->
<div id="embedPanel" class="float-panel hidden">
<div class="panel-title">生成嵌入链接 <img src="./icons/close.0fb8dc6e.png" class="panel-close" data-panel="embed" alt="关闭"></div>
<div class="panel-row">
<span>模型路径</span>
<input type="text" id="embedPath" placeholder="samples/xxx.stp 或 https://...">
</div>
<div class="panel-row">
<span>嵌入地址</span>
<input type="text" id="embedUrl" readonly>
</div>
<div class="panel-row">
<span>iframe 代码</span>
<textarea id="embedCode" rows="3" readonly></textarea>
</div>
<div class="panel-row embed-actions">
<button id="btnUploadModel" class="small-btn">上传当前模型</button>
<button id="btnCopyUrl" class="small-btn">复制链接</button>
<button id="btnCopyCode" class="small-btn">复制代码</button>
</div>
<div id="embedHint" class="embed-hint"></div>
</div>
<!-- 状态栏 -->
<div id="statusbar">
<span id="statusText">就绪 | 左键旋转 · 右键平移 · 滚轮缩放</span>
<span id="modelInfo" class="status-right"></span>
</div>
</div>
</div>
<!-- 零件右键菜单 -->
<div id="ctxMenu" class="hidden">
<div class="ctx-title" id="ctxMenuTitle"></div>
<div class="ctx-item" data-act="hide"><img src="./icons/view-tool-hideShow.png" alt=""><span>隐藏</span></div>
<div class="ctx-item" data-act="isolate"><img src="./icons/view-tool-conceal.png" alt=""><span>显示其他</span></div>
<div class="ctx-item" data-act="showAll"><img src="./icons/view-tool-hideShow.png" alt=""><span>全部显示</span></div>
<div class="ctx-sep"></div>
<div class="ctx-item" data-act="color"><img src="./icons/ico-set-color.png" alt=""><span>更改颜色</span></div>
<div class="ctx-item" data-act="transparent"><img src="./icons/view-tool-transparent.png" alt=""><span>透明</span></div>
<div class="ctx-sep"></div>
<div class="ctx-item" data-act="drag"><img src="./icons/view-tool-drag.png" alt=""><span>拖动</span></div>
<div class="ctx-item" data-act="reset"><img src="./icons/view-tool-singalReset.png" alt=""><span>复位</span></div>
</div>
<input type="file" id="fileInput" accept=".step,.stp,.STEP,.STP" style="display:none">
<!-- 加载遮罩(新迪同款弹跳圆点) -->
<div id="loading" class="hidden">
<div class="waiter"><div class="bounce1"></div><div class="bounce2"></div><div class="bounce3"></div></div>
<div id="loadingText">正在转换 STEP 模型...</div>
</div>
<!-- 拖拽提示 -->
<div id="dropOverlay" class="hidden"><div class="drop-box">松开鼠标加载 STEP 文件</div></div>
<script type="module" src="./app.js?v=5"></script>
</body>
</html>