diff --git a/packages/components/src/civil/Civil3DNavigator/example.ts b/packages/components/src/civil/Civil3DNavigator/example.ts index cf17d6633..03cdf02d6 100644 --- a/packages/components/src/civil/Civil3DNavigator/example.ts +++ b/packages/components/src/civil/Civil3DNavigator/example.ts @@ -1,5 +1,3 @@ -// Set up scene (see SimpleScene tutorial) - import * as THREE from "three"; import Stats from "stats.js"; import * as OBC from "../.."; @@ -46,20 +44,8 @@ const file = await fetch("../../../resources/asdf.frag"); const data = await file.arrayBuffer(); const buffer = new Uint8Array(data); const model = await fragments.load(buffer); -// const properties = await fetch("../../../resources/asdf.json"); -// model.setLocalProperties(await properties.json()); - -// const culler = new OBC.ScreenCuller(components); -// culler.setup(); -// -// for(const fragment of model.items) { -// culler.elements.add(fragment.mesh); -// } -// -// container.addEventListener("mouseup", () => culler.elements.needsUpdate = true); -// container.addEventListener("wheel", () => culler.elements.needsUpdate = true); - -// culler.elements.needsUpdate = true; +const properties = await fetch("../../../resources/asdf.json"); +model.setLocalProperties(await properties.json()); const mainToolbar = new OBC.Toolbar(components, { name: "Main Toolbar", @@ -70,12 +56,29 @@ mainToolbar.addChild(fragmentIfcLoader.uiElement.get("main")); console.log(model); -// Set up road navigator +/* +### 🌍 Creating a 3D World with Civil 3D Navigator + +**🔧 Setting up Civil 3D Navigator** + ___ + Now that we've established our simple scene, let's integrate the + Civil 3D Navigator to explore our 3D model further. First, we need to + create an instance of the Civil 3D Navigator component. This will enable + us to navigate through our 3D environment and interact with the model. +*/ const navigator = new OBC.Civil3DNavigator(components); navigator.draw(model); navigator.setup(); +/* +**🖌️ Configuring Navigator Highlighting** + ___ + To enhance user interaction, we'll configure highlighting for + civil elements within the navigator. This will provide visual feedback + when interacting with civil elements, making the experience more intuitive. +*/ + navigator.highlighter.hoverCurve.material.color.set(1, 1, 1); const { material: hoverPointsMaterial } = navigator.highlighter.hoverPoints; @@ -85,6 +88,13 @@ if (Array.isArray(hoverPointsMaterial)) { } else if ("color" in hoverPointsMaterial) (hoverPointsMaterial.color as THREE.Color).set(1, 1, 1); +/* +**⚪ Highlight Sphere** + ___ + A sphere object is defined and introduced to the scene everytime the + user interacts with the alignments. Try it out! +*/ + const sphere = new THREE.Sphere(undefined, 20); navigator.onHighlight.add(({ point }) => { @@ -92,12 +102,10 @@ navigator.onHighlight.add(({ point }) => { cameraComponent.controls.fitToSphere(sphere, true); }); -// navigator.highlighter.highlightColor = 0xff0000; -// navigator.onHighlight.add((data) => {}); - -// const hider = new OBC.FragmentHider(components); -// await hider.loadCached(); -// mainToolbar.addChild(hider.uiElement.get("main")); +/* + With that, we finished! You've successfully created a Navigator compatible + with Civil elements and other Civil components. +*/ const stats = new Stats(); stats.showPanel(2); diff --git a/packages/components/src/civil/CivilCrossSectionNavigator/example.ts b/packages/components/src/civil/CivilCrossSectionNavigator/example.ts index 8a551e817..ac0e3cd07 100644 --- a/packages/components/src/civil/CivilCrossSectionNavigator/example.ts +++ b/packages/components/src/civil/CivilCrossSectionNavigator/example.ts @@ -1,5 +1,3 @@ -// Set up scene (see SimpleScene tutorial) - import * as THREE from "three"; import Stats from "stats.js"; import * as OBC from "../.."; @@ -18,6 +16,8 @@ components.renderer = rendererComponent; const cameraComponent = new OBC.SimpleCamera(components); components.camera = cameraComponent; +components.raycaster = new OBC.SimpleRaycaster(components); + components.init(); rendererComponent.postproduction.enabled = true; @@ -40,25 +40,13 @@ fragmentIfcLoader.settings.wasm = { fragmentIfcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true; fragmentIfcLoader.settings.webIfc.OPTIMIZE_PROFILES = true; -const file = await fetch("../../../resources/asdf2.frag"); +const file = await fetch("../../../resources/asdf.frag"); const data = await file.arrayBuffer(); const buffer = new Uint8Array(data); const model = await fragments.load(buffer); -const properties = await fetch("../../../resources/asdf2.json"); +const properties = await fetch("../../../resources/asdf.json"); model.setLocalProperties(await properties.json()); -// const culler = new OBC.ScreenCuller(components); -// culler.setup(); -// -// for(const fragment of model.items) { -// culler.elements.add(fragment.mesh); -// } -// -// container.addEventListener("mouseup", () => culler.elements.needsUpdate = true); -// container.addEventListener("wheel", () => culler.elements.needsUpdate = true); - -// culler.elements.needsUpdate = true; - const mainToolbar = new OBC.Toolbar(components, { name: "Main Toolbar", position: "bottom", @@ -68,11 +56,10 @@ mainToolbar.addChild(fragmentIfcLoader.uiElement.get("main")); console.log(model); -// Set up road navigator - const navigator = new OBC.CivilPlanNavigator(components); const horizontalWindow = navigator.uiElement.get("floatingWindow"); horizontalWindow.visible = true; + navigator.draw(model); const elevationNavigator = new OBC.CivilElevationNavigator(components); @@ -106,10 +93,40 @@ navigator.onHighlight.add(({ mesh }) => { ); }); +/* +### 🌍 Exploring Civil Cross Sections with Navigators + +**🔧 Setting up Civil Cross Section Navigator** + ___ + The Cross Section Navigator is a tool that will allow you to clearly visualize + the cross section of any civil IFC model, in any point selected in an alignment. + Let's begin! + + **Important**: This tool requires the Civil 3D Navigator and the Civil Plan Navigator + tools to be initialized beforehand. Make sure to check out those respective tutorials + before proceeding. + + We'll start by setting up the navigator component within our scene. +*/ + const crossNavigator = new OBC.CivilCrossSectionNavigator(components); + +/* +**🌅 Defining the UI for the tool** + ___ + The UI element to be used with this tool is a floating window, so let's + define it and introduce it to our scene. +*/ + const crossWindow = crossNavigator.uiElement.get("floatingWindow"); crossWindow.visible = true; +/* + And that's it! You've successfully set up the Civil Cross Section Navigator. + Go ahead and interact with the Horizontal Alignment Window in any point of an alignment, + and the cross section of the selected area will be displayed in the Cross Section Window. +*/ + navigator.onMarkerChange.add(({ alignment, percentage, type, curve }) => { elevationNavigator.setMarker(alignment, percentage, type); navigator3D.setMarker(alignment, percentage, type); @@ -126,13 +143,6 @@ navigator.onMarkerHidden.add(({ type }) => { navigator3D.hideMarker(type); }); -// const navigator = new OBC.Civil3DNavigator(components); -// navigator.draw(model); -// navigator.setup(); -// -// navigator.highlighter.hoverCurve.material.color.set(1, 1, 1); -// navigator.highlighter.hoverPoints.material.color.set(1, 1, 1); - window.addEventListener("keydown", () => { elevationNavigator.scene.scaleY += 0.1; }); @@ -163,12 +173,6 @@ for (const category in classifications.entities) { } } -// classifier.find({{entities: []}}) - -// const hider = new OBC.FragmentHider(components); -// await hider.loadCached(); -// mainToolbar.addChild(hider.uiElement.get("main")); - const stats = new Stats(); stats.showPanel(2); document.body.append(stats.dom); diff --git a/packages/components/src/civil/CivilElevationNavigator/example.html b/packages/components/src/civil/CivilElevationNavigator/example.html new file mode 100644 index 000000000..837e28499 --- /dev/null +++ b/packages/components/src/civil/CivilElevationNavigator/example.html @@ -0,0 +1,33 @@ + + + + + + + + + + + Civil Elevation Navigator + + + + +
+ + + + \ No newline at end of file diff --git a/packages/components/src/civil/CivilElevationNavigator/example.ts b/packages/components/src/civil/CivilElevationNavigator/example.ts new file mode 100644 index 000000000..af8f86a49 --- /dev/null +++ b/packages/components/src/civil/CivilElevationNavigator/example.ts @@ -0,0 +1,125 @@ +import * as THREE from "three"; +import Stats from "stats.js"; +import * as OBC from "../.."; + +const container = document.getElementById("container")!; + +const components = new OBC.Components(); + +const sceneComponent = new OBC.SimpleScene(components); +sceneComponent.setup(); +components.scene = sceneComponent; + +const rendererComponent = new OBC.PostproductionRenderer(components, container); +components.renderer = rendererComponent; + +const cameraComponent = new OBC.SimpleCamera(components); +components.camera = cameraComponent; +components.raycaster = new OBC.SimpleRaycaster(components); + +components.init(); + +rendererComponent.postproduction.enabled = true; +rendererComponent.postproduction.customEffects.outlineEnabled = true; + +cameraComponent.controls.setLookAt(12, 6, 8, 0, 0, -10); + +const grid = new OBC.SimpleGrid(components, new THREE.Color(0x666666)); +const customEffects = rendererComponent.postproduction.customEffects; +customEffects.excludedMeshes.push(grid.get()); + +const fragments = new OBC.FragmentManager(components); +const fragmentIfcLoader = new OBC.FragmentIfcLoader(components); + +fragmentIfcLoader.settings.wasm = { + path: "https://unpkg.com/web-ifc@0.0.50/", + absolute: true, +}; + +fragmentIfcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true; +fragmentIfcLoader.settings.webIfc.OPTIMIZE_PROFILES = true; + +const file = await fetch("../../../resources/asdf.frag"); +const data = await file.arrayBuffer(); +const buffer = new Uint8Array(data); +const model = await fragments.load(buffer); + +const navigator = new OBC.Civil3DNavigator(components); +navigator.draw(model); +navigator.setup(); +navigator.highlighter.hoverCurve.material.color.set(1, 1, 1); +const { material: hoverPointsMaterial } = navigator.highlighter.hoverPoints; +if (Array.isArray(hoverPointsMaterial)) { + const material = hoverPointsMaterial[0]; + if ("color" in material) (material.color as THREE.Color).set(1, 1, 1); +} else if ("color" in hoverPointsMaterial) + (hoverPointsMaterial.color as THREE.Color).set(1, 1, 1); + +const planNavigator = new OBC.CivilPlanNavigator(components); +const horizontalWindow = planNavigator.uiElement.get("floatingWindow"); +horizontalWindow.visible = true; +planNavigator.draw(model); + +/* +### 🌍 Exploring Civil Elevation View with Navigators + +**🔧 Setting up Civil Elevation Navigator** + ___ + The Elevation Navigator is a tool that allows exploration and visualization of + the alignments in a civil IFC file, by creating a drawer that shows their + its elevation view. Let's get into it! + + **Important**: This tool requires the Civil 3D Navigator and the Civil Plan Navigator + tools to be initialized beforehand. Make sure to check out those respective tutorials + before proceeding. + + We'll start by setting up the navigator component within our scene. +*/ + +const elevationNavigator = new OBC.CivilElevationNavigator(components); + +/* +**🌅 Defining the UI for the tool** + ___ + The UI element to be used with this tool is a drawer element, so let's + define it and introduce it to our scene. +*/ + +const drawer = elevationNavigator.uiElement.get("drawer"); +drawer.visible = true; + +planNavigator.onHighlight.add(({ mesh }) => { + /* + **🖌️ Configuring Navigator Highlighting** + ___ + Finally, the following lines are added to the highlighter tool defined + previously for the Plan Navigator. These lines provide visual objects + specific to the Elevation Navigator, improving user experience. + */ + elevationNavigator.clear(); + elevationNavigator.draw(model, [mesh.curve.alignment]); + elevationNavigator.highlighter.select(mesh); + + navigator.highlighter.select(mesh); + + const index = mesh.curve.index; + const curve3d = mesh.curve.alignment.absolute[index]; + curve3d.mesh.geometry.computeBoundingSphere(); + cameraComponent.controls.fitToSphere( + curve3d.mesh.geometry.boundingSphere, + true, + ); +}); + +/* + That's it! We're done setting up the Civil Elevation Navigator. Now you can + interact with any alignment in the Horizontal Alignment Window, and the Elevation + View of that specific alignment will be displayed in the Elevation Window. +*/ + +const stats = new Stats(); +stats.showPanel(2); +document.body.append(stats.dom); +stats.dom.style.left = "0px"; +rendererComponent.onBeforeUpdate.add(() => stats.begin()); +rendererComponent.onAfterUpdate.add(() => stats.end()); diff --git a/packages/components/src/civil/CivilPlanNavigator/example.ts b/packages/components/src/civil/CivilPlanNavigator/example.ts index 40c2571de..aaecc72d2 100644 --- a/packages/components/src/civil/CivilPlanNavigator/example.ts +++ b/packages/components/src/civil/CivilPlanNavigator/example.ts @@ -1,5 +1,3 @@ -// Set up scene (see SimpleScene tutorial) - import * as THREE from "three"; import Stats from "stats.js"; import * as OBC from "../.."; @@ -41,31 +39,11 @@ fragmentIfcLoader.settings.wasm = { fragmentIfcLoader.settings.webIfc.COORDINATE_TO_ORIGIN = true; fragmentIfcLoader.settings.webIfc.OPTIMIZE_PROFILES = true; -// 2. IFC 4 fragment integration - const file = await fetch("../../../resources/asdf.frag"); const data = await file.arrayBuffer(); const buffer = new Uint8Array(data); const model = await fragments.load(buffer); -// 3. Horizontal alignment - -const planNavigator = new OBC.CivilPlanNavigator(components); -const horizontalWindow = planNavigator.uiElement.get("floatingWindow"); -horizontalWindow.visible = true; -planNavigator.draw(model); - -// 4. Vertical alignment - -const elevationNavigator = new OBC.CivilElevationNavigator(components); -const drawer = elevationNavigator.uiElement.get("drawer"); -drawer.visible = true; - -// 4.5 Set scene elevation in horizontal -// planNavigator.elevation = elevationNavigator.scene.scene; - -// 5. 3D alignment - const navigator = new OBC.Civil3DNavigator(components); navigator.draw(model); navigator.setup(); @@ -77,51 +55,45 @@ if (Array.isArray(hoverPointsMaterial)) { } else if ("color" in hoverPointsMaterial) (hoverPointsMaterial.color as THREE.Color).set(1, 1, 1); -// 6. Cross section +/* +### 🌍 Exploring Civil Plan View with Navigators -// const crossNavigator = new OBC.CivilCrossSectionNavigator(components); -// const crossWindow = crossNavigator.uiElement.get("floatingWindow"); -// crossWindow.visible = true; +**🔧 Setting up Civil Plan Navigator** + ___ + The Plan Navigator is a tool that allows exploration and visualization of + the alignments in a civil IFC file, by creating a window that shows their + plan view. Let's explore it! -// const classifier = new OBC.FragmentClassifier(components); -// classifier.byEntity(model); + **Important**: This tool requires the Civil 3D Navigator tool to be + initialized beforehand. Make sure to check out that respective tutorial + before proceeding. -// const classifications = classifier.get(); + We'll start by setting up the navigator component within our scene and + adding our civil model to it. +*/ -// const clipper = components.tools.get(OBC.EdgesClipper); -// const styles = clipper.styles.get(); - -// for (const category in classifications.entities) { -// const found = classifier.find({ entities: [category] }); - -// const color = new THREE.Color( -// Math.random(), -// Math.random(), -// Math.random() -// ); - -// const lineMaterial = new THREE.LineBasicMaterial({ color }); -// clipper.styles.create(category, new Set(), lineMaterial); +const planNavigator = new OBC.CivilPlanNavigator(components); +planNavigator.draw(model); -// for (const fragID in found) { -// const foundFrag = fragments.list[fragID]; -// if(!foundFrag) { -// continue; -// } -// styles[category].fragments[fragID] = new Set(found[fragID]); -// styles[category].meshes.add(foundFrag.mesh); -// } -// } +/* +**🌅 Defining the UI for the tool** + ___ + The UI element to be used with this tool is a floating window, so let's + define it and introduce it to our scene. +*/ -// // 7. Synchronization +const horizontalWindow = planNavigator.uiElement.get("floatingWindow"); +horizontalWindow.visible = true; -// const sphere = new THREE.Sphere(undefined, 20); +/* +**🖌️ Configuring Navigator Highlighting** + ___ + Finally, we configure a highlighter to be able to interact with the + alignments shown in the navigator. This will provide multiple visual objects + when navigating through the model, making the experience more intuitive. +*/ planNavigator.onHighlight.add(({ mesh }) => { - elevationNavigator.clear(); - elevationNavigator.draw(model, [mesh.curve.alignment]); - elevationNavigator.highlighter.select(mesh); - navigator.highlighter.select(mesh); const index = mesh.curve.index; @@ -133,24 +105,12 @@ planNavigator.onHighlight.add(({ mesh }) => { ); }); -// planNavigator.onMarkerChange.add(({ alignment, percentage, type, curve }) => { -// elevationNavigator.setMarker(alignment, percentage, type); -// navigator3D.setMarker(alignment, percentage, type); - -// if(type === "select") { -// const mesh = curve.alignment.absolute[curve.index].mesh; -// const point = alignment.getPointAt(percentage, "absolute"); -// crossNavigator.set(mesh, point); -// } -// }) - -// window.addEventListener("keydown", () => { -// elevationNavigator.scene.scaleY += 0.2; -// }) - -// const hider = new OBC.FragmentHider(components); -// await hider.loadCached(); -// mainToolbar.addChild(hider.uiElement.get("main")); +/* + And we're done! You've successfully set up the Civil Plan Navigator. + Now you can interact with the Horizontal Alignment Window. Now try adding + some other compatible tools like the Civil Elevation Navigator and the + Civil Cross Section Navigator.🚀 +*/ const stats = new Stats(); stats.showPanel(2);