From 6b8c973f61d0f0860a621a9480fd19d0b77a932d Mon Sep 17 00:00:00 2001 From: Matteo Boscolo Date: Tue, 2 Jul 2024 11:33:00 +0200 Subject: [PATCH] Progress on webgl 3mf file format support --- plm_web_3d/controllers/main.py | 5 ++ plm_web_3d/models/ir_attachment.py | 37 +++++++++++-- .../static/src/js/OdooCADApplication.js | 17 +++++- .../static/src/js/lib/odoocad/loaders.js | 52 +++++++++++++++++-- .../static/src/js/lib/odoocad/odoocad.js | 3 +- 5 files changed, 105 insertions(+), 9 deletions(-) diff --git a/plm_web_3d/controllers/main.py b/plm_web_3d/controllers/main.py index 30d5f6d3..55a891bf 100755 --- a/plm_web_3d/controllers/main.py +++ b/plm_web_3d/controllers/main.py @@ -39,6 +39,11 @@ def download_treejs_model(self, document_id): return response return Response(response="Document Not Found %r " % document_id, status=500) + @route('/plm/get_document_relation//', type='http', auth='public') + def get_document_relation(self, document_id, document_name): + return request.env['ir.attachment'].sudo().get_document_relation_dict(document_id, document_name) + + def document_extra(self, document): """ this function id for customising the documents attributes diff --git a/plm_web_3d/models/ir_attachment.py b/plm_web_3d/models/ir_attachment.py index ede7aa9a..ea2f8a90 100644 --- a/plm_web_3d/models/ir_attachment.py +++ b/plm_web_3d/models/ir_attachment.py @@ -24,6 +24,7 @@ @author: mboscolo ''' import os +import json import logging import datetime from odoo import models @@ -34,7 +35,7 @@ from datetime import timedelta from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT import urllib.parse -SUPPORTED_WEBGL_EXTENTION = ['.gltf','.glb','.fbx','.obj','.wrl','.json', '.stl','.svg', '.dxf'] +SUPPORTED_WEBGL_EXTENTION = ['.3mf','.gltf','.glb','.fbx','.obj','.wrl','.json', '.stl','.svg', '.dxf'] # # class IrAttachment(models.Model): @@ -77,7 +78,7 @@ def get_url_for_3dWebModel(self): url_params = urllib.parse.urlencode({'document_id': rel.child_id.id, 'document_name': rel.child_id.name}) if url_params: - return "%s/plm/show_treejs_model?%s" % (base_url, url_params) + return f"{base_url}/plm/show_treejs_model?{url_params}" def show_releted_3d(self): for ir_attachment in self: @@ -88,5 +89,33 @@ def show_releted_3d(self): 'type': 'ir.actions.act_url', 'target': self, 'url': url - } - \ No newline at end of file + } + + def get_all_relation(self, document_id, exte): + out={} + if exte in document_id.name: + out[document_id.id] = document_id.name + for child_attachment_id in self.getRelatedHiTree(document_id.id): + if exte in self.browse(child_attachment_id).name: + out[child_attachment_id.id]=child_attachment_id.name + return out + + def get_document_relation_dict(self, document_id, document_name): + out = {} + for ir_attachment in self.browse(document_id): + _name, exte = os.path.splitext(ir_attachment.name) + for product_product_id in ir_attachment.linkedcomponents: + for att_id in product_product_id.linkeddocuments: + out.update(self.get_all_relation(att_id,exte)) + for sub_bom_children_id in product_product_id.bom_ids.bom_line_ids.mapped("product_id"): + for att_id in sub_bom_children_id.linkeddocuments: + out.update(self.get_all_relation(att_id,exte)) + # + + if not out: + out = {document_id: document_name} + else: + if document_id in out: + del out[document_id] + return json.dumps(out) + \ No newline at end of file diff --git a/plm_web_3d/static/src/js/OdooCADApplication.js b/plm_web_3d/static/src/js/OdooCADApplication.js index 07c256b6..07856a20 100644 --- a/plm_web_3d/static/src/js/OdooCADApplication.js +++ b/plm_web_3d/static/src/js/OdooCADApplication.js @@ -262,7 +262,22 @@ function init() { * inizialize OdooCAD */ OdooCad = new ODOOCAD.OdooCAD(scene); - OdooCad.load_document(document_id, document_name); + var xmlhttp = new XMLHttpRequest(); + xmlhttp.onreadystatechange = function() { + if (this.readyState == 4 && this.status == 200) { + var documents_dict = JSON.parse(this.responseText); + for (var prop in documents_dict) + { + var name = documents_dict[prop]; + OdooCad.load_document(prop, name); + console.log("Loading document " + name); + } + } + }; + xmlhttp.open("GET", "../plm/get_document_relation/"+ document_id + "/" + document_name, true); + xmlhttp.send(); + + } function getCameraCSSMatrix(matrix) { diff --git a/plm_web_3d/static/src/js/lib/odoocad/loaders.js b/plm_web_3d/static/src/js/lib/odoocad/loaders.js index f8a8c6d6..5baa5f60 100644 --- a/plm_web_3d/static/src/js/lib/odoocad/loaders.js +++ b/plm_web_3d/static/src/js/lib/odoocad/loaders.js @@ -7,6 +7,7 @@ import { OBJLoader } from '../three.js/examples/jsm/loaders/OBJLoader.js'; import { VRMLLoader } from '../three.js/examples/jsm/loaders/VRMLLoader.js'; import { STLLoader } from '../three.js/examples/jsm/loaders/STLLoader.js'; import { SVGLoader } from '../three.js/examples/jsm/loaders/SVGLoader.js'; +import { ThreeMFLoader } from '../three.js/examples/jsm/loaders/3MFLoader.js'; import { DXFLoader } from "./DXFLoader.js" @@ -17,6 +18,7 @@ const vRMLLoader = new VRMLLoader(); const stlLoader = new STLLoader(); const svgloader = new SVGLoader(); const dxfLoader = new DXFLoader(); +const threeMFLoader = new ThreeMFLoader(); const loader = new THREE.ObjectLoader(); @@ -76,7 +78,10 @@ class Loader { } if (['dxf'].includes(exte)){ this.loadDxf(document_name, url); - } + } + if (['3mf'].includes(exte)){ + this.load3mf(document_name, url); + } } loadDxf(document_name, url){ var self=this; @@ -114,6 +119,47 @@ class Loader { alert("Unable to load the " + document_name + " err: " + err); }); } + + load3mf(document_name, url){ + + var load3emfObj = function(args){ + if(args.type=="Group"){ + var i; + var children = args.children; + for (i = 0; i < children.length; i++) { + if(children[i].type=="Mesh"){ + self.odooCad.addItemToScene(children[i]); + } + else { + load3emfObj(children[i]); + } + } + } + } + + var self=this; + threeMFLoader.load( url, function ( mfArgs ) { + var children = mfArgs.children; + var i; + + for (i = 0; i < children.length; i++) { + load3emfObj(children[i]); + } + + + + }, + function ( xhr ) { + var percentage = (xhr.loaded / xhr.total) * 100; + self.progress_bar.style.width = percentage + '%'; + console.log(self.progress_bar.style.width + ' loaded') + }, + + function ( err ) { + alert("Unable to load the " + document_name + " err: " + err); + }); + } + loadfBXLoader(document_name, url){ var self=this; fBXLoader.load( url, function ( gltf ) { @@ -136,8 +182,8 @@ class Loader { loadoBJLoader(document_name, file_path){ var self=this; - oBJLoader.load( file_path, function ( gltf ) { - var children = gltf.children; + oBJLoader.load(file_path, function ( objArgs ) { + var children = objArgs.children; var i; for (i = 0; i < children.length; i++) { self.odooCad.addItemToScene(children[i]); diff --git a/plm_web_3d/static/src/js/lib/odoocad/odoocad.js b/plm_web_3d/static/src/js/lib/odoocad/odoocad.js index 84cc10f5..eb3518a5 100644 --- a/plm_web_3d/static/src/js/lib/odoocad/odoocad.js +++ b/plm_web_3d/static/src/js/lib/odoocad/odoocad.js @@ -28,7 +28,8 @@ class OdooCAD{ */ object.receiveShadow=true; object.castShadow=true; - var material = new THREE.MeshPhongMaterial( { color: 0x444444 } ); + var randomColor = "#000000".replace(/0/g,function(){return (~~(Math.random()*16)).toString(16);}); + var material = new THREE.MeshPhongMaterial( { color:randomColor } ); object.traverse( function ( child ) {