基于GLTF的轻量化模型在浏览器展示及操作的方法转让专利

申请号 : CN202211004126.7

文献号 : CN115080890B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 运东伦张瑞丁谭

申请人 : 南京国睿信维软件有限公司

摘要 :

本发明涉及一种基于GLTF的轻量化模型在浏览器展示及操作的方法,涉及三维模型在浏览器展示领域,特别是GLTF格式模型在Chrome、Firefox等浏览器中展示。通过三维模型到GLTF的快速转换方案,用户可以直接在页面上对GLTF格式的模型进行展示查看,并能够对模型节点进行展开,同时支持对模型进行测量、标注、剖切、爆炸、旋转、平移、放大、缩小、复位、重新加载等操作,在一些情况下用户不必打开MCAD工具查看三维模型,极大提高模型查看展示效率。

权利要求 :

1.一种基于GLTF的轻量化模型在浏览器展示及操作的方法,其特征在于:包括以下步骤:步骤1:选择文件或者压缩文件,判断文件或者压缩文件的模型格式,选择的文件或者压缩文件中不包含后缀名为GLTF的文件时,弹出错误提醒,选择的文件或者压缩文件中包含后缀名为GLTF的文件时,在浏览器页面加载选择的模型并展示;

步骤2:对选择的文件或者压缩文件进行解析,若加载文件为压缩包,则先进行解压,将得到的文件转换成blob格式数据,分别初始化GLTFLoader、 DRACOLoader 、KTX2Loader,对blob格式数据通过loader的load方法加载,获取到模型的Scene场景信息进行展示;

通过对得到展示模型的数据结构提取,得到模型树状结构节点,从而进行模型结构树展示,并能够展开折叠结构树,支持对节点进行搜索及定位;

步骤3:根据模型的位置,对模型进行测量操作,包括点到点距离,点到直线距离,点到平面距离,并按照测量结果在页面显示;

点点测量根据鼠标点击依次在模型拾取模型两点startPoint和endPoint信息并获取所拾取点的三维坐标Vector信息,通过distanceTo方法计算两点之间距离,创建Label在页面进行展示;

点到直线测量根据鼠标点击分别拾取模型第一个点startPoint,拾取直线时需首先判断所拾取为线段并显示该线段,默认线段线框为隐藏,并获取startPoint到line上的投影点,通过distanceTo计算点到直线上投影的距离,创建Label在页面进行展示;

点到平面测量根据鼠标点击分别拾取模型第一个点startPoint,拾取直线时需首先判断所拾取为平面并显示该平面,默认平面线框为隐藏,并获取startPoint到plane上的投影点,通过distanceTo计算点到直线上投影的距离,创建Label在页面进行展示;

步骤4:在页面上能直接对模型进行标注操作,包括文本标注,序号标注,零件号标注,并能对已做标注内容进行修改、删除与保存操作;

点击页面模型,在模型中根据深度算法拾取点击的点,以拾取点为起始创建引线,终点创建文本,采用THREE.Sprite精灵文本组件初始化文本,通过sprite的position方法设置文本位置,Sprite是一个永远朝向相机的平面,创建出的文本框正对屏幕;编辑文本框时先获取文本框Sprite对象,获取其值,修改该值即可;删除文本框时通过Sprite对象remove方法删除已创建的文本组件;

步骤5:在页面能对模型六个方向进行剖切,并支持反向剖切,同时进行多个方向的剖切;

根据模型尺寸,计算并绘制外边框最大包络体box3,计算包络体中心点center,拖动长方形包络体某一个面按照向量vector对面进行移动,移动过处通过计算隐藏模型,并支持多面同时拖动对模型剖切;

步骤6:根据模型在CAD中视图,在浏览器页面能直接展示轻量化模型六视图,包括正视图、左视图、右视图、后视图、俯视图和仰视图;

通过场景中心点,及模型中心点,改变相机位置,来达到显示模型不同视图效果,正视图时设置相机位置如下:$mv.camera.position.set(center.x ‑ $mv.model.position.x, center.y ‑ $mv.model.position.y, center.z ‑ $mv.model.position.z + size * scale * distance);

步骤7:根据模型在PLM中属性信息及PMI标注信息,在浏览器页面分别展示;

通过JSON文件获取PMI标注信息在模型上的位置即为标注信息的起点为位置,标注文本通过JSON中相关信息创建SVG图片文档,通过SVGLoader加载SVG图片,使标注信息在页面进行展示。

2.根据权利要求1所述的基于GLTF的轻量化模型在浏览器展示及操作的方法,其特征在于:在查看过程中,如需查看其它模型,能直接在页面加载其它模型并重新显示。

3.根据权利要求1所述的基于GLTF的轻量化模型在浏览器展示及操作的方法,其特征在于:所述GLTF的轻量化模型包括gltf、bin、jpg、png、json五种类型的文件,启动时选中gltf后缀文件,bin、jpg、png、json文件自动加载。

4.根据权利要求1所述的基于GLTF的轻量化模型在浏览器展示及操作的方法,其特征在于:在浏览器中能够按照名称对节点进行搜索,节点与模型能进行交互,选中节点,对应模型会高亮显示,当选中模型时,对应的结构树节点高亮显示。

5.根据权利要求1所述的基于GLTF的轻量化模型在浏览器展示及操作的方法,其特征在于:所述浏览器界面上有测量按钮、标注按钮、爆炸按钮、剖切按钮、视图按钮和属性按钮,通过测量按钮,进行步骤3,

通过标注按钮,进行步骤4,

通过剖切按钮,进行步骤5,

通过视图按钮,进行步骤6,

通过爆炸按钮,对模型进行爆炸与复原操作,

通过属性按钮,查看当前加载模型属性信息。

6.根据权利要求1所述的基于GLTF的轻量化模型在浏览器展示及操作的方法,其特征在于:通过重新加载可复原按钮模型可重新加载或者复原居中。

说明书 :

基于GLTF的轻量化模型在浏览器展示及操作的方法

技术领域

[0001] 本发明涉及一种基于GLTF的轻量化模型在浏览器展示及操作的方法,属于GLTF数据格式的解析的技术领域。

背景技术

[0002] GLTF格式基于JSON格式进行构造,该格式描述了一个3D场景,包含对该3D场景描述的场景图scene,其中场景中独立的3D对象通过网格三角面片mesh的形式进行定义,另外在gltf中还定义了3D对象所使用的材质信息material,texture节点用来定义sampler对象和image图片对象,accessor是一个访问任意数据的抽象数据源。

发明内容

[0003] 为了解决上述技术问题,本发明提供一种基于GLTF的轻量化模型在浏览器展示及操作的方法,其具体技术方案如下:
[0004] 一种基于GLTF的轻量化模型在浏览器展示及操作的方法,包括以下步骤:
[0005] 步骤1:选择文件或者压缩文件,判断文件或者压缩文件的模型格式,选择的文件或者压缩文件中不包含后缀名为GLTF的文件时,弹出错误提醒,选择的文件或者压缩文件中包含后缀名为GLTF的文件时,在浏览器页面加载选择的模型并展示;
[0006] 步骤2:对选择的文件或者压缩文件进行解析,若加载文件为压缩包,则先进行解压,将得到的文件转换成blob格式数据,分别初始化GLTFLoader、 DRACOLoader 、KTX2Loader,对blob格式数据通过loader的load方法加载,获取到模型的Scene场景信息进行展示;
[0007] 通过对得到展示模型的数据结构提取,得到模型树状结构节点,从而进行模型结构树展示,并能够展开折叠结构树,支持对节点进行搜索及定位;
[0008] 步骤3:根据模型的位置,对模型进行测量操作,包括点到点距离,点到直线距离,点到平面距离,并按照测量结果在页面显示;
[0009] 点点测量根据鼠标点击依次在模型拾取模型两点startPoint和endPoint信息并获取所拾取点的三维坐标Vector信息,通过distanceTo方法计算两点之间距离,创建Label在页面进行展示;
[0010] 点到直线测量根据鼠标点击分别拾取模型第一个点startPoint,拾取直线时需首先判断所拾取为线段并显示该线段,默认线段线框为隐藏,并获取startPoint到line上的投影点,通过distanceTo计算点到直线上投影的距离,创建Label在页面进行展示;
[0011] 点到平面测量根据鼠标点击分别拾取模型第一个点startPoint,拾取直线时需首先判断所拾取为平面并显示该平面,默认平面线框为隐藏,并获取startPoint到plane上的投影点,通过distanceTo计算点到直线上投影的距离,创建Label在页面进行展示;
[0012] 步骤4:在页面上能直接对模型进行标注操作,包括文本标注,序号标注,零件号标注,并能对已做标注内容进行修改、删除与保存操作;
[0013] 点击页面模型,在模型中根据深度算法拾取点击的点,以拾取点为起始创建引线,终点创建文本,采用THREE.Sprite精灵文本组件初始化文本,通过sprite的position方法设置文本位置,Sprite是一个永远朝向相机的平面,创建出的文本框正对屏幕;编辑文本框时先获取文本框Sprite对象,获取其值,修改该值即可;删除文本框时通过Sprite对象remove方法删除已创建的文本组件;
[0014] 步骤5:在页面能对模型六个方向进行剖切,并支持反向剖切,同时进行多个方向的剖切;
[0015] 根据模型尺寸,计算并绘制外边框最大包络体box3,计算包络体中心点center,拖动长方形包络体某一个面按照向量vector对面进行移动,移动过处通过计算隐藏模型,并支持多面同时拖动对模型剖切;
[0016] 步骤6:根据模型在CAD中视图,在浏览器页面能直接展示轻量化模型六视图,包括正视图、左视图、右视图、后视图、俯视图和仰视图;
[0017] 通过场景中心点,及模型中心点,改变相机位置,来达到显示模型不同视图效果,如正视图时设置相机位置如下:
[0018] $mv.camera.position.set(center.x ‑ $mv.model.position.x, center.y ‑ $mv.model.position.y, center.z ‑ $mv.model.position.z + size * scale * distance);
[0019] 步骤7:根据模型在PLM中属性信息及PMI标注信息,在浏览器页面分别展示;
[0020] 通过JSON文件获取PMI标注信息在模型上的位置即为标注信息的起点为位置,标注文本通过JSON中相关信息创建SVG图片文档,通过SVGLoader加载SVG图片,使标注信息在页面进行展示。
[0021] 进一步的,在查看过程中,如需查看其它模型,能直接在页面加载其它模型并重新显示。
[0022] 进一步的,所述GLTF模型中包括了gltf、bin、jpg、png、json五种类型的文件,启动时选中gltf后缀文件,bin、jpg、png、json文件自动加载。
[0023] 进一步的,在浏览器中能够按照名称对节点进行搜索,节点与模型能进行交互,选中节点,对应模型会高亮显示,当选中模型时,对应的结构树节点高亮显示。
[0024] 进一步的,所述浏览器界面上有测量按钮、标注按钮、爆炸按钮、剖切按钮、视图按钮和属性按钮,
[0025] 通过测量按钮,进行步骤3,
[0026] 通过标注按钮,进行步骤4,
[0027] 通过剖切按钮,进行步骤5,
[0028] 通过视图按钮,进行步骤6,
[0029] 通过爆炸按钮,对模型进行爆炸与复原操作,
[0030] 通过属性按钮,查看当前加载模型属性信息。
[0031] 进一步的,通过重新加载可复原按钮模型可重新加载或者复原居中。
[0032] 本发明的有益效果是:
[0033] 本发明能够在浏览器上查看展示三维模型,并且不需安装插件,大大降低模型查看成本,极大提高加载模型速率,并能够对模型进行部分操作,可应用于模型审批、透明工厂等各个领域,极大提高工作效率。

附图说明

[0034] 图1是本发明的轻量化模型数据展示流程示意图,
[0035] 图2是本发明的轻量化模型展示页面范例,
[0036] 图3是本发明的总体功能架构。

具体实施方式

[0037] 现在结合附图对本发明作进一步详细的说明。这些附图均为简化的示意图,仅以示意方式说明本发明的基本结构,因此其仅显示与本发明有关的构成。
[0038] 如图1所示,本发明的基于GLTF的轻量化模型在浏览器展示的方法,包括以下步骤:
[0039] 步骤1:输入URL进入模型展示页面,展示默认加载模型。
[0040] 步骤2:点击加载模型按钮,选择GLTF模型(如果选择的文件不为GLTF格式则弹出报错信息),传入模型路径的参数path,调用模型加载方法。
[0041] load模型程序代码:
[0042]  $mv.loader.load(url, gltf => {
[0043] const scene = gltf.scene || gltf.scenes[0];
[0044]     if (scene.children.length<= 0) {
[0045]               // 模型为空,页面发送提示
[0046] document.getElementById('NoModel').click();
[0047]     }
[0048]     let box3 = new THREE.Box3().expandByObject(scene);
[0049]     let center = box3.getCenter(new THREE.Vector3());
[0050]     $mv.model = scene;
[0051]     $mv.inSideModel = scene;
[0052]     // 统一处理模型加载后续处理程序
[0053] traverseModel($mv);
[0054]     $mv.scene.add($mv.model);
[0055]     // centerModel($mv);
[0056] setCameraPosition($mv);
[0057]     // 旋转模型
[0058]     // $mv.Rotation.start();
[0059]     $mv.isModelLoaded = true;
[0060]     loading && loading['rendered'] && loading['rendered']();
[0061]     if (!loading || (loading &&enableLoading)) {
[0062] Vue.hideLoading();
[0063]     }
[0064] });
[0065] 步骤3:点击左侧结构树按钮,解析模型结构树节点json信息,并展示。
[0066] 解析模型结构树程序代码:
[0067] let setTree = {
[0068]         traverse: function (node) {
[0069]             if (node.type === 'Group' || node.type === "Object3D") {[0070]                 let icon = '';
[0071]                 if (node.type === 'Object3D') {
[0072]                     icon = '1';
[0073]                 } else if (node.type === 'Group') {
[0074]                     icon = '2';
[0075]                 }
[0076]                 let parentUUID = '';
[0077]                 if (node.parent) {
[0078] parentUUID = node.parent.uuid;
[0079]                 }
[0080]                 let newNode = {
[0081] uuid: node.uuid,
[0082]                     name: node.userData.name,
[0083]                     icon,
[0084]                     parent: {
[0085] uuid: parentUUID,
[0086]                     },
[0087]                     visible: true,
[0088]                     children: [],
[0089]                 };
[0090]                 $mv.treeDefaultChecked.push(newNode.uuid);
[0091]                 $mv.listNode[node.uuid] = node;
[0092]                 if (node.parent) {
[0093]                     if (dictObject3D[node.parent.uuid]) {[0094]                         dictObject3D[node.parent.uuid].children.push(newNode);
[0095]                     }
[0096]                 }
[0097]                 dictObject3D[newNode.uuid] = newNode;
[0098]                 $mv.LineSegmentsArray[node.uuid] = [];
[0099]                 if ($mv.Object3DArray === null) {
[0100]                     $mv.Object3DArray = newNode;
[0101]                 }
[0102]             } else if (node.type === 'LineSegments') {
[0103] this.setLineSegmentsToParentNode(node.parent.parent.uuid, node);
[0104]             }
[0105]         }
[0106] }
[0107] 如图2所示,本发明的基于GLTF的轻量化模型在浏览器操作的方法,包括以下步骤:
[0108] 步骤1:点击测量按钮,对模型进行相关测量。
[0109] 测量核心代码:
[0110]  let sphere = createdPoint(intersects[0].point);
[0111] pointsArray.push(sphere);
[0112] Group.add(sphere);
[0113] if (pointsArray.length>= 2) {
[0114]        let positions = [pointsArray[0].position.x,pointsArray[0].position.y,pointsArray[0].position.z, pointsArray[1].position.x,pointsArray[1].position.y,pointsArray[1].position.z];
[0115]        let line = createdLineSegments(pointsArray[0].position, pointsArray[1].position, 'helperLine');
[0116]        conststartPoint = new THREE.Vector3().copy(pointsArray[0].position);
[0117]        constendPoint = new THREE.Vector3().copy(pointsArray[1].position);
[0118]        let distance = startPoint.distanceTo(endPoint);
[0119]        Group.add(line);
[0120]        let x = (startPoint.x + endPoint.x) / 2;
[0121]        let y = (startPoint.y + endPoint.y) / 2;
[0122]        let z = (startPoint.z + endPoint.z) / 2;
[0123]        let  textContent = `${(distance * 1000).toFixed(2)}mm`;
[0124]        let Label = createdLabel([x, y, z], textContent);
[0125]        Group.add(Label);
[0126]        pointsArray = [];
[0127] }
[0128] 步骤2:点击标注按钮,对模型进行相关标注操作。
[0129] 标注核心代码:
[0130]               let sprite = new THREE.Sprite(spriteMaterial);
[0131] sprite.text = text;
[0132]         console.log(text);
[0133] sprite.group = group;
[0134] sprite.startPos = startPos;
[0135] sprite.endPos = endPos;
[0136] sprite.line = line;
[0137]         $mv.sprites.push(sprite);
[0138] sprite.scale.set(0, 0, 0);
[0139]         console.log(line.type);
[0140] group.add(line); // 添加
[0141] sprite.position.copy(endPos); // 设置sprite的位置
[0142] sprite.NumberSig = NumberSig;
[0143] sprite.modelSig = modelSig;
[0144]         sprite.dot = dot;
[0145] sprite.renderOrder = $mv.sprites.length;
[0146] sprite.user = user;
[0147] sprite.date = date;
[0148] sprite.visible = editable false : true;
[0149]         if (id) sprite.groupID = id;
[0150] group.add(sprite);
[0151] 步骤3:点击爆炸按钮,对模型进行爆炸与还原操作。
[0152] 爆炸核心代码:
[0153]  function expandModel(nodes, deep) {
[0154]        deepCount++;
[0155]        let children = [];
[0156]        nodes.forEach(node => {
[0157]               if ('Group' === node.type ||  'Object3D' === node.type) {
[0158]                      modelChildren.push(node);
[0159]                      if (node.position.x === 0 &&
[0160]                             node.position.y === 0 &&
[0161]                             node.position.z === 0) {
[0162]                             zeroObject3D.push(node);
[0163]                      }
[0164]                       modelChildrenSrcPosition.push(node.position.clone());
[0165]                      modelChildrenCenterPosition.push(new THREE.Box3().expandByObject(node).getCenter(new THREE.Vector3()));
[0166]               }
[0167]               if (node.children&&node.children.length> 0) {[0168]                      node.children.forEach(child => {
[0169]                             children.push(child);
[0170]                      });
[0171]               }
[0172]        });
[0173]        if (children.length> 0) {
[0174]               expandModel(children, deep);
[0175]        }
[0176] }
[0177] 步骤4:点击剖切按钮,对模型进行剖切操作。
[0178] 剖切核心代码:
[0179]  initClipBox() {
[0180]        const box3 = utils_getBox(this.obj, this.obj);
[0181]        var center = new THREE.Vector3();
[0182]        box3.getCenter(center);
[0183]        var p = new THREE.Vector3(
[0184]               this.obj.position.x,
[0185]               this.obj.position.y,
[0186]               this.obj.position.z
[0187]        );
[0188]        vardisVector = p.sub(center);
[0189]        this.low = box3.min;
[0190]        this.high = box3.max;
[0191]        this.halfDisVector = new THREE.Vector3(
[0192]               disVector.x / 2,
[0193]               disVector.y / 2,
[0194]               disVector.z / 2
[0195]        );
[0196]        this.low_init.copy(this.low);
[0197]        this.high_init.copy(this.high);
[0198]        this.group = new Group();
[0199]        this.initPlanes();
[0200]        this.initVertices();
[0201]        this.initFaces();
[0202]        this.faces.forEach((face) => {
[0203]               face.material.transparent = true;
[0204]               face.material.opacity = 0.3;
[0205]        });
[0206]        console.log(this.faces);
[0207]        this.initLines();
[0208]        this.scene.add(this.group);
[0209] }
[0210] 步骤5:点击视图按钮,对模型进行视图展示。
[0211] 视图核心代码:
[0212]  $mv.camera.position.set(center.x ‑ $mv.model.position.x, center.y ‑ $mv.model.position.y, center.z ‑ $mv.model.position.z + size * scale * distance)。
[0213] 依据本发明的理想实施例为启示,通过上述的说明内容,相关工作人员完全可以在不偏离本项发明技术思想的范围内,进行多样的变更以及修改。