PLYExporter.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /**
  2. * @author Garrett Johnson / http://gkjohnson.github.io/
  3. * https://github.com/gkjohnson/ply-exporter-js
  4. *
  5. * Usage:
  6. * var exporter = new THREE.PLYExporter();
  7. *
  8. * // second argument is an array of attributes to
  9. * // exclude from the format ('color', 'uv', 'normal')
  10. * var data = exporter.parse(mesh, [ 'color' ]);
  11. *
  12. * Format Definition:
  13. * http://paulbourke.net/dataformats/ply/
  14. */
  15. THREE.PLYExporter = function () {};
  16. THREE.PLYExporter.prototype = {
  17. constructor: THREE.PLYExporter,
  18. parse: function ( object, excludeProperties ) {
  19. if ( Array.isArray( excludeProperties ) !== true ) {
  20. excludeProperties = [];
  21. }
  22. var includeNormals = excludeProperties.indexOf( 'normal' ) === - 1;
  23. var includeColors = excludeProperties.indexOf( 'color' ) === - 1;
  24. var includeUVs = excludeProperties.indexOf( 'uv' ) === - 1;
  25. // count the number of vertices
  26. var vertexCount = 0;
  27. var faceCount = 0;
  28. var vertexList = '';
  29. var faceList = '';
  30. var vertex = new THREE.Vector3();
  31. var normalMatrixWorld = new THREE.Matrix3();
  32. object.traverse( function ( child ) {
  33. if ( child instanceof THREE.Mesh ) {
  34. var mesh = child;
  35. var geometry = mesh.geometry;
  36. if ( geometry instanceof THREE.Geometry ) {
  37. geometry = new THREE.BufferGeometry().setFromObject( mesh );
  38. }
  39. if ( geometry instanceof THREE.BufferGeometry ) {
  40. var vertices = geometry.getAttribute( 'position' );
  41. var normals = geometry.getAttribute( 'normal' );
  42. var uvs = geometry.getAttribute( 'uv' );
  43. var colors = geometry.getAttribute( 'color' );
  44. var indices = geometry.getIndex();
  45. normalMatrixWorld.getNormalMatrix( mesh.matrixWorld );
  46. if ( vertices === undefined ) {
  47. return;
  48. }
  49. // form each line
  50. for ( var i = 0, l = vertices.count; i < l; i ++ ) {
  51. vertex.x = vertices.getX( i );
  52. vertex.y = vertices.getY( i );
  53. vertex.z = vertices.getZ( i );
  54. vertex.applyMatrix4( mesh.matrixWorld );
  55. // Position information
  56. var line =
  57. vertex.x + ' ' +
  58. vertex.y + ' ' +
  59. vertex.z;
  60. // Normal information
  61. if ( includeNormals === true ) {
  62. if ( normals !== undefined ) {
  63. vertex.x = normals.getX( i );
  64. vertex.y = normals.getY( i );
  65. vertex.z = normals.getZ( i );
  66. vertex.applyMatrix3( normalMatrixWorld );
  67. line += ' ' +
  68. vertex.x + ' ' +
  69. vertex.y + ' ' +
  70. vertex.z;
  71. } else {
  72. line += ' 0 0 0';
  73. }
  74. }
  75. // UV information
  76. if ( includeUVs === true ) {
  77. if ( uvs !== undefined ) {
  78. line += ' ' +
  79. uvs.getX( i ) + ' ' +
  80. uvs.getY( i );
  81. } else if ( includeUVs !== false ) {
  82. line += ' 0 0';
  83. }
  84. }
  85. // Color information
  86. if ( includeColors === true ) {
  87. if ( colors !== undefined ) {
  88. line += ' ' +
  89. Math.floor( colors.getX( i ) ) + ' ' +
  90. Math.floor( colors.getY( i ) ) + ' ' +
  91. Math.floor( colors.getZ( i ) );
  92. } else {
  93. line += ' 255 255 255';
  94. }
  95. }
  96. vertexList += line + '\n';
  97. }
  98. // Create the face list
  99. if ( indices !== null ) {
  100. for ( i = 0, l = indices.count; i < l; i += 3 ) {
  101. faceList += `3 ${ indices.getX( i + 0 ) + vertexCount }`;
  102. faceList += ` ${ indices.getX( i + 1 ) + vertexCount }`;
  103. faceList += ` ${ indices.getX( i + 2 ) + vertexCount }\n`;
  104. }
  105. } else {
  106. for ( var i = 0, l = vertices.count; i < l; i += 3 ) {
  107. faceList += `3 ${ vertexCount + i } ${ vertexCount + i + 1 } ${ vertexCount + i + 2 }\n`;
  108. }
  109. }
  110. vertexCount += vertices.count;
  111. faceCount += indices ? indices.count / 3 : vertices.count / 3;
  112. }
  113. }
  114. } );
  115. var output =
  116. 'ply\n' +
  117. 'format ascii 1.0\n' +
  118. `element vertex ${vertexCount}\n` +
  119. // position
  120. 'property float x\n' +
  121. 'property float y\n' +
  122. 'property float z\n';
  123. if ( includeNormals === true ) {
  124. // normal
  125. output +=
  126. 'property float nx\n' +
  127. 'property float ny\n' +
  128. 'property float nz\n';
  129. }
  130. if ( includeUVs === true ) {
  131. // uvs
  132. output +=
  133. 'property float s\n' +
  134. 'property float t\n';
  135. }
  136. if ( includeColors === true ) {
  137. // colors
  138. output +=
  139. 'property uchar red\n' +
  140. 'property uchar green\n' +
  141. 'property uchar blue\n';
  142. }
  143. // faces
  144. output +=
  145. `element face ${faceCount}\n` +
  146. 'property list uchar int vertex_index\n' +
  147. 'end_header\n' +
  148. `${vertexList}\n` +
  149. `${faceList}\n`;
  150. return output;
  151. }
  152. };