Skip to content

Commit

Permalink
Implement hatching through SceneModelEntity::CapMaterial
Browse files Browse the repository at this point in the history
  • Loading branch information
ijlal99 committed Sep 27, 2024
1 parent f9cc8c6 commit ba604a5
Show file tree
Hide file tree
Showing 7 changed files with 1,493 additions and 0 deletions.
196 changes: 196 additions & 0 deletions examples/slicing/SectionCaps.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>xeokit Example</title>
<link href="../css/pageStyle.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.
</head>
<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<div class="slideout-sidebar">
<img class="info-icon" src="../../assets/images/performance_model_icon.png"/>
<h1>SceneModel</h1>
<h2>Non-realistic rendering, geometry reuse, triangle primitives</h2>
<p>
<a href="../../docs/class/src/viewer/scene/model/SceneModel.js~SceneModel.html"
target="_other">SceneModel</a> is a WebGL2-based <a
href="../../docs/class/src/viewer/scene/model/SceneModel.js~SceneModel.html"
target="_other">SceneModel</a> implementation that stores model geometry as data textures on the GPU.
</p>
<h3>Components Used</h3>
<ul>
<li>
<a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
target="_other">Viewer</a>
</li>
<li>
<a href="../../docs/class/src/viewer/scene/model/SceneModel.js~SceneModel.html"
target="_other">SceneModel</a>
</li>
</ul>
</div>
</body>

<script type="module">

import {Viewer, SceneModel, SectionPlanesPlugin, PhongMaterial, Texture, LinearEncoding, math} from "../../dist/xeokit-sdk.min.es.js";

const viewer = new Viewer({
canvasId: "myCanvas",
transparent: true,
readableGeometryEnabled: true,
});

viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
viewer.scene.camera.look = [0, -5.75, 0];
viewer.scene.camera.up = [0.37, 0.91, -0.11];

const sceneModel = new SceneModel(viewer.scene, {
id: "table",
isModel: true,
position: [0, 0, 0],
scale: [1, 1, 1],
rotation: [0, 0, 0],
edges: true,
});

sceneModel.createGeometry({
id: "myBoxGeometry",
primitive: "solid",
positions: [
1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1,
-1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1
],
indices: [
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // right
8, 9, 10, 8, 10, 11, // top
12, 13, 14, 12, 14, 15, // left
16, 17, 18, 16, 18, 19, // bottom
20, 21, 22, 20, 22, 23
],

});

sceneModel.createMesh({
id: "redLegMesh",
geometryId: "myBoxGeometry",
position: [-4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1, 0.3, 0.3],
});

sceneModel.createEntity({
id: "redLeg",
meshIds: ["redLegMesh"],
isObject: true,
}).capMaterial = new PhongMaterial(viewer.scene, {
diffuse: [1, 0.3, 0.3],
backfaces: true,
});

sceneModel.createMesh({
id: "greenLegMesh",
geometryId: "myBoxGeometry",
position: [4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 1.0, 0.3]
});

sceneModel.createEntity({
id: "greenLeg",
meshIds: ["greenLegMesh"],
isObject: true,
}).capMaterial = new PhongMaterial(viewer.scene, {
diffuse: [0.3, 1.0, 0.3],
backfaces: true,
});

sceneModel.createMesh({
id: "blueLegMesh",
geometryId: "myBoxGeometry",
position: [4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 0.3, 1.0]
});

sceneModel.createEntity({
id: "blueLeg",
meshIds: ["blueLegMesh"],
isObject: true,
}).capMaterial = new PhongMaterial(viewer.scene, {
diffuse: [0.3, 0.3, 1.0],
backfaces: true,
});

sceneModel.createMesh({
id: "yellowLegMesh",
geometryId: "myBoxGeometry",
position: [-4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1.0, 1.0, 0.0]
});

sceneModel.createEntity({
id: "yellowLeg",
meshIds: ["yellowLegMesh"],
isObject: true,
}).capMaterial = new PhongMaterial(viewer.scene, {
diffuse: [1.0, 1.0, 0.0],
backfaces: true,
});

sceneModel.createMesh({
id: "purpleTableTopMesh",
geometryId: "myBoxGeometry",
position: [0, -3, 0],
scale: [6, 0.5, 6],
rotation: [0, 0, 0],
color: [1.0, 0.3, 1.0]
});

const purpleTableTop = sceneModel.createEntity({
id: "purpleTableTop",
meshIds: ["purpleTableTopMesh"],
isObject: true,
}).capMaterial = new PhongMaterial(viewer.scene, {
diffuse: [1,1,1],
backfaces: true,
diffuseMap: new Texture(viewer.scene, {
src: "../../assets/textures/diffuse/uvGrid2.jpg",
encoding: LinearEncoding
}),
});

sceneModel.finalize();

const sectionPlanes = new SectionPlanesPlugin(viewer, {
overviewCanvasId: "mySectionPlanesOverviewCanvas",
overviewVisible: true,
});

const sectionPlane = sectionPlanes.createSectionPlane({
id: "mySectionPlane",
pos: [-2.20, 2.5, 2.3],
dir: math.normalizeVec3([1.0, 0.01, 1])
});

window.sectionPlane = sectionPlane;

sectionPlanes.showControl(sectionPlane.id);



</script>
</html>

150 changes: 150 additions & 0 deletions examples/slicing/SectionPlanesPlugin_Duplex_SectionCaps.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<!doctype html>
<html>

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>xeokit Example</title>
<link href="../css/pageStyle.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.
</head>

<body>
<input type="checkbox" id="info-button" />
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<div class="slideout-sidebar">
<img class="info-icon" src="../../assets/images/section_plane_icon.png" />
<h1>SectionPlanesPlugin</h1>
<h2>Slices models open to reveal internal structures</h2>
<p>In this example, we're loading an IFC2x3 BIM model from the file system, then slicing it with a section
plane.</p>
<h3>Stats</h3>
<ul>
<li>
<div id="time">Loading JavaScript modules...</div>
</li>
</ul>
<h3>Components used</h3>
<ul>
<li>
<a href="../../docs/class/src/viewer/Viewer.js~Viewer.html" target="_other">Viewer</a>
</li>
<li>
<a href="../../docs/class/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js~XKTLoaderPlugin.html"
target="_other">XKTLoaderPlugin</a>
</li>
<li>
<a href="../../docs/class/src/plugins/SectionPlanesPlugin/SectionPlanesPlugin.js~SectionPlanesPlugin.html"
target="_other">SectionPlanesPlugin</a>
</li>
</ul>
<h3>Resources</h3>
<ul>
<li>
<a href="http://openifcmodel.cs.auckland.ac.nz/Model/Details/274" target="_other">Model source</a>
</li>
</ul>
</div>
</body>

<script type="module">

//------------------------------------------------------------------------------------------------------------------
// Import the modules we need for this example
//------------------------------------------------------------------------------------------------------------------

import { Viewer, SceneModel, XKTLoaderPlugin, SectionPlanesPlugin, PhongMaterial, math } from "../../dist/xeokit-sdk.min.es.js";

//------------------------------------------------------------------------------------------------------------------
// Create a Viewer and arrange the camera
//------------------------------------------------------------------------------------------------------------------

const viewer = new Viewer({
canvasId: "myCanvas",
transparent: true,
readableGeometryEnabled: true
});

viewer.camera.eye = [-2.341298674548419, 22.43987089731119, 7.236688436028655];
viewer.camera.look = [4.399999999999963, 3.7240000000000606, 8.899000000000006];
viewer.camera.up = [0.9102954845584759, 0.34781746407929504, 0.22446635042673466];

const cameraControl = viewer.cameraControl;
cameraControl.navMode = "orbit";
cameraControl.followPointer = true;

//----------------------------------------------------------------------------------------------------------------------
// Create a xeokit loader plugin, load a model, fit to view
//----------------------------------------------------------------------------------------------------------------------

const xktLoader = new XKTLoaderPlugin(viewer);

var t0 = performance.now();

document.getElementById("time").innerHTML = "Loading model...";

const sceneModel = xktLoader.load({
id: "myModel",
src: "../../assets/models/xkt/v10/glTF-Embedded/Duplex_A_20110505.glTFEmbedded.xkt",
edges: true
});

sceneModel.on("loaded", () => {

var t1 = performance.now();
document.getElementById("time").innerHTML = "Model loaded in " + Math.floor(t1 - t0) / 1000.0 + " seconds<br>Objects: " + sceneModel.numEntities;

//------------------------------------------------------------------------------------------------------------------
// Add caps materials to all objects inside the loaded model that have an opacity equal to or above 0.7
//------------------------------------------------------------------------------------------------------------------
const opacityThreshold = 0.7;
const material = new PhongMaterial(viewer.scene,{
diffuse: [1.0, 0.0, 0.0],
backfaces: true
});
addCapsMaterialsToAllObjects(sceneModel, opacityThreshold, material);

//------------------------------------------------------------------------------------------------------------------
// Create a moving SectionPlane, that moves through the table models
//------------------------------------------------------------------------------------------------------------------

const sectionPlanes = new SectionPlanesPlugin(viewer, {
overviewCanvasId: "mySectionPlanesOverviewCanvas",
overviewVisible: true,
});

const sectionPlane = sectionPlanes.createSectionPlane({
id: "mySectionPlane",
pos: [0.5, 2.5, 5.0],
dir: math.normalizeVec3([1.0, 0.01, 1])
});

sectionPlanes.showControl(sectionPlane.id);

const sectionPlane2 = sectionPlanes.createSectionPlane({
id: "mySectionPlane2",
pos: [8.0, 2.5, 12.5],
dir: math.normalizeVec3([-1.0, -0.01, -1])
})

sectionPlanes.showControl(sectionPlane2.id);

window.viewer = viewer;

});

function addCapsMaterialsToAllObjects(sceneModel, opacityThreshold, material) {
const allObjects = sceneModel.objects;
for(const key in allObjects){
const object = allObjects[key];
if(object.opacity >= opacityThreshold)
object.capMaterial = material;
}
}


</script>

</html>
Loading

0 comments on commit ba604a5

Please sign in to comment.