diff --git a/examples/slicing/SectionCapsPlugin.html b/examples/slicing/SectionCapsPlugin.html index 7dfd34c0d..e6d9370de 100644 --- a/examples/slicing/SectionCapsPlugin.html +++ b/examples/slicing/SectionCapsPlugin.html @@ -91,6 +91,14 @@

Components Used

id: "redLeg", meshIds: ["redLegMesh"], isObject: true, + capMaterial: new MetallicMaterial(viewer.scene, { + baseColor: [1, 0, 0], + backfaces: true, + baseColorMap: new Texture(viewer.scene, { + src: "../../assets/models/obj/fireHydrant/fire_hydrant_Base_Color.png", + encoding: "sRGB" + }), + }) }); sceneModel.createMesh({ @@ -106,6 +114,14 @@

Components Used

id: "greenLeg", meshIds: ["greenLegMesh"], isObject: true, + capMaterial: new MetallicMaterial(viewer.scene, { + baseColor: [0, 1, 0], + backfaces: true, + baseColorMap: new Texture(viewer.scene, { + src: "../../assets/models/obj/fireHydrant/fire_hydrant_Base_Color.png", + encoding: "sRGB" + }), + }) }); sceneModel.createMesh({ @@ -121,6 +137,14 @@

Components Used

id: "blueLeg", meshIds: ["blueLegMesh"], isObject: true, + capMaterial: new MetallicMaterial(viewer.scene, { + baseColor: [0, 0, 1], + backfaces: true, + baseColorMap: new Texture(viewer.scene, { + src: "../../assets/models/obj/fireHydrant/fire_hydrant_Base_Color.png", + encoding: "sRGB" + }), + }) }); sceneModel.createMesh({ @@ -136,6 +160,14 @@

Components Used

id: "yellowLeg", meshIds: ["yellowLegMesh"], isObject: true, + capMaterial: new MetallicMaterial(viewer.scene, { + baseColor: [1, 0, 1], + backfaces: true, + baseColorMap: new Texture(viewer.scene, { + src: "../../assets/models/obj/fireHydrant/fire_hydrant_Base_Color.png", + encoding: "sRGB" + }), + }) }); sceneModel.createMesh({ @@ -151,6 +183,16 @@

Components Used

id: "purpleTableTop", meshIds: ["purpleTableTopMesh"], isObject: true, + capMaterial: new MetallicMaterial(viewer.scene, { + baseColor: [1,1,1], + metallic: 1.0, + roughness: 1.0, + backfaces: true, + baseColorMap: new Texture(viewer.scene, { + src: "../../assets/models/obj/fireHydrant/fire_hydrant_Base_Color.png", + encoding: "sRGB" + }), + }) }); sceneModel.finalize(); diff --git a/src/plugins/SectionCapsPlugin/SectionCapsPlugin.js b/src/plugins/SectionCapsPlugin/SectionCapsPlugin.js index 220342736..3ca4ace6b 100644 --- a/src/plugins/SectionCapsPlugin/SectionCapsPlugin.js +++ b/src/plugins/SectionCapsPlugin/SectionCapsPlugin.js @@ -2,7 +2,6 @@ import { Plugin } from "../../viewer/Plugin.js"; import { math } from "../../viewer/scene/math/math.js"; import { Mesh } from "../../viewer/scene/mesh/Mesh.js"; import { ReadableGeometry } from "../../viewer/scene/geometry/ReadableGeometry.js"; -import { PhongMaterial } from "../../viewer/scene/materials/PhongMaterial.js"; import CSG from "../lib/csg.js"; class SectionCapsPlugin extends Plugin { @@ -113,11 +112,14 @@ class SectionCapsPlugin extends Plugin { this._deletePreviousModels(); - const csgGeometries = this._convertWebglGeometriesToCsgGeometries(sceneModel); + const { csgGeometries, materials } = this._convertWebglGeometriesToCsgGeometries(sceneModel); + + if (Object.keys(materials).length <= 0) return; + const csgPlane = this._createCSGPlane(plane); let caps = this._getCapGeometries(csgGeometries, csgPlane); - this._addIntersectedGeometries(caps); + this._addIntersectedGeometries(caps, materials); } //#region main callers @@ -133,14 +135,17 @@ class SectionCapsPlugin extends Plugin { _convertWebglGeometriesToCsgGeometries(sceneModels) { let csgGeometries = {}; + let materials = {}; sceneModels.forEach((sceneModel) => { const objects = {}; for (const key in sceneModel.objects) { const object = sceneModel.objects[key]; const isSolid = object.meshes[0].layer.solid !== false; - if (isSolid && object.opacity >= this._opacityThreshold) + if (isSolid && object.opacity >= this._opacityThreshold && object.capMaterial) { objects[key] = sceneModel.objects[key]; + materials[key] = sceneModel.objects[key].capMaterial; + } } let cloneModel = { @@ -156,7 +161,7 @@ class SectionCapsPlugin extends Plugin { } }) - return csgGeometries; + return { csgGeometries, materials }; } _getVerticesAndIndices(sceneModel) { @@ -288,10 +293,10 @@ class SectionCapsPlugin extends Plugin { return cappedGeometries; } - _addIntersectedGeometries(csgGometries) { + _addIntersectedGeometries(csgGometries, materials) { for (const key in csgGometries) { const webglGeometry = this._csgToWebGLGeometry(csgGometries[key]); - const model = this._addGeometryToScene(webglGeometry.vertices, webglGeometry.indices, key); + const model = this._addGeometryToScene(webglGeometry.vertices, webglGeometry.indices, key, materials[key]); if (model) this._prevIntersectionModels[key] = model; } @@ -399,7 +404,7 @@ class SectionCapsPlugin extends Plugin { return { vertices: new Float32Array(vertices), indices: new Uint16Array(indices) }; } - _addGeometryToScene(vertices, indices, id) { + _addGeometryToScene(vertices, indices, id, material) { if (vertices.length <= 0 && indices.length <= 0) return; const intersectedModel = new Mesh(this.viewer.scene, { id, @@ -410,10 +415,7 @@ class SectionCapsPlugin extends Plugin { }), position: [0, 0, 0], rotation: [0, 0, 0], - material: new PhongMaterial(this.viewer.scene, { - diffuse: [1, 0, 0], - backfaces: true, - }), + material, }) return intersectedModel; diff --git a/src/plugins/SectionCapsPlugin/index.js b/src/plugins/SectionCapsPlugin/index.js index a66dd247a..2aad64318 100644 --- a/src/plugins/SectionCapsPlugin/index.js +++ b/src/plugins/SectionCapsPlugin/index.js @@ -1 +1 @@ -export * from "./SectionCapsPlugin"; \ No newline at end of file +export * from "./SectionCapsPlugin.js"; \ No newline at end of file diff --git a/src/viewer/scene/model/SceneModel.js b/src/viewer/scene/model/SceneModel.js index d64d8c0c9..b9af27a81 100644 --- a/src/viewer/scene/model/SceneModel.js +++ b/src/viewer/scene/model/SceneModel.js @@ -3436,6 +3436,7 @@ export class SceneModel extends Component { * @param {Boolean} [cfg.highlighted=false] Indicates if the SceneModelEntity is initially highlighted. Highlighted appearance is configured by {@link SceneModel#highlightMaterial}. * @param {Boolean} [cfg.selected=false] Indicates if the SceneModelEntity is initially selected. Selected appearance is configured by {@link SceneModel#selectedMaterial}. * @param {Boolean} [cfg.edges=false] Indicates if the SceneModelEntity's edges are initially emphasized. Edges appearance is configured by {@link SceneModel#edgeMaterial}. + * @param {Material} [cfg.capMaterial=null] Material that will be used if user slices and caps this entity * @returns {SceneModelEntity} The new SceneModelEntity. */ createEntity(cfg) { @@ -3504,7 +3505,9 @@ export class SceneModel extends Component { cfg.id, meshes, cfg.flags, - lodCullable); // Internally sets SceneModelEntity#parent to this SceneModel + lodCullable, + cfg.capMaterial + ); // Internally sets SceneModelEntity#parent to this SceneModel this._entityList.push(entity); this._entities[cfg.id] = entity; this._entitiesToFinalize.push(entity); diff --git a/src/viewer/scene/model/SceneModelEntity.js b/src/viewer/scene/model/SceneModelEntity.js index b2a4052a1..d2519b34c 100644 --- a/src/viewer/scene/model/SceneModelEntity.js +++ b/src/viewer/scene/model/SceneModelEntity.js @@ -20,7 +20,7 @@ export class SceneModelEntity { /** * @private */ - constructor(model, isObject, id, meshes, flags, lodCullable) { + constructor(model, isObject, id, meshes, flags, lodCullable, capMaterial) { this._isObject = isObject; @@ -43,6 +43,7 @@ export class SceneModelEntity { this.meshes = meshes; this._numPrimitives = 0; + this._capMaterial = null; for (let i = 0, len = this.meshes.length; i < len; i++) { // TODO: tidier way? Refactor? const mesh = this.meshes[i]; @@ -73,6 +74,7 @@ export class SceneModelEntity { this._culled = false; this._culledVFC = false; this._culledLOD = false; + this.capMaterial = capMaterial; if (this._isObject) { model.scene._registerObject(this); @@ -644,6 +646,15 @@ export class SceneModelEntity { return this.model.saoEnabled; } + set capMaterial(value) { + if (((value instanceof Material) || value === null) && value !== this._capMaterial) + this._capMaterial = value; + } + + get capMaterial() { + return this._capMaterial; + } + getEachVertex(callback) { for (let i = 0, len = this.meshes.length; i < len; i++) { this.meshes[i].getEachVertex(callback)