MergeGeometriesTool.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /*
  2. * MergeGeometriesTool.js
  3. *
  4. * @author realor
  5. */
  6. import { Tool } from './Tool.js'
  7. import { Selection } from '../utils/Selection.js'
  8. import { ObjectUtils } from '../utils/ObjectUtils.js'
  9. import { GeometryUtils } from '../utils/GeometryUtils.js'
  10. import { Solid } from '../core/Solid.js'
  11. import * as THREE from '../lib/three.module.js'
  12. class MergeGeometriesTool extends Tool {
  13. constructor(application, options) {
  14. super(application)
  15. this.name = 'merge_geometries'
  16. this.label = 'tool.merge_geometries.label'
  17. this.help = 'tool.merge_geometries.help'
  18. this.className = 'merge_geometries'
  19. this.setOptions(options)
  20. this.immediate = true
  21. }
  22. execute() {
  23. const application = this.application
  24. const roots = application.selection.roots
  25. this.convert(roots)
  26. }
  27. convert(roots) {
  28. const application = this.application
  29. const parents = new Selection()
  30. for (let root of roots) {
  31. parents.add(root.parent)
  32. this.traverse(root)
  33. }
  34. const changed = parents.roots
  35. application.notifyObjectsChanged(changed, this, 'structureChanged')
  36. }
  37. traverse(object) {
  38. const materialMap = new Map()
  39. let children = object.children
  40. for (let child of children) {
  41. if (child instanceof THREE.Mesh || child instanceof Solid) {
  42. let material = child.material
  43. if (material instanceof THREE.Material) {
  44. let entry = materialMap.get(material)
  45. if (entry === undefined) {
  46. entry = { material: material, geometries: [], objects: [] }
  47. materialMap.set(material, entry)
  48. }
  49. let geometry = child.geometry.clone().applyMatrix4(child.matrix)
  50. entry.geometries.push(geometry)
  51. entry.objects.push(child)
  52. }
  53. } else if (child.geometry === undefined) {
  54. this.traverse(child)
  55. }
  56. }
  57. for (let entry of materialMap.values()) {
  58. if (entry.geometries.length > 1) {
  59. let mergedGeometry = GeometryUtils.mergeBufferGeometries(entry.geometries, false)
  60. if (mergedGeometry) {
  61. for (let obj of entry.objects) {
  62. obj.removeFromParent()
  63. ObjectUtils.dispose(obj)
  64. }
  65. let mergedMesh = new THREE.Mesh(mergedGeometry, entry.material)
  66. mergedMesh.name = 'merged_' + entry.material.id
  67. object.add(mergedMesh)
  68. object.needsRebuild = true
  69. }
  70. }
  71. }
  72. }
  73. }
  74. export { MergeGeometriesTool }