GeometryMerger.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * GeometryMerger.js
  3. *
  4. * @author realor
  5. */
  6. import { ObjectBuilder } from './ObjectBuilder.js'
  7. import { SolidBuilder } from './SolidBuilder.js'
  8. import { SolidGeometry } from '../core/SolidGeometry.js'
  9. import { Solid } from '../core/Solid.js'
  10. import { Profile } from '../core/Profile.js'
  11. import { Cord } from '../core/Cord.js'
  12. import { GeometryUtils } from '../utils/GeometryUtils.js'
  13. import * as THREE from '../lib/three.module.js'
  14. class GeometryMerger extends ObjectBuilder {
  15. static MESHES_NAME = 'merged_meshes'
  16. static LINES_NAME = 'merged_lines'
  17. constructor() {
  18. super()
  19. this._triangle = [new THREE.Vector3(), new THREE.Vector3(), new THREE.Vector3()]
  20. this._vector = new THREE.Vector3()
  21. this._material = null
  22. }
  23. performBuild(object) {
  24. const triangles = []
  25. const normals = []
  26. const edges = []
  27. const matrix = new THREE.Matrix4()
  28. let mesh = object.getObjectByName(GeometryMerger.MESHES_NAME)
  29. if (mesh) {
  30. mesh.geometry.dispose()
  31. object.remove(mesh)
  32. }
  33. let lines = object.getObjectByName(GeometryMerger.LINES_NAME)
  34. if (lines) {
  35. lines.geometry.dispose()
  36. object.remove(lines)
  37. }
  38. for (let child of object.children) {
  39. this.collectGeometry(child, matrix, triangles, normals, edges)
  40. child.visible = false
  41. }
  42. /* meshes */
  43. const meshGeometry = new THREE.BufferGeometry()
  44. meshGeometry.setAttribute('position', new THREE.Float32BufferAttribute(triangles, 3))
  45. meshGeometry.setAttribute('normal', new THREE.Float32BufferAttribute(normals, 3))
  46. mesh = new THREE.Mesh(meshGeometry, this._material)
  47. mesh.name = GeometryMerger.MESHES_NAME
  48. mesh.raycast = function() {}
  49. object.add(mesh)
  50. /* lines */
  51. const linesGeometry = new THREE.BufferGeometry()
  52. linesGeometry.setAttribute('position', new THREE.Float32BufferAttribute(edges, 3))
  53. lines = new THREE.LineSegments(linesGeometry, Solid.EdgeMaterial)
  54. lines.name = GeometryMerger.LINES_NAME
  55. lines.raycast = function() {}
  56. object.add(lines)
  57. return true
  58. }
  59. copy(source) {
  60. return this
  61. }
  62. collectGeometry(object, baseMatrix, triangles, normals, edges) {
  63. const triangle = this._triangle
  64. const normal = this._vector
  65. const vector = this._vector
  66. const matrix = new THREE.Matrix4()
  67. matrix.copy(baseMatrix)
  68. matrix.multiply(object.matrix)
  69. if (object instanceof Solid) {
  70. const solid = object
  71. if (solid.facesVisible) {
  72. const vertices = solid.geometry.vertices
  73. for (let face of solid.geometry.faces) {
  74. let faceTriangles = face.getTriangles()
  75. for (let t of faceTriangles) {
  76. for (let i = 0; i < 3; i++) {
  77. triangle[i].copy(vertices[t[i]]).applyMatrix4(matrix)
  78. }
  79. GeometryUtils.calculateNormal(triangle, undefined, normal)
  80. for (let i = 0; i < 3; i++) {
  81. triangles.push(triangle[i].x, triangle[i].y, triangle[i].z)
  82. normals.push(normal.x, normal.y, normal.z)
  83. }
  84. }
  85. }
  86. }
  87. if (solid.edgesVisible) {
  88. const array = solid.edgesGeometry.attributes.position.array
  89. for (let i = 0; i < array.length; i += 3) {
  90. vector.set(array[i], array[i + 1], array[i + 2])
  91. vector.applyMatrix4(matrix)
  92. edges.push(vector.x, vector.y, vector.z)
  93. }
  94. }
  95. if (this._material === null) {
  96. this._material = solid.material
  97. }
  98. } else if (object instanceof Profile) {
  99. } else if (object instanceof Cord) {
  100. } else {
  101. for (let child of object.children) {
  102. this.collectGeometry(child, matrix, triangles, normals, edges)
  103. }
  104. }
  105. }
  106. }
  107. ObjectBuilder.addClass(GeometryMerger)
  108. export { GeometryMerger }