A three-dimensional model adaptive lightweight processing method and system

The adaptive lightweight system for 3D models, which utilizes multi-process concurrent processing and modular design, solves the adaptability problem of 3D models across different operating systems and engineering digital delivery platforms. It achieves efficient, cross-platform lightweight processing and compression, ensuring the accuracy of the model and the integrity of its semantic information.

CN122115809APending Publication Date: 2026-05-29OFFSHORE OIL ENG CO LTD

Patent Information

Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
OFFSHORE OIL ENG CO LTD
Filing Date
2025-12-29
Publication Date
2026-05-29

AI Technical Summary

Technical Problem

Existing technologies struggle to achieve efficient and lightweight processing while maintaining the accuracy of 3D models, especially for large and complex structural models in the field of marine engineering. Furthermore, traditional methods are difficult to adapt to different operating system environments and integrate into digital delivery and maintenance platforms for engineering projects.

Method used

The 3D model adaptive lightweight processing system adopts a multi-process concurrent processing mechanism, supports the parsing and conversion of various industrial 3D model formats, and achieves efficient model compression and cross-platform compatibility through MQTT asynchronous message communication and modular design, combined with triangular mesh indexing technology and lossless compression.

Benefits of technology

It achieves unified lightweight processing of various 3D model formats, with a compression rate of over 50%, supports multiple operating systems, and ensures that the model retains engineering semantic information in engineering delivery and operation and maintenance applications, adapting to different deployment scenarios.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN122115809A_ABST
    Figure CN122115809A_ABST
Patent Text Reader

Abstract

The application discloses a kind of three-dimensional model adaptive lightweight processing method and system, the three-dimensional model adaptive lightweight processing method uses C++ and C# mixed development mode, combined with.NET Core cross-platform framework, is divided into business layer and data processing layer: business layer is developed using C#, responsible for service management, MQTT communication and three-party system docking;Data processing layer is developed using C++, focuses on file analysis, mesh partitioning and face reduction optimization.System supports NWD, FBX, IFC, RVM, VUE and the analysis and conversion of multiple industrial three-dimensional model formats, reduce vertex redundancy through triangular mesh index technology, combined with WebP lossless compression material map, realize model volume compression rate is more than 50%.Asynchronous message communication is realized using MQTT protocol, supports JSON instruction control conversion process, can receive conversion request including model UUID, file type, scaling ratio and LOD level and other parameters, while guaranteeing the integrity of model engineering semantic information, significantly reduce model storage and transmission cost.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] This invention belongs to the field of digital delivery technology for engineering, and in particular relates to a method and system for adaptive lightweight processing of three-dimensional models. Background Technology

[0002] With the widespread application of Computer-Aided Design (CAD) and Building Information Modeling (BIM) technologies in the engineering field, a large amount of complex 3D model data is generated during the engineering design process. These models typically contain massive amounts of geometric information and engineering attributes, resulting in huge file sizes that are difficult to use directly in resource-constrained environments (such as offshore platforms). Traditional 3D model processing faces the following challenges in the digital delivery of engineering projects: First, the support for complex industrial-grade models (such as NWD, FBX, IFC, etc.) is incomplete, making it difficult to handle large-scale engineering models. Second, the model quality is severely compromised during the lightweighting process, affecting the accuracy of engineering applications. Third, there is a lack of unified cross-platform solutions, making it difficult to adapt to different operating system environments. Finally, the integration with engineering digital delivery and maintenance platforms is low, failing to meet the needs of engineering lifecycle management.

[0003] Especially in the field of marine engineering, the 3D model data of complex structures such as large jackets and floating facilities is enormous. Traditional processing methods are difficult to achieve efficient and lightweight processing while ensuring model accuracy, which seriously restricts the application of 3D technology in the entire life cycle of engineering design, construction and operation.

[0004] Therefore, there is an urgent need to design an adaptive lightweight processing method and system for 3D models to solve the problems mentioned above. Summary of the Invention

[0005] The purpose of this invention is to provide an adaptive lightweight processing method and system for 3D models, which achieves efficient and high-fidelity lightweight processing of 3D models, improves the transmission efficiency and rendering performance of models in network environments, and maintains the integrity of the engineering semantic information of the models. This solves the problem that traditional processing methods in the background technology are unable to achieve efficient lightweighting while ensuring model accuracy, which seriously restricts the application of 3D technology in the entire life cycle of engineering design, construction and operation and maintenance.

[0006] To achieve the above objectives, the specific technical solution of the three-dimensional model adaptive lightweight processing method of the present invention is as follows: An adaptive lightweight processing method for 3D models includes: The business layer, developed in C#, is responsible for service management, MQTT communication, and integration with third-party systems, interacting with the underlying C++ module through unmanaged calls. The data processing layer, developed in C++, focuses on file parsing, mesh generation, and polygon reduction optimization. The business layer implements service startup, shutdown, and status monitoring functions, and provides a REST API interface for external systems to call. The data processing layer contains multiple format-specific processing modules. The conversion functions for different formats are implemented as independent modules, and are provided for calling by a unified external encapsulation interface. The lightweight processing system supports the parsing and conversion of various industrial 3D model formats, including NWD, FBX, IFC, RVM, VUE, and STP / STEP. It receives conversion requests containing parameters such as model UUID, file type, scaling ratio, and LOD level via the MQTT protocol. It uses triangular mesh indexing technology to reduce vertex redundancy and combines WebP lossless compression of material textures to achieve a model volume compression rate of over 50%, and outputs lightweight models in AURR, FBX, or OBJ formats.

[0007] Furthermore, the business layer obtains the list of models to be converted from the MQTT message queue through the GetMQModelConvertList method. This method receives the application configuration object, establishes an MQTT connection and subscribes to a specified topic, deserializes the message body into a RocketMQModelConvertEntity object, converts it into the internally unified ModelConvertEntity format, combines the complete source file path, encapsulates the conversion parameters, and returns a standardized list of model conversion tasks.

[0008] Furthermore, the lightweight processing of the RVM format model includes: Parse RVM files using parseRVM to construct the model hierarchy; Parse geometry data using parse_prim; Use Tessellator to convert the geometry into a triangular mesh; Duplicate vertices are removed using RemoveDuplicateVertex, and normals are corrected using CorrectNormal. Collect processed mesh data using ExportMesh::geometry; Data is added to the buffer using TriangleMesh::AddMesh, serialized to aurr format, and written to a file.

[0009] Furthermore, the lightweight processing of the VUE format model includes: The Vue format file is parsed using VueFrExporter to obtain the BaseComponent array; Iterate through each component and create a processing context; The geometric data is converted into a triangular mesh using GeometryTracer; Use MemoryHelper for managed / unmanaged memory conversion; Triangulation optimization is performed using the Earcut algorithm; Compress data such as vertices, normals, and indices; The final output is in aurr format.

[0010] Furthermore, the lightweight processing of the NWD format model includes: Use the Open Design Alliance API to read Navisworks model files; The model structure is parsed using OdNwModelItem, and model items and their attributes are extracted. The model is triangulated to generate triangular mesh data; The vector difference, cross product, and normalization are calculated using the Sub, Cross, and Normalized methods, and then the normal vector is calculated. The normal vectors of the triangular mesh are calculated using the CalNormal method; Convert the processed data to AURR format and output it.

[0011] Furthermore, the lightweight processing of the FBX / IFC format model includes: Load FBX / IFC format models using the Assimp library; Perform mesh processing such as triangulation, vertex merging, and normal calculation; Optimize the grid structure to reduce redundant data; Data compression is performed using the Open3DGC encoder; Convert the compressed data to AURR format; The compressed data is output using the glTFExporter::ExportMesh method.

[0012] Furthermore, the lightweight processing of the STP / STEP format model includes: Read CAD files using STEPControl_Reader or STPControl_Reader; Convert CAD entities into a TopoDS_Shape hierarchy; Triangulation is performed using BRepMesh_IncrementalMesh; Extract information such as vertices, normals, and colors; The SetShape method can be used to process different types of shape data. Write OBJ format files and edge data.

[0013] An adaptive lightweight 3D model processing system employs a multi-process concurrent processing mechanism, which can handle multiple model conversion tasks simultaneously. By using an adjustable polygon reduction ratio parameter, it achieves a balance between model complexity and visual quality, ensuring that the lightweight model can still be used for engineering delivery and operation and maintenance applications.

[0014] The adaptive lightweight processing method for three-dimensional models of the present invention has the following advantages: (1) This invention achieves unified lightweight processing of various industrial 3D model formats, with a compression rate of over 50%, significantly reducing model storage and transmission costs.

[0015] (2) The present invention adopts a modular design. The conversion functions of different formats are implemented by independent modules and encapsulated through a unified interface, which facilitates function expansion and maintenance.

[0016] (3) This invention supports MQTT asynchronous message communication and can be seamlessly integrated into the engineering digital delivery and maintenance platform to realize automated processing.

[0017] (4) This invention has strong cross-platform compatibility and supports multiple operating system environments such as Windows, Linux, and Kylin V10sp1, adapting to different deployment scenarios.

[0018] (5) The present invention retains the engineering semantic information of the model, ensuring that the lightweight model can still be used for engineering delivery and operation and maintenance applications. Attached Figure Description

[0019] Figure 1 This is a flowchart of the adaptive lightweight processing method for three-dimensional models according to the present invention; Figure 2 This is a processing diagram of the module for obtaining the model list in the adaptive lightweight processing method for 3D models of the present invention; Figure 3 This is a flowchart of the RVM format processing method for adaptive lightweight 3D model processing in this invention. Figure 4 This is a flowchart of the VUE format processing method for the adaptive lightweighting of 3D models in this invention. Figure 5 This is a flowchart of the NWD format processing method for the adaptive lightweighting of 3D models in this invention. Figure 6 This is a flowchart of the FBX / IFC format processing method for the adaptive lightweight processing of three-dimensional models in this invention. Figure 7 This is a flowchart of the STP / STEP format for the adaptive lightweight processing method of the three-dimensional model of the present invention. Detailed Implementation

[0020] To make the objectives, technical solutions, and advantages of the embodiments of the present invention clearer, the technical solutions of the embodiments of the present invention will be clearly and completely described below with reference to the accompanying drawings. Obviously, the described embodiments are only some embodiments of the present invention, not all embodiments. Based on the embodiments of the present invention, all other embodiments obtained by those skilled in the art without creative effort are within the scope of protection of the present invention.

[0021] Those skilled in the art will understand that although some embodiments herein include certain features included in other embodiments but not others, combinations of features from different embodiments are intended to be within the scope of the invention and form different embodiments. For example, in the claims, any of the claimed embodiments can be used in any combination.

[0022] The following is a reference to the appendix. Figure 1 To be continued Figure 7 The present invention describes a three-dimensional model adaptive lightweight processing method.

[0023] As a preferred embodiment, 1. System architecture: The 3D model adaptive lightweight processing method of the present invention includes: The business layer, developed in C#, is responsible for service management, MQTT communication, and integration with third-party systems, interacting with the underlying C++ module through unmanaged calls. The data processing layer, developed in C++, focuses on file parsing, mesh generation, and polygon reduction optimization. The business layer implements service startup, shutdown, and status monitoring functions, and provides a REST API interface for external systems to call. The data processing layer contains multiple format-specific processing modules. The conversion functions for different formats are implemented as independent modules, and are provided for calling by a unified external encapsulation interface. The lightweight processing system supports the parsing and conversion of various industrial 3D model formats, including NWD, FBX, IFC, RVM, VUE, and STP / STEP. It receives conversion requests containing parameters such as model UUID, file type, scaling ratio, and LOD level via the MQTT protocol. It uses triangular mesh indexing technology to reduce vertex redundancy and combines WebP lossless compression of material textures to achieve a model volume compression rate of over 50%, and outputs lightweight models in AURR, FBX, or OBJ formats.

[0024] Furthermore, the business layer obtains the list of models to be converted from the MQTT message queue through the GetMQModelConvertList method. This method receives the application configuration object, establishes an MQTT connection and subscribes to a specified topic, deserializes the message body into a RocketMQModelConvertEntity object, converts it into the internally unified ModelConvertEntity format, combines the complete source file path, encapsulates the conversion parameters, and returns a standardized list of model conversion tasks.

[0025] As a preferred embodiment, the two core modules are implemented. 2.1 Model-analysis-project (GetMQModelConvertList method) 2.1.1 Functional Overview and Code (1) Function Overview: The GetMQModelConvertList method is used to retrieve a list of models to be converted from the MQTT message queue and convert them to an internal unified format. (2) Method parameters: <param name="appSettings"> The application configuration object must contain: - MQInfo: MQTT connection configuration - MqttServerIp: string Server IP - MqttPort: int service port - MqttUserName: string Authentication username - MqttPassword: string authentication password - MqttReceiveTopic: string Subscribed topic - FilePath: File path configuration - Source: string Source file directory - Process: string (Processing intermediate directories) - Target: string Output directory (3) Method code: public List <modelconvertentity>GetMQModelConvertList(AppSettings appSettings) { / / Initialize the MQTT client var mqHelper = new MQTTHelper( appSettings.MQInfo.MqttServerIp, appSettings.MQInfo.MqttPort, appSettings.MQInfo.MqttUserName, appSettings.MQInfo.MqttPassword, "client-"+Guid.NewGuid().ToString("N")); / / Subscribe to the message topic var receiveTopic = appSettings.MQInfo.MqttReceiveTopic; mqHelper.AddTopic(receiveTopic).Wait(); var modelList = new List <modelconvertentity>(); / / Message processing callback mqHelper.OnMessage((topic, data, arg) => { try { var modelInfo = JsonConvert.DeserializeObject <rocketmqmodelconvertentity>(data); modelList.Add(new ModelConvertEntity { Uuid = modelInfo.Uuid, FileType = modelInfo.FileType, FilePath = Path.Combine(appSettings.FilePath.Source,$"{modelInfo.Uuid}.{modelInfo.FileType}"), ConvertParams = new { Scale = modelInfo.Scale > 0 ? modelInfo.Scale :1.0, LodCount = modelInfo.LodLevel > 0 ?modelInfo.LodLevel : 3 } }); } catch(Exception ex) { _logger.LogError(ex, "MQTT message processing error"); } }); return modelList; } 2.1.2 Core Logic Input: Receive JSON format conversion requests via MQTT deal with: Establish an MQTT connection and subscribe to the specified topic The deserialized message body is a RocketMQModelConvertEntity object. Convert to the internally unified ModelConvertEntity format Combine the complete source file path Encapsulation conversion parameters Output: Returns a list of standardized model transformation tasks. 2.1.3 Code snippets corresponding to process nodes Initialize the MQTT connection: new MQTTHelper(serverIp, port, userName, password, clientId); Subscribe to the topic: mqHelper.AddTopic(receiveTopic).Wait(); Message Analysis: JsonConvert.DeserializeObject <rocketmqmodelconvertentity>(data); Format conversion: new ModelConvertEntity { Uuid = modelInfo.Uuid, FileType = modelInfo.FileType, / / ...other field mappings } Path combinations: Path.Combine(appSettings.FilePath.Source, $"{modelInfo.Uuid}.{modelInfo.FileType}") Error handling: logger.LogError(ex, "MQTT message processing error").

[0026] Furthermore, the lightweight processing of the RVM format model includes: Parse RVM files using parseRVM to construct the model hierarchy; Parse geometry data using parse_prim; Use Tessellator to convert the geometry into a triangular mesh; Duplicate vertices are removed using RemoveDuplicateVertex, and normals are corrected using CorrectNormal. Collect processed mesh data using ExportMesh::geometry; Data is added to the buffer using TriangleMesh::AddMesh, serialized to aurr format, and written to a file.

[0027] Preferably, 2.2 Lightweight processing of RVM format models 2.2.1 Functional Overview and Code 2.2.1.1 RVM parsing module 2.2.1.1.1 parseRVM - Entry point for RVM file parsing (1) Function Overview: Parses RVM format 3D model files and constructs model hierarchical structure. (2) Method parameters: Store* store: Data storage object Logger: Log callback const char* path: file path const void* ptr: File data pointer size_t size: Data size (3) Method code bool parseRVM(class Store* store, Logger logger, const char* path, const void * ptr, size_t size) { char buf

[1024] ; Context ctx = { .store = store, .logger = logger, .buf = buf, .buf_size = sizeof(buf) }; / / ...parse logic... } 2.2.1.1.2 parse_prim - Geometry parsing (1) Function Overview: Analyzes geometric blocks such as PRIM / OBST / INSU (2) Method parameters: Context* ctx: Context resolution const char* base_ptr: Data start pointer const char* curr_ptr: Current parsing position const char* end_ptr: End position of data uint32_t chunk_id: Block ID uint32_t expected_next_chunk_offset: Expected offset of the next chunk (3) Method code const char* parse_prim(Context* ctx, const char* base_ptr, constchar* curr_ptr, const char* end_ptr, uint32_t chunk_id, uint32_t expected_next_chunk_offset) { / / ...geometry analysis logic... } 2.2.1.2 Triangulation Module 2.2.1.2.1 Tessellator - Triangulation Processor (1) Function Overview: Converts geometry into triangular mesh. (2) Method parameters: Logger: Log callback float tolerance: partitioning tolerance float cullLeafThreshold: Culling threshold float cullGeometryThreshold: Geometry culling threshold unsigned maxSamples: Maximum number of samples (3) Method code: Tessellator tessellator(logger, tolerance, cullLeafThreshold,cullGeometryThreshold, maxSamples); store->(&tessellator); 2.2.1.2.2 TriangulationFactory - Geometric Triangulation (1) Function Overview: Converts basic geometry into triangular meshes (2) Method parameters: Arena* arena: Memory allocator const Geometry* geo: Geometry data float scale: scaling factor (3) Method code Triangulation* TriangulationFactory::pyramid(Arena* arena, constGeometry* geo, float scale) { / / ...triangulation of pyramid geometry... } 2.2.1.3 Mesh Processing Module 2.2.1.3.1 RemoveDuplicateVertex - Vertex deduplication (1) Function Overview: Remove duplicate vertices and optimize mesh data (2) Method parameters: std::vector <float>& inVerties: Input Vertex std::vector <float>& inNormals: Input normals std::vector<unsigned int> & inIndices: Input index std::vector <float>& outVerties: Output Vertices std::vector <float>&outNormals: Output normals std::vector<unsigned int> &outIndices: Output index (3) Method code void MeshUtils::RemoveDuplicateVertex(std::vector <float>& inVerties,std::vector <float>& inNormals, std::vector<unsigned int>& inIndices, std::vector <float>& outVerties, std::vector <float>& outNormals, std::vector<unsigned int> & outIndices) { / / ...Vertex deduplication logic... } 2.2.1.3.2 CorrectNormal - Normal Correction (1) Functional Overview: Corrects the direction of the mesh normal. (2) Method parameters: std::vector <float>& verties: Vertex data std::vector<unsigned int> & indices: Index data std::vector <float>normals: normal data (3) Method code void MeshUtils::CorrectNormal(std::vector <float>& verties, std::vector<unsigned int>& indices, std::vector <float>normals) { / / ...normal correction logic... } 2.2.1.4 AURR format export module 2.2.1.4.1 ExportMesh::geometry - Geometry Processing (1) Function Overview: Processes individual geometry data and adds it to the mesh. (2) Method parameters: Geometry* geometry: Pointer to geometry data (3) Method code void MeshUtils::ExportMesh::geometry(Geometry* geometry) { Mesh& mesh = m_meshes.back(); / / ...processing vertex, normal, and index data... if (geometry->triangulation) { auto* tri = geometry->triangulation; / / Add vertex and normal data for (size_t i = 0; i < 3 * tri->vertices_n; i += 3) { auto p = scale * mul(geometry->M_3x4, makeVec3f(tri->vertices + i)); vertices.push_back(px); vertices.push_back(py); vertices.push_back(pz); Vec3f n = normalize(mul(makeMat3f(geometry->M_3x4.data),makeVec3f(tri->normals + i))); normals.push_back(nx); normals.push_back(ny); normals.push_back(nz); } / / Add index data for (size_t i = 0; i < 3 * tri->triangles_n; i += 3) { indices.push_back(tri->indices[i + 0] + offset); indices.push_back(tri->indices[i + 1] + offset); indices.push_back(tri->indices[i + 2] + offset); } } } 2.2.1.4.2 TriangleMesh::AddMesh - Add Mesh Data (1) Function Overview: Adds the processed grid data to the aurr format buffer. (2) Method parameters: MeshUtils::Mesh& mesh: Input mesh data (3) Method code void Convert::TriangleMesh::AddMesh(MeshUtils::Mesh& mesh) { / / Add vertex data std::copy(mesh.vertices.begin(), mesh.vertices.end(), std::back_inserter(*vertices)); / / Add normal data std::copy(mesh.normals.begin(), mesh.normals.end(), std::back_inserter(*normals)); / / Add index data for (size_t i = 0; i < mesh.indices.size(); i++) { indices->push_back(startIndex + mesh.indices[i]); } / / Add color data colors->push_back(mesh.color.r * 256); colors->push_back(mesh.color.g * 256); colors->push_back(mesh.color.b * 256); colors->push_back(mesh.color.a * 256); } 2.2.2 Core Logic Parsing phase: Parse the RVM file using parseRVM, construct the model hierarchy, and parse the geometric data. Triangulation stage: Using Tessellator to convert geometry into triangular meshes, handling curved surfaces and complex shapes. Mesh optimization: Remove duplicate vertices using RemoveDuplicateVertex, correct normals using CorrectNormal, and calculate bounding box and mesh properties. Data preparation: Collect processed mesh data using ExportMesh::geometry. AURR format export: Add data to the buffer via TriangleMesh::AddMesh, serialize it into binary format, and write it to a file.

[0028] 2.2.3 Code snippets corresponding to process nodes Parsing RVM files bool parseRVM(class Store* store, Logger logger, const char* path, const void * ptr, size_t size) { / / Initialize the parsing context Context ctx = { .store = store, .logger = logger, .buf = buf, .buf_size = sizeof(buf) }; / / Parse file header curr_ptr = parse_head(&ctx, path, base_ptr, curr_ptr, end_ptr,expected_next_chunk_offset); / / Parse model data curr_ptr = parse_modl(&ctx, base_ptr, curr_ptr, end_ptr, expected_next_chunk_offset); / / Analyze geometry data while (curr_ptr < end_ptr) { curr_ptr = parse_prim(&ctx, base_ptr, curr_ptr, end_ptr, id_chunk_id, expected_next_chunk_offset); } } Building a model hierarchy const char* parse_modl(Context* ctx, const char* base_ptr, constchar* curr_ptr, const char* end_ptr, uint32_t expected_next_chunk_offset) { / / Create model node auto * g = ctx->store->newNode(ctx->group_stack.back(), Node::Kind::Model); ctx->group_stack.push_back(g); / / Read model properties curr_ptr = read_string(&g->model.project, ctx->store, curr_ptr,end_ptr); curr_ptr = read_string(&g->model.name, ctx->store, curr_ptr, end_ptr); } Geometric Triangulation Triangulation* TriangulationFactory::pyramid(Arena* arena, constGeometry* geo, float scale) { / / Triangulation of pyramid geometry tri->vertices_n = (shell ? 2 * samples : 0) + (cap[0] ? samples :0) + (cap[1] ? samples : 0); tri->vertices = (float*)arena->alloc(3 * sizeof(float)*tri->vertices_n); / / ...Generate triangular mesh... } Mesh optimization processing void MeshUtils::RemoveDuplicateVertex(std::vector <float>& inVerties,std::vector <float>& inNormals, std::vector<unsigned int>& inIndices, std::vector <float>& outVerties, std::vector <float>& outNormals, std::vector<unsigned int> & outIndices) { / / Vertex hash deduplication std::unordered_map <size_t, std::vector <info>> remap; / / ...Rebuild index buffer... } void MeshUtils::Mesh::CalBoundBox() { / / Calculate bounding box for (size_t i = 3; i < vertices.size(); i += 3) { box.min.x = std::min(box.min.x, vertices[i]); box.max.x = std::max(box.max.x, vertices[i]); / / ...other axes... } } Data preparation void MeshUtils::ExportMesh::geometry(Geometry* geometry) { / / Processing triangular mesh data if (geometry->triangulation) { auto* tri = geometry->triangulation; / / Add vertex data for (size_t i = 0; i < 3 * tri->vertices_n; i += 3) { auto p = scale * mul(geometry->M_3x4, makeVec3f(tri->vertices +i)); vertices.push_back(px); vertices.push_back(py); vertices.push_back(pz); } / / Add index data for (size_t i = 0; i < 3 * tri->triangles_n; i += 3) { indices.push_back(tri->indices[i + 0] + offset); indices.push_back(tri->indices[i + 1] + offset); indices.push_back(tri->indices[i + 2] + offset); } } } Export in AURR format void Convert::TriangleMesh::SaveToFile(const char* rootPath, constchar* name, const char* typeName) { / / Create output directory std::filesystem::create_directories(path); / / Open binary output file std::ofstream file(path.string(), std::ios::binary); / / Write vertex data file.write((char*)vertices->data(), vertices->size() * sizeof(float)); / / Write normal data file.write((char*)normals->data(), normals->size() * sizeof(float)); / / Write index data file.write((char*)indices->data(), indices->size() * sizeof(int)); / / Write color data file.write((char*)colors->data(), colors->size() * sizeof(int)); / / Write metadata file.write((char*)&meshNum, sizeof(uint32_t)); / / ...write metadata for each grid block... file.close(); }

[0029] Furthermore, the lightweight processing of the VUE format model includes: The Vue format file is parsed using VueFrExporter to obtain the BaseComponent array; Iterate through each component and create a processing context; The geometric data is converted into a triangular mesh using GeometryTracer; Use MemoryHelper for managed / unmanaged memory conversion; Triangulation optimization is performed using the Earcut algorithm; Compress data such as vertices, normals, and indices; The final output is in aurr format.

[0030] Preferably, 2.3 Lightweight processing of VUE format models 2.3.1 Functional Overview and Code 2.3.1.1 VueToGlb / VueToZb methods (1) Function Overview: The main entry method for VUE format model data, responsible for initiating the entire processing flow. (2) Method Parameters: vueFile: string - The path to the input Vue format model file glbFile / zbFile: string - Output file path progressCallback: ProgressCallback - Progress callback function config: ExportConfig - Export configuration (VueToZb only) (3) Method code: VueFrExporter con = new VueFrExporter(); BaseComponent[] result = con.Export(vueFile, vueFile.Replace(".vue",".json")); TriangulationService exporter = new TriangulationService(); exporter.Import(result, con); exporter.Dispose(); 2.3.1.2 Import Method (1) Function Overview: Import VUE model data and start processing (2) Method parameters: result: BaseComponent[] - An array of basic components parsed from the Vue file. con: VueFrExporter - A Vue file exporter example (3) Method code: int index = 0; m_con = con; foreach (var item in result) { if (item != null) DumpComponent(item); index++; if (index % 10000 == 0) Console.WriteLine($"The {index} component has been processed"); } 2.3.1.3 DumpComponent method (1) Function Overview: Processes individual components and creates processing contexts. (2) Method parameters: item: BaseComponent - Data for a single component (3) Method code: var color = new Vector4(item.Color.R, item.Color.G, item.Color.B,item.Color.A); if (item.Symbol == null) return; Context context = new(item.Name, item.Oid, color, m_geometryTracer); DumpSymbol(context, Matrix4.Identity, item.Symbol); if (!context.Triangulation.IsEmpty()) { context.Triangulation.CalBox(); m_triangulations.Add(context.Triangulation); } 2.3.1.4 TracerFace / TraceShell Method (1) Function Overview: Converts geometric surfaces / shells into triangular meshes (2) Method parameters: face: GeoFace - Geometric Face Data geoShell: GeoShell - Geoshell Data (3) Method code: IntPtr pFace = MemoryHelper.ToNativePointer(face); IntPtr ptr = GeometryWrapper.Import.TracerFace(m_ptr, pFace); MemoryHelper.FreeGeoFace(pFace); return MemoryHelper.PointerToTriangleMesh(ptr); 2.3.1.5 ToNativePointer method (1) Function Overview: Converts managed geometry data into unmanaged memory pointers (2) Method parameters: face: GeoFace - Geometric Face Data (3) Method code: int size = sizeof(UnSafeEntities.GeoFace); IntPtr intPtr = Marshal.AllocHGlobal(size); UnSafeEntities.GeoFace* geoFace = (UnSafeEntities.GeoFace*)intPtr.ToPointer(); ToNativeRef(ref geoFace->Face, face.Surface); ToNativeRef(ref geoFace->Loops, face.Loops); return intPtr; 2.3.1.6 EarCutTriangulation3D method (1) Functional Overview: 3D triangulation is performed using the Earcut algorithm. (2) Method parameters: polygonVertexes: List <vector3>- List of polygon vertices normal: Vector3 - normal vector (3) Method code: List <double>data = new List <double>(); foreach (var v in polygonVertexs) { data.Add(v.X); data.Add(v.Y); data.Add(v.Z); } return Earcut.Tessellate(data, new List <int>()); 2.3.1.7 Export Method (1) Function Overview: Exports triangulation data to aurr format. (2) Method parameters: workPath: string - working path fileName: string - Output filename (3) Method code: var dirPath = $"{workPath} / {fileName} / "; if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); var count = m_triangulations.Count; var max = m_triangulations.Skip(count / 4); var min = m_triangulations.Take(count / 4); fileStreamJson.Write(UTF8Encoding.UTF8.GetBytes("[")); id = WriteZb(workPath, fileName, "outline", max, ids, id); if (min.Count() > 0) { id = WriteZb(workPath, fileName, "normal", min, ids, id); } 2.3.2 Core Logic Input parsing: Parse the Vue format file using VueFrExporter to obtain the BaseComponent array. Component handling: Iterate through each component and create a processing context. Geometric Transformation: Converts geometric data (faces / shells) into triangular meshes using GeometryTracer. Memory optimization: Use MemoryHelper for managed / unmanaged memory conversion Triangulation: Triangulation optimization using the Earcut algorithm. Data compression: Compressing data such as vertices, normals, and indices. Output format: The final output is in aurr format. 2.3.4 Code snippets corresponding to process nodes VUE file parsing BaseComponent[] result = con.Export(vueFile, vueFile.Replace(".vue",".json")) Node DE: Component Traversal and Context Creation Context context = new(item.Name, item.Oid, color, m_geometryTracer); DumpSymbol(context, Matrix4.Identity, item.Symbol); Geometric type judgment if (geometry is Symbol subSymbol) { DumpSymbol(context, matrix, subSymbol); } else if (geometry is GeometryInstance geometryInstance) { DumpGeometry(context, geometryInstance); } Surface conversion IntPtr pFace = MemoryHelper.ToNativePointer(face); IntPtr ptr = GeometryWrapper.Import.TracerFace(m_ptr, pFace); Shell conversion IntPtr pShell = MemoryHelper.ToNativePointer(geoShell); IntPtr ptr = GeometryWrapper.Import.TracerShell(m_ptr, pShell); Memory optimization IntPtr intPtr = Marshal.AllocHGlobal(size); UnSafeEntities.GeoFace* geoFace = (UnSafeEntities.GeoFace*)intPtr.ToPointer(); Triangulation var triangles = Earcut.Tessellate(newPtsData, holeIndex); Data compression item.Vertices.ForEach(vertex => stream.VerStream.Write(BitConverter.GetBytes((float)vertex))); item.Normals.ForEach(normal => stream.NormalStream.Write(BitConverter.GetBytes((float)normal))); Formatted output var fileSteam = File.Create($"{file}.{ext}"); fileSteam.Write(stream.GetBuffer(), 0, (int)stream.Length).

[0031] Furthermore, the lightweight processing of the NWD format model includes: Use the Open Design Alliance API to read Navisworks model files; The model structure is parsed using OdNwModelItem, and model items and their attributes are extracted. The model is triangulated to generate triangular mesh data; The vector difference, cross product, and normalization are calculated using the Sub, Cross, and Normalized methods, and then the normal vector is calculated. The normal vectors of the triangular mesh are calculated using the CalNormal method; Convert the processed data to AURR format and output it.

[0032] Preferably, lightweight processing of 2.4 NWD format models 2.4.1 Functional Overview and Code 2.4.1.1 OdNwODAUniqueIDProperty::subGetValue method (1) Function Overview: Retrieves the unique ID of a Navisworks model item. (2) Method parameters: - pO: const OdRxObject* Input parameter, representing the model object whose ID you want to retrieve. - value: OdRxValue& Output parameter, used to store the obtained unique ID. (3) Method code: template <> OdResult OdNwODAUniqueIDProperty <odnwmodelitem>::subGetValue(constOdRxObject* pO, OdRxValue& value) const { OdSmartPtr <odnwmodelitem>pMI = OdNwModelItem::cast(pO); if (pMI.isNull()) return eNotApplicable; OdNwObjectIdArray aIns; pMI->getInstances(aIns); ODA_ASSERT(!aIns.empty()); value = static_cast <oduint64>(aIns[0].getHandle()); return eOk; } 2.4.1.2 propertyLengthUnits method (1) Function Overview: Returns a formatted string indicating the length unit based on the unit type. (2) Method parameters: - units: NwModelUnits::Enum Input parameter, indicating the length unit type. (3) Method code: const OdChar* propertyLengthUnits(NwModelUnits::Enum units) { switch (units) { case NwModelUnits::UNITS_METERS: return OD_T("%fm"); / / ...processed by other units... default: return OD_T("%f"); } } 2.4.1.3 OdNwModelItemPropertyFacet::makeMembers method (1) Function Overview: Constructs the attribute set of model items. (2) Method parameters: - collectionBuilder: OdRxMemberCollectionBuilder& Input and output parameters used to construct the property collection. - pUserData: void* Input parameter, pointing to the model item object (3) Method code: void OdNwModelItemPropertyFacet::makeMembers(OdRxMemberCollectionBuilder& collectionBuilder, void* pUserData) { const OdRxObject* pO = (const OdRxObject*)pUserData; OdNwModelItemPtr pMI = OdNwModelItem::cast(pO); if (pMI.isNull()) return; collectionBuilder.add(OdNwObjectChildsProperty<OdNwModelItem,OdNwObjectIdArray, &OdNwModelItem::getChildren>::createObject(collectionBuilder.owner())); collectionBuilder.add(OdNwODAUniqueIDProperty <odnwmodelitem>::createObject(collectionBuilder.owner())); OdArray <odnwattributeptr>aAttributes; / / ...attribute processing logic... } 2.4.1.4 Sub Method (1) Function Overview: Calculates the difference between two three-dimensional vectors. (2) Method parameters: - v1: float* Input parameter, the first vector - v2: float* Input parameter, the second vector - out: float* Output parameter, storing the result (3) Method code: inline void Sub(float* v1, float* v2, float* out) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; out[2] = v1[2] - v2[2]; } 2.4.1.5 Cross Method (1) Function Overview: Calculates the cross product of two three-dimensional vectors. (2) Method parameters: - v1: float* Input parameter, the first vector - v2: float* Input parameter, the second vector - out: float* Output parameter, storing the result (3) Method code: inline void Cross(float* v1, float* v2, float* out) { out[0] = v1[1] * v2[2] - v1[2] * v2[1]; out[1] = v1[2] * v2[0] - v1[0] * v2[2]; out[2] = v1[0] * v2[1] - v1[1] * v2[0]; } 2.4.1.6 Normalized method (1) Functional Overview: Normalizes three-dimensional vectors (2) Method parameters: - vertor: float* Input / output parameters, the vector to be normalized. (3) Method code: inline void Normalized(float* vertor) { float length = std::sqrt(vertor[0] * vertor[0] + vertor[1] *vertor[1] + vertor[2] * vertor[2]); vertor[0] / = length; vertor[1] / = length; vertor[2] / = length; } 2.4.1.7 CalNormal method (1) Function Overview: Calculates the normal vector of the triangular mesh. (2) Method parameters: - inVertices: std::vector <float>& Input parameters, vertex coordinates - inIndices: std::vector <int>& Input parameters, triangle patch index - outNormals: std::vector <float>& Output parameters, storing the calculated normal vector (3) Method code: void CalNormal(std::vector <float>& inVertices, std::vector <int>&inIndices, std::vector <float>& outNormals) { / / ...Implementation details... } 2.4.1.8 TriangleMesh::SaveToFile method (1) Function Overview: Saves triangular mesh data to a file (2) Method parameters: - workPath: const char* Input parameter, working directory path - name: const char* Input parameter, filename - type: const char* Input parameter, file type (3) Method code: void Convert::TriangleMesh::SaveToFile(const char* workPath, constchar* name, const char* type) { / / ...Implementation details... } 2.4.2 Core Logic Read Navisworks model files (NWD format) Analyze the model structure and extract model items and their attributes. Triangulate the model to generate triangular mesh data. Optimize and compress grid data Convert the processed data to AURR format. Output lightweight model data 2.4.3 Code snippets corresponding to process nodes Read NWD files / / Primarily uses Open Design Alliance related APIs Analytical model structure / / Use the OdNwModelItem class to parse the model structure OdSmartPtr <odnwmodelitem>pMI = OdNwModelItem::cast(pO); if (pMI.isNull()) return eNotApplicable; Extracting model item attributes / / Extract from NwModelItemProperties.cpp void OdNwModelItemPropertyFacet::makeMembers(OdRxMemberCollectionBuilder& collectionBuilder, void* pUserData) { const OdRxObject* pO = (const OdRxObject*)pUserData; OdNwModelItemPtr pMI = OdNwModelItem::cast(pO); if (pMI.isNull()) return; / / Add child item properties collectionBuilder.add(OdNwObjectChildsProperty<OdNwModelItem,OdNwObjectIdArray, &OdNwModelItem::getChildren> ::createObject(collectionBuilder.owner())); / / Add a unique ID attribute collectionBuilder.add(OdNwODAUniqueIDProperty <odnwmodelitem>::createObject(collectionBuilder.owner())); / / Get all properties OdArray <odnwattributeptr>aAttributes; pMI->getAttributes(aAttributes); } Triangulation processing / / Core data structure for triangulation processing Convert::TriangleMesh::TriangleMesh() { ids = new std::vector <int>(); verIndex = new std::vector<size_t> (); / / ...Other member initialization... } Calculate the normal vector / / Vector difference calculation inline void Sub(float* v1, float* v2, float* out) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; out[2] = v1[2] - v2[2]; } / / Vector cross product inline void Cross(float* v1, float* v2, float* out) { out[0] = v1[1] * v2[2] - v1[2] * v2[1]; out[1] = v1[2] * v2[0] - v1[0] * v2[2]; out[2] = v1[0] * v2[1] - v1[1] * v2[0]; } / / Normalization inline void Normalized(float* vertor) { float length = std::sqrt(vertor[0] * vertor[0] + vertor[1] *vertor[1] + vertor[2] * vertor[2]); vertor[0] / = length; vertor[1] / = length; vertor[2] / = length; } Save grid data / / Save vertex data sprintf(fileName, "%s / zb / %s-%s-%d.ver", workPath, name, type,packIndex); std::ofstream file(fileName, std::ios::binary); file.write((char*)vertices->data(), vertices->size() * sizeof(float)); file.close(); / / Save normal data sprintf(fileName, "%s / zb / %s-%s-%d.normal", workPath, name, type,packIndex); file.open(fileName, std::ios::binary); file.write((char*)normals->data(), normals->size() * sizeof(float)); file.close(); / / Save index data sprintf(fileName, "%s / zb / %s-%s-%d.index", workPath, name, type,packIndex); file.open(fileName, std::ios::binary); file.write((char*)indices->data(), indices->size() * sizeof(int)); file.close(); Generate metadata / / Generate info file sprintf(fileName, "%s / zb / %s-%s-%d.info", workPath, name, type,packIndex); file.open(fileName, std::ios::binary); / / Write model ID and color information for (size_t i = 0; i < meshNum; i++) { uint32_t id = (*ids)[i]; uint32_t r = (*colors)[i * 4]; uint32_t g = (*colors)[i * 4 + 1]; uint32_t b = (*colors)[i * 4 + 2]; uint32_t a = (*colors)[i * 4 + 3]; file.write((char*)&id, sizeof(uint32_t)); file.write((char*)&indexStart, sizeof(uint32_t)); file.write((char*)&endIndex, sizeof(uint32_t)); file.write((char*)&r, sizeof(uint32_t)); file.write((char*)&g, sizeof(uint32_t)); file.write((char*)&b, sizeof(uint32_t)); file.write((char*)&a, sizeof(uint32_t)); } / / Write bounding box information OdGePoint3d min = box->minPoint(); OdGePoint3d max = box->maxPoint(); stringjson << "\",\"box\":{\"min\":{\"x\":" << min.x << ",\"y\":" <<min.y <<",\"z\":"<<min.z<<"},\"max\":{\"x\":" << max.x << ",\"y\":" <<max.y << ",\"z\":" << max.z << "}}"; file.close(); Output lightweight model / / Final output processing LOG(INFO) << "dumpzb file = " << workPath << " / zb / " << name << "-" < <type << "-" << packIndex; packIndex++; / / Clear temporary data verIndex->clear(); indIndex->clear(); ids->clear(); colors->clear(); vertices->clear(); normals->clear(); indices->clear().

[0033] Furthermore, the lightweight processing of the FBX / IFC format model includes: Load FBX / IFC format models using the Assimp library; Perform mesh processing such as triangulation, vertex merging, and normal calculation; Optimize the grid structure to reduce redundant data; Data compression is performed using the Open3DGC encoder; Convert the compressed data to AURR format; The compressed data is output using the glTFExporter::ExportMesh method.

[0034] Preferably, lightweight processing of 2.5 FBX / IFC format models. 2.5.1 Functional Overview and Code 2.5.1.1 ProcessProfile Method (1) Functional Overview: Processes IFC profile geometry data (2) Method parameters: const Schema_2x3::IfcProfileDef &profile (input profile definition) TempMesh & meshout (output mesh) ConversionData & conv (Convert Data) (3) Method code: bool ProcessProfile(const Schema_2x3::IfcProfileDef &profile,TempMesh &meshout, ConversionData &conv) { if(const auto* const cprofile = profile.ToPtr<Schema_2x3::IfcArbitraryProfileDefWithVoids> ()) { / / Processing profiles with holes } / / ...processing other profile types... } 2.5.1.2 ProcessExtrudedAreaSolid (1) Functional Overview: Handling the geometry of stretched solids (2) Method parameters: const Schema_2x3::IfcExtrudedAreaSolid &solid (Extruded Solid) TempMesh & result (Result Grid) ConversionData & conv (Convert Data) bool collect_openings (whether to collect openings) (3) Method code: void ProcessExtrudedAreaSolid(const Schema_2x3::IfcExtrudedAreaSolid&solid, TempMesh &result, ConversionData &conv, bool collect_openings) { / / 1. Processing the foundation profile / / 2. Apply stretch transformation / / 3. Handle openings (e.g., collect_openings is true) } 2.5.1.3 ConvertWeights method (1) Function Overview: Transform FBX weight data (2) Method parameters: aiMesh *out (output mesh) const MeshGeometry &geo (input geometry) const aiMatrix4x4 &absolute_transform (absolute transformation) aiNode *parent (parent node) unsigned int materialIndex (material index) (3) Method code: void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent, unsigned intmaterialIndex) { / / 1. Handling bone weights / / 2. Apply the transformation matrix / / 3. Generate vertex weight data } 2.5.1.4 ProcessNode method (1) Functional Overview: Processing scene node hierarchy (2) Method parameters: aiNode *node (current node) const aiScene *scene (scene data) (3) Method code: void ModelLoader::processNode(aiNode *node, const aiScene *scene) { / / Recursively process all child nodes for (UINT i = 0; i < node->mNumChildren; i++) { this->processNode(node->mChildren[i], scene); } } 2.5.1.5 ExportMesh Method (1) Function Overview: Export grid data and compress it. (2) Method parameters: const aiMesh* aim (input mesh) const std::vector<unsigned char> & input (input data) size_t idx_srcdata_begin (starting index of the data) (3) Method code: void glTFExporter::ExportMesh(const aiMesh* aim, const std::vector<unsigned char> & input, size_t idx_srcdata_begin) { / / 1. Set Open3DGC encoder parameters / / 2. Perform mesh compression / / 3. Output compressed data } 2.5.1.6 ConvertMaterial Method (1) Function Overview: Convert FBX material data (2) Method parameters: const Element & element (material element) const Document& doc (document data) (3) Method code: Material::Material(uint64_t id, const Element& element, constDocument& doc, const std::string& name) { / / Analyze material properties const Scope& sc = GetRequiredScope(element); / / ...material parameter processing... } 2.5.1.7 ProcessAnimations method (1) Functional Overview: Processing animation data (2) Method parameters: const std::vector<const AnimationCurveNode*> & curves (animation curves) const LayerMap& layer_map (animation layer) int64_t start (start time) int64_t stop (end time) (3) Method code: void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim*> &node_anims, const std::string& fixed_name, const std::vector<constAnimationCurveNode*> & curves, const LayerMap& layer_map, int64_t start,int64_t stop) { / / Process rotation / translation / scaling animation data } 2.5.1.8 SetupEmptyMesh method (1) Function Overview: Creates an empty grid container (2) Method parameters: const MeshGeometry &mesh (input geometry) aiNode *parent (parent node) (3) Method code: aiMesh* FBXConverter::SetupEmptyMesh(const MeshGeometry &mesh, aiNode*parent) { aiMesh* const out_mesh = new aiMesh(); / / Initialize mesh basic properties return out_mesh; } 2.5.1.9 Load Method (1) Functional Overview: Main Loading Entry Point (2) Method parameters: HWND hwnd (window handle) ID3D11Device *dev (DirectX device) ID3D11DeviceContext *devcon (device context) std::string filename (filename) (3) Method code: bool ModelLoader::Load(HWND hwnd, ID3D11Device *dev,ID3D11DeviceContext *devcon, std::string filename) { const aiScene* pScene = importer.ReadFile(filename, aiProcess_Triangulate | aiProcess_ConvertToLeftHanded); / / ...loading and processing... } 2.5.1.10 ProcessCurve Method (1) Functional Overview: Processes IFC curve data (2) Method parameters: const Schema_2x3::IfcCurve &curve (input curve) TempMesh & meshout (output mesh) ConversionData & conv (Convert Data) (3) Method code: void ProcessCurve(const Schema_2x3::IfcCurve &curve, TempMesh &meshout, ConversionData &conv) { / / Handling different types of curves (B-splines, polylines, etc.) } 2.5.2 Core Logic Model loading: Loading FBX / IFC format models using the Assimp library. Mesh processing: performing triangulation, vertex merging, normal calculation, etc. Data optimization: Optimize the grid structure and reduce redundant data. Data compression: Compressing the optimized data. Format conversion: Convert compressed data to AURR format. Data export: Providing the final data to external users. 2.5.3 Code snippets corresponding to process nodes Format parsing node (IFC / FBX input parsing) const aiScene* IFCLoader::ReadFile() { const STEP::LazyObject* proj = db->GetObject("ifcproject"); ConversionData conv(*db, proj->To<Schema_2x3::IfcProject> (),pScene, settings); SetUnits(conv); SetCoordinateSpace(conv); ProcessSpatialStructures(conv); } FBXConverter::FBXConverter(const Document& doc, boolremoveEmptyBones) { ConvertAnimations(); ConvertRootNode(); ConvertGlobalSettings(); TransferDataToScene(); } Geometric data processing node void ProcessSweptAreaSolid(const Schema_2x3::IfcSweptAreaSolid&swept, TempMesh& meshout, ConversionData& conv) { if(const auto* solid = swept.ToPtr<Schema_2x3::IfcExtrudedAreaSolid> ()) { ProcessExtrudedAreaSolid(*solid, meshout, conv); } } Triangular mesh generation nodes void TriangulateProcess::Execute(aiScene* pScene) { for (unsigned int a = 0; a < pScene->mNumMeshes; a++) { aiMesh* mesh = pScene->mMeshes[a]; if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON) { TriangulateMesh(mesh); } } } Mesh Optimization Node void OptimizeMeshes::ProcessNode(aiNode* pNode) { for (unsigned int i = 0; i < pNode->mNumMeshes; ++i) { aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[i]]; MergeVertices(mesh); } } Data Compression Node void glTFExporter::ExportMesh(const aiMesh* aim) { o3dgc::SC3DMCEncodeParams comp_o3dgc_params; comp_o3dgc_params.SetCoordQuantBits(12); encoder.Encode(comp_o3dgc_ifs, comp_o3dgc_params, bs); } AURR Format Output Node void ExportSceneToAURR(const aiScene* pScene, const std::string& filename) { ZBWriter writer; writer.Write(pScene, aiProcess_CalcTangentSpace | aiProcess_GenNormals | aiProcess_OptimizeMeshes); }

[0035] Furthermore, the lightweight processing of the STP / STEP format model includes: Read CAD files using STEPControl_Reader or STPControl_Reader; Convert CAD entities into a TopoDS_Shape hierarchy; Triangulation is performed using BRepMesh_IncrementalMesh; Extract information such as vertices, normals, and colors; The SetShape method can be used to process different types of shape data. Write OBJ format files and edge data.

[0036] Preferably, lightweight processing of the 2.6 STP / STEP format model. 2.6.1 Functional Overview and Code 2.6.1.1 CAD_reader::read() method (1) Function Overview: Reads CAD files (STEP / STP) and parses them into TopoDS_Shape objects. (2) Method parameters: Standard_CString& path - file path (3) Method code: virtual int read(Standard_CString& path) { if (reader.ReadFile(path) != IFSelect_RetDone) { reader.PrintCheckLoad(Standard_False, IFSelect_GeneralInfo); return 1; } / / ...file reading and conversion processing... aShape = reader0.OneShape(); return 0; } 2.6.1.2 MeshShape() method (1) Functional Overview: Performs triangular meshing on shapes. (2) Method parameters: TopoDS_Shape theShape - the shape to be divided float theDeflection - Grid deviation value (control precision) bool theForced - Whether to force repartitioning (3) Method code: void MeshShape(const TopoDS_Shape theShape, float theDeflection, booltheForced) { if (theDeflection <= 0) theDeflection = 0.01; TopExp_Explorer explorer(theShape, TopAbs_FACE); for (; explorer.More(); explorer.Next()) { const TopoDS_Shape& shape = explorer.Current(); if (shape.ShapeType() == TopAbs_FACE) { MeshShape0(shape, theDeflection, theForced); } } } 2.6.1.3 MeshShape0() method (1) Function Overview: Performs the actual triangular mesh generation operation. (2) Method parameters: TopoDS_Shape theShape - the shape to be divided float theDeflection - Grid deviation value bool theForced - Whether to force partitioning (3) Method code: void MeshShape0(const TopoDS_Shape theShape, float theDeflection,bool theForced) { / / Check if it has been split Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(TopoDS::Face(theShape), aLoc); if (!aPoly.IsNull() && !theForced) return; / / Calculate the bounding box and determine the meshing parameters Bnd_Box B; BRepBndLib::Add(theShape, B); Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); / / Perform triangulation BRepMesh_IncrementalMesh MESH(theShape, theDeflection); } 2.6.1.4 AddEdge() method (1) Function Overview: Add an edge to the edge list (2) Method parameters: const TopoDS_Edge& anEdge - The edge to be added N_Cylinder& EdgeList - Target Edge List (3) Method code: void AddEdge(const TopoDS_Edge& anEdge, N_Cylinder& EdgeList) { if (!BRep_Tool::Degenerated(anEdge)) { / / Get the point data on the edge Handle(Poly_PolygonOnTriangulation) aEdgePoly; Handle(Poly_Triangulation) T; BRep_Tool::PolygonOnTriangulation(anEdge, aEdgePoly, T,aEdgeLoc); / / Process each line segment on the edge for (int j = 1; j < aNbNodes; j++) { gp_Pnt pt1 = aNodesP(j); gp_Pnt pt2 = aNodesP(j + 1); / / Transform coordinates and add to edge list double aCoord1[3] = { pt1.X(), pt1.Y(), pt1.Z()}; double aCoord2[3] = { pt2.X(), pt2.Y(), pt2.Z()}; EdgeList.Add(Cylinder(aCoord1, aCoord2, 3.0)); } } } 2.6.1.5 SetShape() method (1) Function Overview: Set shape attributes and process its geometric data (2) Method parameters: const TopoDS_Shape& theShape - The shape to be processed const TopTools_IndexedDataMapOfShapeListOfShape& theEdgeMap - Edge Map bool theIsVector - Whether it is a vector int depth - Current processing depth std::string& Name - Shape Name (3) Method code: void SetShape(const TopoDS_Shape& theShape, const TopTools_IndexedDataMapOfShapeListOfShape& theEdgeMap, bool theIsVector, int depth, std::string& Name) { switch (theShape.ShapeType()) { case TopAbs_FACE: { / / Processing face data const TopoDS_Face& aFace = TopoDS::Face(theShape); Handle(Poly_Triangulation) poly = BRep_Tool::Triangulation(aFace, loc); / / Output triangle patch data for (Standard_Integer i = 1; i <= poly->NbTriangles(); i++) { const Poly_Triangle& tri = poly->Triangle(i); / / Output vertex data... fprintf(obj_fp, "v %f %f %f\n", p1.X(), p1.Y(), p1.Z()); / / Output surface data... fprintf(obj_fp, "f %d %d %d\n", vindex+1, vindex+2,vindex+3); } break } case TopAbs_EDGE: / / Process edge data AddEdge(TopoDS::Edge(theShape), IsolatedEdgeList); break / / Handling other shape types... } } 2.6.1.6 The queryColor() method (1) Function Overview: Query the color information of a given shape (2) Method parameters: const TopoDS_Shape& shape - The shape to query Quantity_Color& color - The returned color value (3) Method code: bool queryColor(const TopoDS_Shape& shape, Quantity_Color& color) { / / Set default color color.SetValues(0.5, 0.5, 0.5, Quantity_TOC_RGB); / / Try to get different categories of colors if (aColorTool->GetColor(shape, XCAFDoc_ColorGen, color)) returntrue; if (aColorTool->GetColor(shape, XCAFDoc_ColorCurv, color)) returntrue; if (aColorTool->GetColor(shape, XCAFDoc_ColorSurf, color)) returntrue; return false; } 2.6.1.7 ShapeToName() method (1) Function Overview: Converts shapes into name strings (2) Method parameters: const TopoDS_Shape& theShape - The shape to be converted float* color - Optional color output parameter (3) Method code: std::string ShapeToName(const TopoDS_Shape& theShape, float* color =NULL) { std::string name; TDF_Label label = aShapeTool->FindShape(theShape); / / Get shape name if (!label.IsNull()) { Handle(TDataStd_Name) N; if (label.FindAttribute(TDataStd_Name::GetID(), N)) { name = TCollection_AsciiString(N->Get()).ToCString(); } } / / Get color information if (color) { Quantity_Color qcolor; if (queryColor(theShape, qcolor)) { color[0] = qcolor.Red(); color[1] = qcolor.Green(); color[2] = qcolor.Blue(); } } return name; } 2.6.2 Core Logic File reading: Read CAD files using STEPControl_Reader or STPControl_Reader Data parsing: Converting CAD entities into a TopoDS_Shape hierarchy. Mesh generation: Triangulation is performed using BRepMesh_IncrementalMesh Data processing: Extracting information such as vertices, normals, and colors. Output generation: Write to OBJ format file and edge data 2.6.3 Code snippets corresponding to process nodes File reading STEPCAFControl_Reader reader; reader.ReadFile(path); aShape = reader.Reader().OneShape(); Shape Analysis TDF_LabelSequence shapes; aShapeTool->GetShapes(shapes); for (int i = 1; i <= shapes.Length(); i++) { TDF_Label label = shapes.Value(i); Handle(TDataStd_Name) N; / / ...parse labels and shapes... } Shape traversal and type determination TopExp_Explorer explorer(theShape, TopAbs_FACE); for (; explorer.More(); explorer.Next()) { const TopoDS_Shape& shape = explorer.Current(); switch (shape.ShapeType()) { case TopAbs_SOLID: / / ...processes entities case TopAbs_FACE: / / ...processing the surface / / ...other types of processing... } } Mesh subdivision BRepMesh_IncrementalMesh MESH(theShape, aDeflection); Triangular facet extraction Handle(Poly_Triangulation) poly = BRep_Tool::Triangulation(aFace,loc); const Poly_Array1OfTriangle& tris = poly->Triangles(); const Poly_ArrayOfNodes& Nodes = poly->InternalNodes(); Data generation and output fprintf(obj_fp, "v %f %f %f\n", p1.X(), p1.Y(), p1.Z()); fprintf(obj_fp, "f %d %d %d\n", vindex+1, vindex+2, vindex+3); Edge processing AddEdge(anEdge, IsolatedEdgeList); IsolatedEdgeList.put(edgeFile, edge_r).

[0037] The present invention also includes a three-dimensional model adaptive lightweight processing system, which adopts a multi-process concurrent processing mechanism, can process multiple model conversion tasks simultaneously, and achieves a balance between model complexity and visual quality through adjustable facet reduction ratio parameters, ensuring that the lightweight model can still be used for engineering delivery and operation and maintenance applications.

[0038] The system supports multiple operating system environments such as Windows, Linux, and Kylin V10sp1, adapting to different deployment scenarios. It can be seamlessly integrated into the engineering digital delivery and operation and maintenance platform, realizing the automatic delivery process of obtaining design data from the "data pool", classifying it according to the marine oil engineering delivery standard library, and connecting each object to the field data required by its library according to the classification content.

[0039] Obviously, the above embodiments of the present invention are merely examples for clearly illustrating the present invention, and are not intended to limit the implementation of the present invention. Those skilled in the art can make other variations or modifications based on the above description. It is neither necessary nor possible to exhaustively describe all embodiments here. Any modifications, equivalent substitutions, and improvements made within the spirit and principles of the present invention should be included within the scope of protection of the claims of the present invention.< / int> < / odnwattributeptr> < / odnwmodelitem> < / odnwmodelitem> < / float> < / int> < / float> < / float> < / int> < / float> < / odnwattributeptr> < / odnwmodelitem> < / odnwmodelitem> < / odnwmodelitem> < / int> < / double> < / double> < / info> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / float> < / rocketmqmodelconvertentity> < / rocketmqmodelconvertentity> < / modelconvertentity> < / modelconvertentity>

Claims

1. A method for adaptive lightweight processing of three-dimensional models, characterized in that, include: The business layer, developed in C#, is responsible for service management, MQTT communication, and integration with third-party systems, interacting with the underlying C++ module through unmanaged calls. The data processing layer, developed in C++, focuses on file parsing, mesh generation, and polygon reduction optimization. The business layer implements service startup, shutdown, and status monitoring functions, and provides a REST API interface for external systems to call. The data processing layer contains multiple format-specific processing modules. The conversion functions for different formats are implemented as independent modules, and are provided for calling by a unified external encapsulation interface. The lightweight processing system supports the parsing and conversion of various industrial 3D model formats, including NWD, FBX, IFC, RVM, VUE, and STP / STEP. It receives conversion requests containing parameters such as model UUID, file type, scaling ratio, and LOD level via the MQTT protocol. It uses triangular mesh indexing technology to reduce vertex redundancy and combines WebP lossless compression of material textures to achieve a model volume compression rate of over 50%, and outputs lightweight models in AURR, FBX, or OBJ formats.

2. The adaptive lightweight processing method for three-dimensional models according to claim 1, characterized in that, The business layer obtains a list of models to be converted from the MQTT message queue through the GetMQModelConvertList method. This method receives the application configuration object, establishes an MQTT connection and subscribes to a specified topic, deserializes the message body into a RocketMQModelConvertEntity object, converts it into the internally unified ModelConvertEntity format, combines the complete source file path, encapsulates the conversion parameters, and returns a standardized list of model conversion tasks.

3. The adaptive lightweight processing method for three-dimensional models according to claim 1, characterized in that, The lightweighting process for the RVM format model includes: Parse RVM files using parseRVM to construct the model hierarchy; Parse geometry data using parse_prim; Use Tessellator to convert the geometry into a triangular mesh; Duplicate vertices are removed using RemoveDuplicateVertex, and normals are corrected using CorrectNormal. Collect processed mesh data using ExportMesh::geometry; Data is added to the buffer using TriangleMesh::AddMesh, serialized to aurr format, and written to a file.

4. The adaptive lightweight processing method for three-dimensional models according to claim 1, characterized in that, The lightweighting process for the VUE format model includes: The Vue format file is parsed using VueFrExporter to obtain the BaseComponent array; Iterate through each component and create a processing context; The geometric data is converted into a triangular mesh using GeometryTracer; Use MemoryHelper for managed / unmanaged memory conversion; Triangulation optimization is performed using the Earcut algorithm; Compress data such as vertices, normals, and indices; The final output is in aurr format.

5. The adaptive lightweight processing method for three-dimensional models according to claim 1, characterized in that, The lightweighting process for the NWD format model includes: Use the Open Design Alliance API to read Navisworks model files; The model structure is parsed using OdNwModelItem, and model items and their attributes are extracted. The model is triangulated to generate triangular mesh data; The vector difference, cross product, and normalization are calculated using the Sub, Cross, and Normalized methods, and then the normal vector is calculated. The normal vectors of the triangular mesh are calculated using the CalNormal method; Convert the processed data to AURR format and output it.

6. The adaptive lightweight processing method for three-dimensional models according to claim 1, characterized in that, The lightweighting process for the FBX / IFC format model includes: Load FBX / IFC format models using the Assimp library; Perform mesh processing such as triangulation, vertex merging, and normal calculation; Optimize the grid structure to reduce redundant data; Data compression is performed using the Open3DGC encoder; Convert the compressed data to AURR format; The compressed data is output using the glTFExporter::ExportMesh method.

7. The adaptive lightweight processing method for three-dimensional models according to claim 1, characterized in that, The lightweighting process for the STP / STEP format model includes: Read CAD files using STEPControl_Reader or STPControl_Reader; Convert CAD entities into a TopoDS_Shape hierarchy; Triangulation is performed using BRepMesh_IncrementalMesh; Extract information such as vertices, normals, and colors; The SetShape method can be used to process different types of shape data. Write OBJ format files and edge data.

8. A three-dimensional model adaptive lightweight processing system for performing the method as described in any one of claims 1 to 7, characterized in that, Employing a multi-process concurrent processing mechanism, it can handle multiple model conversion tasks simultaneously. Through adjustable polygon reduction ratio parameters, it achieves a balance between model complexity and visual quality, ensuring that the lightweight model can still be used for engineering delivery and operation and maintenance applications.