智慧水务管理系统 - 精河县供水工程综合管理平台

draco_nodejs_example.js 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2017 The Draco Authors.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. //
  15. 'use_strict';
  16. const fs = require('fs');
  17. const assert = require('assert');
  18. const draco3d = require('draco3d');
  19. // Global decoder and encoder module variables.
  20. let decoderModule = null;
  21. let encoderModule = null;
  22. // The code to create the encoder and decoder modules is asynchronous.
  23. // draco3d.createDecoderModule will return a promise to a funciton with a
  24. // module as a parameter when the module has been fully initialized.
  25. // Create and set the decoder module.
  26. draco3d.createDecoderModule({}).then(function(module) {
  27. // This is reached when everything is ready, and you can call methods on
  28. // Module.
  29. decoderModule = module;
  30. console.log('Decoder Module Initialized!');
  31. modulesInitialized();
  32. });
  33. // Create and set the encoder module.
  34. draco3d.createEncoderModule({}).then(function(module) {
  35. // This is reached when everything is ready, and you can call methods on
  36. // Module.
  37. encoderModule = module;
  38. console.log('Encoder Module Initialized!');
  39. modulesInitialized();
  40. });
  41. function modulesInitialized() {
  42. // Check if both the encoder and decoder modules have been initialized.
  43. if (encoderModule && decoderModule) {
  44. fs.readFile('./bunny.drc', function(err, data) {
  45. if (err) {
  46. return console.log(err);
  47. }
  48. console.log("Decoding file of size " + data.byteLength + " ..");
  49. // Decode mesh
  50. const decoder = new decoderModule.Decoder();
  51. const decodedGeometry = decodeDracoData(data, decoder);
  52. // Encode mesh
  53. encodeMeshToFile(decodedGeometry, decoder);
  54. decoderModule.destroy(decoder);
  55. decoderModule.destroy(decodedGeometry);
  56. });
  57. }
  58. }
  59. function decodeDracoData(rawBuffer, decoder) {
  60. const buffer = new decoderModule.DecoderBuffer();
  61. buffer.Init(new Int8Array(rawBuffer), rawBuffer.byteLength);
  62. const geometryType = decoder.GetEncodedGeometryType(buffer);
  63. let dracoGeometry;
  64. let status;
  65. if (geometryType === decoderModule.TRIANGULAR_MESH) {
  66. dracoGeometry = new decoderModule.Mesh();
  67. status = decoder.DecodeBufferToMesh(buffer, dracoGeometry);
  68. } else if (geometryType === decoderModule.POINT_CLOUD) {
  69. dracoGeometry = new decoderModule.PointCloud();
  70. status = decoder.DecodeBufferToPointCloud(buffer, dracoGeometry);
  71. } else {
  72. const errorMsg = 'Error: Unknown geometry type.';
  73. console.error(errorMsg);
  74. }
  75. decoderModule.destroy(buffer);
  76. return dracoGeometry;
  77. }
  78. function encodeMeshToFile(mesh, decoder) {
  79. const encoder = new encoderModule.Encoder();
  80. const meshBuilder = new encoderModule.MeshBuilder();
  81. // Create a mesh object for storing mesh data.
  82. const newMesh = new encoderModule.Mesh();
  83. const numFaces = mesh.num_faces();
  84. const numIndices = numFaces * 3;
  85. const numPoints = mesh.num_points();
  86. const indices = new Uint32Array(numIndices);
  87. console.log("Number of faces " + numFaces);
  88. console.log("Number of vertices " + numPoints);
  89. // Add Faces to mesh
  90. const ia = new decoderModule.DracoInt32Array();
  91. for (let i = 0; i < numFaces; ++i) {
  92. decoder.GetFaceFromMesh(mesh, i, ia);
  93. const index = i * 3;
  94. indices[index] = ia.GetValue(0);
  95. indices[index + 1] = ia.GetValue(1);
  96. indices[index + 2] = ia.GetValue(2);
  97. }
  98. decoderModule.destroy(ia);
  99. meshBuilder.AddFacesToMesh(newMesh, numFaces, indices);
  100. const attrs = {POSITION: 3, NORMAL: 3, COLOR: 3, TEX_COORD: 2};
  101. Object.keys(attrs).forEach((attr) => {
  102. const stride = attrs[attr];
  103. const numValues = numPoints * stride;
  104. const decoderAttr = decoderModule[attr];
  105. const encoderAttr = encoderModule[attr];
  106. const attrId = decoder.GetAttributeId(mesh, decoderAttr);
  107. if (attrId < 0) {
  108. return;
  109. }
  110. console.log("Adding %s attribute", attr);
  111. const attribute = decoder.GetAttribute(mesh, attrId);
  112. const attributeData = new decoderModule.DracoFloat32Array();
  113. decoder.GetAttributeFloatForAllPoints(mesh, attribute, attributeData);
  114. assert(numValues === attributeData.size(), 'Wrong attribute size.');
  115. const attributeDataArray = new Float32Array(numValues);
  116. for (let i = 0; i < numValues; ++i) {
  117. attributeDataArray[i] = attributeData.GetValue(i);
  118. }
  119. decoderModule.destroy(attributeData);
  120. meshBuilder.AddFloatAttributeToMesh(newMesh, encoderAttr, numPoints,
  121. stride, attributeDataArray);
  122. });
  123. let encodedData = new encoderModule.DracoInt8Array();
  124. // Set encoding options.
  125. encoder.SetSpeedOptions(5, 5);
  126. encoder.SetAttributeQuantization(encoderModule.POSITION, 10);
  127. encoder.SetEncodingMethod(encoderModule.MESH_EDGEBREAKER_ENCODING);
  128. // Encoding.
  129. console.log("Encoding...");
  130. const encodedLen = encoder.EncodeMeshToDracoBuffer(newMesh,
  131. encodedData);
  132. encoderModule.destroy(newMesh);
  133. if (encodedLen > 0) {
  134. console.log("Encoded size is " + encodedLen);
  135. } else {
  136. console.log("Error: Encoding failed.");
  137. }
  138. // Copy encoded data to buffer.
  139. const outputBuffer = new ArrayBuffer(encodedLen);
  140. const outputData = new Int8Array(outputBuffer);
  141. for (let i = 0; i < encodedLen; ++i) {
  142. outputData[i] = encodedData.GetValue(i);
  143. }
  144. encoderModule.destroy(encodedData);
  145. encoderModule.destroy(encoder);
  146. encoderModule.destroy(meshBuilder);
  147. // Write to file. You can view the the file using webgl_loader_draco.html
  148. // example.
  149. fs.writeFile("bunny_10.drc", Buffer.from(outputBuffer), "binary",
  150. function(err) {
  151. if (err) {
  152. console.log(err);
  153. } else {
  154. console.log("The file was saved!");
  155. }
  156. });
  157. }