Compare commits

4 Commits

Author SHA1 Message Date
Mike Tasset f87ca4db70 Comment out init 2024-11-14 07:14:13 +00:00
Mike Tasset a70e8385ea Fully hide everything on demo branch 2024-11-14 07:12:59 +00:00
Mike Tasset a910ba1447 Minor cleanup 2024-11-14 07:12:26 +00:00
Mike Tasset b7a5692167 Init demo branch 2024-11-14 07:10:23 +00:00
5 changed files with 69 additions and 105 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
<template>
<main class="relative">
<SpeckleViewer />
<ControlPanel />
<SelectionPanel />
<!-- <ControlPanel />
<SelectionPanel /> -->
</main>
</template>
+14 -17
View File
@@ -8,11 +8,11 @@
</div>
<div class="py-3 px-4">
<div class="flex gap-x-2">
<BaseButton @click="getLevels">Get levels</BaseButton>
<BaseButton @click="categorizeLevels">Categorize levels</BaseButton>
<BaseButton @click="uncategorizeLevels">Uncategorize levels</BaseButton>
<!-- <BaseButton @click="getLevels">Get levels</BaseButton> -->
<!-- <BaseButton @click="categorizeLevels">Categorize levels</BaseButton> -->
<!-- <BaseButton @click="uncategorizeLevels">Uncategorize levels</BaseButton> -->
</div>
<div v-if="levels" class="flex flex-col gap-y-2 items-start text-sm mt-4 mb-2">
<!-- <div v-if="levels" class="flex flex-col gap-y-2 items-start text-sm mt-4 mb-2">
<button
v-for="(property, index) in levels?.valueGroups"
:key="`level-${index}`"
@@ -22,7 +22,7 @@
{{ property.value }}
</button>
<button class="font-medium hover:text-blue-600 mt-2" @click="resetFilters">Show all</button>
</div>
</div> -->
</div>
</div>
</div>
@@ -39,23 +39,20 @@ const { categorize, isolate, animate, resetFilters } = useViewer()
const levels = ref()
// Get all the properties with the key 'properties.Instance Parameters.Constraints.Level.value'
const getLevels = async () => {
if (!properties) return
levels.value = properties.find((property: PropertyInfo) => property.key === 'properties.Instance Parameters.Constraints.Level.value')
const getLevels = () => {
// if (!properties) return
// levels.value = properties.find((property: PropertyInfo) => property.key === 'properties.Instance Parameters.Constraints.Level.value')
}
// Categorize the levels and isolate the objects
const categorizeLevels = async () => {
await getLevels()
categorize(levels.value.valueGroups)
isolate(levels.value.valueGroups.flatMap((group: StringPropertyInfo['valueGroups']) => group.ids))
animate()
// getLevels()
// categorize(levels.value.valueGroups)
// isolate(levels.value.valueGroups.flatMap((group: StringPropertyInfo['valueGroups']) => group.ids))
// animate()
}
// Reset filters and reverse the animation
const uncategorizeLevels = async () => {
resetFilters()
animate({ reverse: true })
// resetFilters()
// animate({ reverse: true })
}
</script>
+2 -2
View File
@@ -7,7 +7,7 @@
<h2 class="text-sm font-medium text-gray-800">Selection info</h2>
</div>
<div class="py-3 px-4 text-sm flex flex-col gap-y-1">
<template v-if="selectionInfo">
<!-- <template v-if="selectionInfo">
<div>
<span class="font-medium">ID:</span> {{ selectionInfo.id }}
</div>
@@ -18,7 +18,7 @@
<span class="font-medium">Level:</span> {{ selectionInfo.level.name }}
</div>
</template>
<p v-else class="text-sm text-gray-500">No selection</p>
<p v-else class="text-sm text-gray-500">No selection</p> -->
</div>
</div>
</div>
+4 -6
View File
@@ -11,18 +11,16 @@ import useViewer from '@/composables/viewer'
const canvas = useTemplateRef('canvas')
const { init, addExtensions,loadModelFromUrl } = useViewer()
// For demo purposes we will load two models
// You can replace these with your own as well
const MODELS = {
ONE: 'https://app.speckle.systems/projects/7744b171ca/models/e32f5e5416',
TWO: 'https://app.speckle.systems/projects/7744b171ca/models/7fee46df4b'
}
onMounted(async () => {
if (!canvas.value) return
// if (!canvas.value) return
await init(canvas.value)
addExtensions()
await loadModelFromUrl(MODELS.ONE)
// await init(canvas.value)
// addExtensions()
// await loadModelFromUrl(MODELS.ONE)
})
</script>
+47 -78
View File
@@ -19,107 +19,76 @@ export let properties: PropertyInfo[] | undefined = undefined
const selectionInfo = ref(null)
export default function useViewer() {
/**
* Initialize the viewer
* @param element - DOM element to initialize the viewer on
*/
async function init(element: HTMLDivElement) {
const params = {
...DefaultViewerParams,
showStats: false,
verbose: true
}
const init = async (element: HTMLDivElement) => {
// const params = {
// ...DefaultViewerParams,
// showStats: false,
// verbose: true
// }
viewer = new Viewer(element, params)
await viewer.init()
// viewer = new Viewer(element, params)
// await viewer.init()
// Get the object properties after the model has loaded
// This will cache them and allow faster access later
viewer.on(ViewerEvent.LoadComplete, async() => {
properties = await viewer.getObjectProperties()
})
// viewer.on(ViewerEvent.LoadComplete, async() => {
// properties = await viewer.getObjectProperties()
// })
// Handle object clicks in the viewer
viewer.on(ViewerEvent.ObjectClicked, (event: SelectionEvent | null) => {
// If there are no nodes, the click was not on an object
if (event) {
const nodes = viewer.getWorldTree().findId(event.hits[0].node.model.id)
if (nodes && nodes.length > 0) {
selectionInfo.value = nodes[0].model.raw
}
} else {
selectionInfo.value = null
}
})
// viewer.on(ViewerEvent.ObjectClicked, (event: SelectionEvent | null) => {
// if (event) {
// const nodes = viewer.getWorldTree().findId(event.hits[0].node.model.id)
// if (nodes && nodes.length > 0) {
// selectionInfo.value = nodes[0].model.raw
// }
// } else {
// selectionInfo.value = null
// }
// })
}
/**
* The viewer can be extended with additional functionality by adding extensions
* You can use extensions provided by the viewer, or create your own
*/
function addExtensions() {
if (!viewer) return
viewer.createExtension(CameraController)
viewer.createExtension(SelectionExtension)
viewer.createExtension(FilteringExtension)
viewer.createExtension(Catalogue)
const addExtensions = () => {
// if (!viewer) return
// viewer.createExtension(CameraController)
// viewer.createExtension(SelectionExtension)
// viewer.createExtension(FilteringExtension)
// viewer.createExtension(Catalogue)
}
/**
* Load a model from a Speckle URL
* @param url - The URL of the Speckle model
* @param authToken - This is required if the model is private
*/
const loadModelFromUrl = async (url: string, authToken?: string) => {
const urls = await UrlHelper.getResourceUrls(url, authToken)
urls.forEach(async (url) => {
if (!viewer) return
const loader = new SpeckleLoader(viewer.getWorldTree(), url, '')
await viewer.loadObject(loader, true)
})
// const urls = await UrlHelper.getResourceUrls(url, authToken)
// urls.forEach(async (url) => {
// if (!viewer) return
// const loader = new SpeckleLoader(viewer.getWorldTree(), url, '')
// await viewer.loadObject(loader, true)
// })
}
/**
* Isolate objects in the viewer
* @param ids - List of IDs to isolate
*/
const isolate = async (ids: Array<string>) => {
if (!viewer) return
const filter = viewer.getExtension(FilteringExtension)
filter.resetFilters()
filter.isolateObjects(ids)
// if (!viewer) return
// const filter = viewer.getExtension(FilteringExtension)
// filter.resetFilters()
// filter.isolateObjects(ids)
}
/**
* Categorize a certain property in the viewer
* @param input - ids to categorize
* @param options - options for the catalogue
*/
const categorize = async (
input: Array<{ ids: Array<string>; value: string }>,
options?: CatalogueOptions
) => {
if (!viewer) return
const catalogue = viewer.getExtension(Catalogue)
catalogue.categorize(input, options)
// if (!viewer) return
// const catalogue = viewer.getExtension(Catalogue)
// catalogue.categorize(input, options)
}
/**
* Use the catalogue extension to animate the objects
* @param options - option to reverse the animation
*/
const animate = async (options?:{ reverse?: boolean }) => {
const { reverse } = options || {}
if (!viewer) return
const catalogue = viewer.getExtension(Catalogue)
catalogue.animate(reverse)
// const { reverse } = options || {}
// if (!viewer) return
// const catalogue = viewer.getExtension(Catalogue)
// catalogue.animate(reverse)
}
// Reset the filtering extension
const resetFilters = async () => {
if (!viewer) return
const filter = viewer.getExtension(FilteringExtension)
filter.resetFilters()
// if (!viewer) return
// const filter = viewer.getExtension(FilteringExtension)
// filter.resetFilters()
}
return {