IFCVoider.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /**
  2. * Voider.js
  3. *
  4. * @author realor
  5. */
  6. import { Solid } from '../core/Solid.js'
  7. import { BSP } from '../core/BSP.js'
  8. import { ObjectBuilder } from './ObjectBuilder.js'
  9. import { SolidBuilder } from './SolidBuilder.js'
  10. import { IFC } from '../io/ifc/IFC.js'
  11. import * as THREE from '../lib/three.module.js'
  12. class IFCVoider extends SolidBuilder {
  13. constructor() {
  14. super()
  15. }
  16. traverseDependencies(productRepr, action) {
  17. if (!(productRepr instanceof Solid) || productRepr.children.length < 3) return
  18. action(productRepr.parent)
  19. const unvoidedRepr = productRepr.children[2]
  20. action(unvoidedRepr)
  21. let productObject3D = productRepr.parent
  22. if (productObject3D.userData.IFC && productObject3D.userData.IFC.ifcClassName === 'IfcBuildingElementPart') {
  23. productObject3D = productObject3D.parent
  24. }
  25. for (let child of productObject3D.children) {
  26. if (child !== productRepr) {
  27. action(child)
  28. }
  29. }
  30. }
  31. performBuild(productRepr) {
  32. if (productRepr.children.length < 3) return true
  33. const unvoidedRepr = productRepr.children[2]
  34. if (!unvoidedRepr instanceof Solid) return true
  35. const openingReprs = []
  36. let productObject3D = productRepr.parent
  37. if (productObject3D.userData.IFC && productObject3D.userData.IFC.ifcClassName === 'IfcBuildingElementPart') {
  38. productObject3D = productObject3D.parent
  39. }
  40. for (let child of productObject3D.children) {
  41. let userData = child.userData
  42. if (userData.IFC && userData.IFC.ifcClassName === 'IfcOpeningElement') {
  43. let openingRepr = child.getObjectByName(IFC.RepresentationName)
  44. if (openingRepr instanceof Solid) {
  45. openingReprs.push(openingRepr)
  46. } else if (openingRepr instanceof THREE.Group) {
  47. for (let subchild of openingRepr.children) {
  48. if (subchild instanceof Solid) {
  49. openingReprs.push(subchild)
  50. }
  51. }
  52. }
  53. }
  54. }
  55. if (openingReprs.length === 0) {
  56. productRepr.updateGeometry(unvoidedRepr.geometry)
  57. return true
  58. }
  59. const createBSP = function(solid) {
  60. const bsp = new BSP()
  61. bsp.fromSolidGeometry(solid.geometry, solid.matrixWorld)
  62. return bsp
  63. }
  64. let resultBSP = createBSP(unvoidedRepr)
  65. for (let openingRepr of openingReprs) {
  66. if (openingRepr.isValid()) {
  67. let otherBSP = createBSP(openingRepr)
  68. resultBSP = resultBSP.subtract(otherBSP)
  69. }
  70. }
  71. let geometry = resultBSP.toSolidGeometry()
  72. let inverseMatrixWorld = new THREE.Matrix4()
  73. inverseMatrixWorld.copy(productRepr.matrixWorld).invert()
  74. geometry.applyMatrix4(inverseMatrixWorld)
  75. productRepr.updateGeometry(geometry, true)
  76. return true
  77. }
  78. }
  79. ObjectBuilder.addClass(IFCVoider)
  80. export { IFCVoider }