Sfoglia il codice sorgente

Add SimplifyModifierPlugin, MeshOptSimplifyModifierPlugin and examples.

master
Palash Bansal 2 anni fa
parent
commit
181a9606e6
Nessun account collegato all'indirizzo email del committer

+ 43
- 0
README.md Vedi File

- [STLLoadPlugin](#stlloadplugin) - Add support for loading .stl files - [STLLoadPlugin](#stlloadplugin) - Add support for loading .stl files
- [KTX2LoadPlugin](#ktx2loadplugin) - Add support for loading .ktx2 files - [KTX2LoadPlugin](#ktx2loadplugin) - Add support for loading .ktx2 files
- [KTXLoadPlugin](#ktxloadplugin) - Add support for loading .ktx files - [KTXLoadPlugin](#ktxloadplugin) - Add support for loading .ktx files
- [SimplifyModifierPlugin](#simplifymodifierplugin) - Boilerplate for plugin to simplify geometries
- [MeshOptSimplifyModifierPlugin](#meshoptsimplifymodifierplugin) - Simplify geometries using meshoptimizer library
- [Packages](#threepipe-packages) - [Packages](#threepipe-packages)
- [@threepipe/plugin-tweakpane](#threepipeplugin-tweakpane) Tweakpane UI Plugin - [@threepipe/plugin-tweakpane](#threepipeplugin-tweakpane) Tweakpane UI Plugin
- [@threepipe/plugin-blueprintjs](#threepipeplugin-blueprintjs) BlueprintJs UI Plugin - [@threepipe/plugin-blueprintjs](#threepipeplugin-blueprintjs) BlueprintJs UI Plugin
const texture = await viewer.load('file.ktx') const texture = await viewer.load('file.ktx')
``` ```


## SimplifyModifierPlugin

[Example](https://threepipe.org/examples/#simplify-modifier-plugin/) —
[Source Code](./src/plugins/extras/SimplifyModifierPlugin.ts) —
[API Reference](https://threepipe.org/docs/classes/SimplifyModifierPlugin.html)

Boilerplate for implementing a plugin for simplifying geometries.
This is a base class and cannot be used directly.

A sample to use it:
```typescript
class SimplifyModifierPluginImpl extends SimplifyModifierPlugin {
protected _simplify(geometry: IGeometry, count: number) {
return new SimplifyModifier().modify(geometry, count) as IGeometry
}
}

const plugin = viewer.addPluginSync(new SimplifyModifierPluginImpl())

const root = await viewer.load('file.glb')
plugin.simplifyAll(root, {factor: 0.75})
```
Check the [example](https://threepipe.org/examples/#simplify-modifier-plugin/) for full implementation.

## MeshOptSimplifyModifierPlugin

[Example](https://threepipe.org/examples/#meshopt-simplify-modifier-plugin/) —
[Source Code](./src/plugins/extras/MeshOptSimplifyModifierPlugin.ts) —
[API Reference](https://threepipe.org/docs/classes/MeshOptSimplifyModifierPlugin.html)

Simplify modifier using [meshoptimizer](https://github.com/zeux/meshoptimizer) library. It Loads the library at runtime from a customisable CDN URL.

Note: It does not guarantee that the geometry will be simplified to the exact target count.

```typescript
const simplifyModifier = viewer.addPluginSync(new MeshOptSimplifyModifierPlugin())

const root = await viewer.load('file.glb')
simplifyModifier.simplifyAll(root, {factor: 0.75})
```

# @threepipe Packages # @threepipe Packages


Additional plugins can be found in the [plugins](plugins/) directory. Additional plugins can be found in the [plugins](plugins/) directory.

+ 3
- 1
examples/index.html Vedi File

<li><a href="./device-orientation-controls-plugin/">Device Orientation Controls Plugin (Gyroscope) </a></li> <li><a href="./device-orientation-controls-plugin/">Device Orientation Controls Plugin (Gyroscope) </a></li>
<li><a href="./pointer-lock-controls-plugin/">Pointer Lock(FPS) Controls Plugin </a></li> <li><a href="./pointer-lock-controls-plugin/">Pointer Lock(FPS) Controls Plugin </a></li>
<li><a href="./three-first-person-controls-plugin/">Three First Person(look around) Controls Plugin </a></li> <li><a href="./three-first-person-controls-plugin/">Three First Person(look around) Controls Plugin </a></li>
<li><a href="./simplify-modifier-plugin/">Simplify Modifier Plugin </a></li>
<li><a href="./meshopt-simplify-modifier-plugin/">MeshOpt Simplify Modifier Plugin </a></li>
</ul> </ul>
<h2 class="category">Import</h2> <h2 class="category">Import</h2>
<ul> <ul>
<li><a href="./image-snapshot-export/">PNG, JPEG, WEBP Export<br/>(Image Snapshot) </a></li> <li><a href="./image-snapshot-export/">PNG, JPEG, WEBP Export<br/>(Image Snapshot) </a></li>
<li><a href="./render-target-export/">EXR, PNG, JPEG, WEBP Export<br/>(Render Target Export) </a></li> <li><a href="./render-target-export/">EXR, PNG, JPEG, WEBP Export<br/>(Render Target Export) </a></li>
<li><a href="./glb-export/">GLB Export </a></li> <li><a href="./glb-export/">GLB Export </a></li>
<li><a href="./pmat-material-export/">PMAT Material export </a></li>
<li><a href="./pmat-material-export/">PMAT Material Export </a></li>
<li><a href="./svg-geometry-playground/">SVG Geometry Playground </a></li> <li><a href="./svg-geometry-playground/">SVG Geometry Playground </a></li>
</ul> </ul>
<h2 class="category">UI Config</h2> <h2 class="category">UI Config</h2>

+ 36
- 0
examples/meshopt-simplify-modifier-plugin/index.html Vedi File

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MeshOpt Simplify Modifier Plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 40
- 0
examples/meshopt-simplify-modifier-plugin/script.ts Vedi File

import {_testFinish, IObject3D, MeshOptSimplifyModifierPlugin, PickingPlugin, ThreeViewer} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
import {createSimpleButtons} from '../examples-utils/simple-bottom-buttons.js'

async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
plugins: [PickingPlugin],
})

const simplify = viewer.addPluginSync(MeshOptSimplifyModifierPlugin)

const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', {
setBackground: true,
})
const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
})

result?.traverse((obj) => {
obj.materials?.map(m=>m.wireframe = true)
})

createSimpleButtons({
['Simplify']: async(_: HTMLButtonElement) => {
await simplify.simplifyAll(result, {factor: 0.5})
},
})

ui.setupPluginUi(MeshOptSimplifyModifierPlugin)
ui.setupPluginUi(PickingPlugin)

}

init().finally(_testFinish)

+ 38
- 0
examples/simplify-modifier-plugin/index.html Vedi File

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simplify Modifier Plugin</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

<script type="importmap">
{
"imports": {
"three": "./../../dist/index.mjs",
"three/examples/jsm/modifiers/SimplifyModifier.js": "https://cdn.jsdelivr.net/gh/repalash/three.js-modded/examples/jsm/modifiers/SimplifyModifier.js",
"threepipe": "./../../dist/index.mjs",
"@threepipe/plugin-tweakpane": "./../../plugins/tweakpane/dist/index.mjs"
}
}

</script>
<style id="example-style">
html, body, #canvas-container, #mcanvas {
width: 100%;
height: 100%;
margin: 0;
overflow: hidden;
}
</style>
<script type="module" src="../examples-utils/simple-code-preview.mjs"></script>
<script id="example-script" type="module" src="./script.js" data-scripts="./script.ts;./script.js"></script>
</head>
<body>
<div id="canvas-container">
<canvas id="mcanvas"></canvas>
</div>

</body>

+ 63
- 0
examples/simplify-modifier-plugin/script.ts Vedi File

import {
_testFinish,
generateUiFolder,
IGeometry,
IMaterial,
IObject3D,
PickingPlugin,
SimplifyModifierPlugin,
ThreeViewer,
} from 'threepipe'
import {TweakpaneUiPlugin} from '@threepipe/plugin-tweakpane'
import {SimplifyModifier} from 'three/examples/jsm/modifiers/SimplifyModifier.js'
import {createSimpleButtons} from '../examples-utils/simple-bottom-buttons.js'

class SimplifyModifierPluginImpl extends SimplifyModifierPlugin {
protected _simplify(geometry: IGeometry, count: number) {
const res = new SimplifyModifier().modify(geometry, count) as IGeometry
res.computeVertexNormals()
return res
}
uiConfig = generateUiFolder('Simplify Modifier', this)
}
async function init() {

const viewer = new ThreeViewer({
canvas: document.getElementById('mcanvas') as HTMLCanvasElement,
msaa: true,
plugins: [PickingPlugin],
})

const simplify = viewer.addPluginSync(SimplifyModifierPluginImpl)

const ui = viewer.addPluginSync(new TweakpaneUiPlugin(true))

await viewer.setEnvironmentMap('https://threejs.org/examples/textures/equirectangular/venice_sunset_1k.hdr', {
setBackground: true,
})
const result = await viewer.load<IObject3D>('https://threejs.org/examples/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf', {
autoCenter: true,
autoScale: true,
})

const mats: IMaterial[] = []
result?.traverse((obj) => {
obj.materials?.map(m=>{
if (!m) return
m.wireframe = true
mats.push(m)
})
})

createSimpleButtons({
['Simplify']: async(_: HTMLButtonElement) => {
await simplify.simplifyAll(result, {factor: 0.5})
},
})

ui.setupPluginUi(SimplifyModifierPluginImpl)
mats.forEach(m=>ui.appendChild(m.uiConfig, {expanded: false}))

}

init().finally(_testFinish)

+ 8
- 2
examples/tweakpane-editor/script.ts Vedi File

HemisphereLight, HemisphereLight,
KTX2LoadPlugin, KTX2LoadPlugin,
KTXLoadPlugin, KTXLoadPlugin,
MeshOptSimplifyModifierPlugin,
NoiseBumpMaterialPlugin, NoiseBumpMaterialPlugin,
NormalBufferPlugin, NormalBufferPlugin,
Object3DGeneratorPlugin, Object3DGeneratorPlugin,
RenderTargetPreviewPlugin, RenderTargetPreviewPlugin,
Rhino3dmLoadPlugin, Rhino3dmLoadPlugin,
SceneUiConfigPlugin, SceneUiConfigPlugin,
SSAOPlugin,
STLLoadPlugin, STLLoadPlugin,
ThreeFirstPersonControlsPlugin, ThreeFirstPersonControlsPlugin,
ThreeViewer, ThreeViewer,
TonemapPlugin, TonemapPlugin,
TransformControlsPlugin, TransformControlsPlugin,
UnsignedByteType,
USDZLoadPlugin, USDZLoadPlugin,
ViewerUiConfigPlugin, ViewerUiConfigPlugin,
VignettePlugin, VignettePlugin,
new VignettePlugin(false), new VignettePlugin(false),
new ChromaticAberrationPlugin(false), new ChromaticAberrationPlugin(false),
new FilmicGrainPlugin(false), new FilmicGrainPlugin(false),
new SSAOPlugin(UnsignedByteType, 1),
KTX2LoadPlugin, KTX2LoadPlugin,
KTXLoadPlugin, KTXLoadPlugin,
PLYLoadPlugin, PLYLoadPlugin,
DeviceOrientationControlsPlugin, DeviceOrientationControlsPlugin,
PointerLockControlsPlugin, PointerLockControlsPlugin,
ThreeFirstPersonControlsPlugin, ThreeFirstPersonControlsPlugin,
new MeshOptSimplifyModifierPlugin(false), // will auto-initialize on first use.
// new BasicSVGRendererPlugin(false, true),
...extraImportPlugins, ...extraImportPlugins,
]) ])


editor.loadPlugins({ editor.loadPlugins({
['Viewer']: [ViewerUiConfigPlugin, SceneUiConfigPlugin, DropzonePlugin, FullScreenPlugin, TweakpaneUiPlugin], ['Viewer']: [ViewerUiConfigPlugin, SceneUiConfigPlugin, DropzonePlugin, FullScreenPlugin, TweakpaneUiPlugin],
['Scene']: [ContactShadowGroundPlugin], ['Scene']: [ContactShadowGroundPlugin],
['Interaction']: [HierarchyUiPlugin, TransformControlsPlugin, PickingPlugin, Object3DGeneratorPlugin, GeometryGeneratorPlugin, EditorViewWidgetPlugin, Object3DWidgetsPlugin],
['Interaction']: [HierarchyUiPlugin, TransformControlsPlugin, PickingPlugin, Object3DGeneratorPlugin, GeometryGeneratorPlugin, EditorViewWidgetPlugin, Object3DWidgetsPlugin, MeshOptSimplifyModifierPlugin],
['GBuffer']: [GBufferPlugin, DepthBufferPlugin, NormalBufferPlugin], ['GBuffer']: [GBufferPlugin, DepthBufferPlugin, NormalBufferPlugin],
['Post-processing']: [TonemapPlugin, ProgressivePlugin, FrameFadePlugin, VignettePlugin, ChromaticAberrationPlugin, FilmicGrainPlugin],
['Post-processing']: [TonemapPlugin, ProgressivePlugin, SSAOPlugin, FrameFadePlugin, VignettePlugin, ChromaticAberrationPlugin, FilmicGrainPlugin],
['Export']: [CanvasSnapshotPlugin], ['Export']: [CanvasSnapshotPlugin],
['Animation']: [GLTFAnimationPlugin, CameraViewPlugin], ['Animation']: [GLTFAnimationPlugin, CameraViewPlugin],
['Extras']: [HDRiGroundPlugin, Rhino3dmLoadPlugin, ClearcoatTintPlugin, FragmentClippingExtensionPlugin, NoiseBumpMaterialPlugin, CustomBumpMapPlugin, VirtualCamerasPlugin], ['Extras']: [HDRiGroundPlugin, Rhino3dmLoadPlugin, ClearcoatTintPlugin, FragmentClippingExtensionPlugin, NoiseBumpMaterialPlugin, CustomBumpMapPlugin, VirtualCamerasPlugin],

+ 104
- 0
src/plugins/extras/MeshOptSimplifyModifierPlugin.ts Vedi File

import {ThreeViewer} from '../../viewer'
import {BufferAttribute, BufferGeometry} from 'three'
import {IGeometry, iGeometryCommons} from '../../core'
import {toIndexedGeometry} from '../../three'
import {SimplifyModifierPlugin} from './SimplifyModifierPlugin'
import {uiFolderContainer, uiNumber, uiToggle} from 'uiconfig.js'

/**
* Simplify modifier using [meshoptimizer](https://github.com/zeux/meshoptimizer) library.
* Loads the library at runtime from a customisable cdn url.
*/
@uiFolderContainer('Simplify Modifier (meshopt)')
export class MeshOptSimplifyModifierPlugin extends SimplifyModifierPlugin {
public static readonly PluginType = 'MeshOptSimplifyModifierPlugin'

constructor(initialize = true) {
super()
// todo: check if compatible?
if (initialize) this.initialize()
}

get initialized() {
return !!window.MeshoptSimplifier
}

// static SIMPLIFIER_URL = 'https://cdn.jsdelivr.net/gh/zeux/meshoptimizer@master/js/meshopt_simplifier.module.js'
static SIMPLIFIER_URL = 'https://unpkg.com/meshoptimizer@0.20.0/meshopt_simplifier.module.js'

onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
}

protected _initializing?: Promise<void> = undefined

async initialize() {
if (this.initialized) return
if (this._initializing) return await this._initializing
const s = document.createElement('script')
s.type = 'module'
const ev = Math.random().toString(36).substring(7)
s.innerHTML = `
import { MeshoptSimplifier } from '${MeshOptSimplifyModifierPlugin.SIMPLIFIER_URL}';
MeshoptSimplifier.ready.then(() => {
window.MeshoptSimplifier = MeshoptSimplifier;
window.dispatchEvent(new CustomEvent('${ev}'))
});
`
this._initializing = new Promise<void>((res) => {
const l = () => {
window.removeEventListener(ev, l)
res() // todo timeout?
}
window.addEventListener(ev, l)
document.head.appendChild(s) // todo remove later?
// this._script = s
})
}

@uiNumber()
errorThreshold = 0.5
@uiToggle()
lockBorder = false

protected _simplify(geometry: BufferGeometry, count: number): IGeometry {
if (!this.initialized) throw new Error('MeshOptSimplifyModifierPlugin not initialized')
if (!geometry.index) {
geometry = toIndexedGeometry(geometry)
} else {
geometry = geometry.clone()
}
const srcIndexArray = geometry.index!.array
const srcPositionArray = geometry.attributes.position.array
const factor = count / geometry.attributes.position.count
// console.log(factor)
// const targetCount = count * 3
const targetCount = 3 * Math.floor(factor * srcIndexArray.length / 3)
// console.log('srcCount', srcIndexArray.length / 3, 'targetCount', targetCount / 3)
// const errorThresh = 1e-2
const [dstIndexArray, error] = window.MeshoptSimplifier.simplify(
srcIndexArray,
srcPositionArray,
3,
targetCount,
this.errorThreshold,
this.lockBorder ? ['LockBorder'] : [],
)
console.log('srcCount', srcIndexArray.length / 3, 'destCount', dstIndexArray.length / 3)
if (error) {
console.error('Simplify error', error)
// return geometry // todo
}
// (geometry.index!.array as Uint32Array).set(dstIndexArray)
geometry.setIndex(new BufferAttribute(new Uint32Array(dstIndexArray), 1))
// geometry.index!.needsUpdate = true
// geometry.setDrawRange(0, dstIndexArray.length)
return iGeometryCommons.upgradeGeometry.call(geometry.toNonIndexed())
}
}

declare global{
interface Window{
MeshoptSimplifier?: any
}
}

+ 206
- 0
src/plugins/extras/SimplifyModifierPlugin.ts Vedi File

import {AViewerPluginSync, ThreeViewer} from '../../viewer'
import {PickingPlugin} from '../interaction/PickingPlugin'
import {uiButton, uiSlider} from 'uiconfig.js'
import {IGeometry, IObject3D} from '../../core'
import {ValOrArr} from 'ts-browser-helpers'
import {Vector3} from 'three'

export interface SimplifyOptions{
/**
* Number of vertices to remove.
* Factor is not used when count is set.
*/
count?: number
/**
* Factor of vertices to remove. eg 0.5 will remove half of the vertices.
*/
factor?: number
/**
* Replace the geometry with the simplified version in all meshes that use it.
*/
replace?: boolean
/**
* Displace the simplified geometry in the scene. Only used when replace is true
* If set to true, the geometry will be disposed when replaced.
* Default is false.
* This will automatically be done when disposeOnIdle is not false in the geometry.userData.
*/
disposeOnReplace?: boolean
}

/**
* Boilerplate for implementing a plugin for simplifying geometries.
* This is a base class and cannot be used directly.
* See {@link MeshOptSimplifyModifierPlugin} the [simplify-modifier-plugin](https://threepipe.org/examples/#simplify-modifier-plugin) example for a sample implementation.
*/
export abstract class SimplifyModifierPlugin extends AViewerPluginSync<''> {
public static readonly PluginType: string = 'SimplifyModifierPlugin'
enabled = true
toJSON: any = undefined

constructor() {
super()
}

get initialized() { return true }
async initialize() {return}

private _pickingPlugin?: PickingPlugin
onAdded(viewer: ThreeViewer) {
super.onAdded(viewer)
this._pickingPlugin = viewer.getPlugin(PickingPlugin)
}

/**
* Factor of vertices to remove. eg 0.5 will remove half of the vertices.
* Default is 0.5
* This is used when no factor or count is provided in the options to simplifyGeometry or simplifyGeometries.
*/
@uiSlider('Simplify Factor', [0, 1])
simplifyFactor = 0.5

simplifyGeometries(geometry?: ValOrArr<IGeometry>, options?: SimplifyOptions) {
if (!geometry) {
const selected = this._pickingPlugin?.getSelectedObject()
const geom: IGeometry[] = []
selected?.traverse((o) => {
if (o.geometry && !geom.includes(o.geometry)) geom.push(o.geometry)
})
geometry = geom
if (!geometry || !geometry.length) return
}
if (!Array.isArray(geometry)) geometry = [geometry]
const res: IGeometry[] = []
for (const g of geometry) {
res.push(this.simplifyGeometry(g, options)!)
}
return res
}

simplifyGeometry(geometry?: IGeometry, {
factor,
count,
replace = true,
disposeOnReplace = false,
}: SimplifyOptions = {}): IGeometry|undefined {
if (!geometry) {
const selected = this._pickingPlugin?.getSelectedObject()
geometry = selected?.geometry
if (!geometry) return undefined
}
if (!geometry.attributes.position) {
this._viewer?.console.error('SimplifyModifierPlugin: Geometry does not have position attribute', geometry)
return geometry
}
factor = factor || this.simplifyFactor
count = count || geometry.attributes.position.count * factor
if (!geometry.boundingBox) geometry.computeBoundingBox()
const simplified = this._simplify(geometry, count)
simplified.computeBoundingBox()
simplified.computeBoundingSphere()
simplified.computeVertexNormals()
const bbox = simplified.boundingBox
const size = bbox!.getSize(new Vector3())
if (!isFinite(size.x) || !isFinite(size.y) || !isFinite(size.z)) {
this._viewer?.console.error('SimplifyModifierPlugin: Unable to simplify', geometry, simplified, size)
return geometry
}
const oldBB = geometry.boundingBox
const oldSize = oldBB!.getSize(new Vector3())
const diff = size.clone().sub(oldSize)
const diffPerc = diff.clone().divide(oldSize)
if (diffPerc.lengthSq() > 0.001) {
// todo: add option to skip this
console.warn('Simplify', geometry, simplified, bbox, oldBB, size, oldSize, diff, diffPerc)
}
// simplified.setDirty()
if (!replace) return simplified

// not working?
// geometry.copy(simplified)
// geometry.setDirty()
// simplified.dispose()

const meshes = geometry.appliedMeshes
if (!meshes) {
console.error('No meshes found for geometry, cannot replace', geometry)
return simplified
}
for (const mesh of meshes) {
mesh.geometry = simplified
}
if (disposeOnReplace) {
geometry.dispose(true)
}
return simplified
}

/**
* Sample for three.js addons SimplifyModifier:
* `
* import {SimplifyModifier} from 'three/examples/jsm/modifiers/SimplifyModifier'
* protected _simplify(geometry: IGeometry, count: number): IGeometry {
* const modifier = new SimplifyModifier()
* return modifier.modify(geometry, count) as IGeometry
* }
* `
* @param geometry
* @param count
*/
protected abstract _simplify(geometry: IGeometry, count: number): IGeometry

@uiButton('Simplify All')
async simplifyAll(root?: IObject3D, options?: SimplifyOptions) {
if (!root && this._viewer) root = this._viewer.scene.modelRoot
if (!root) {
console.error('SimplifyModifierPlugin: No root found')
return
}
if (!this.initialized) {
await this.initialize()
if (!this.initialized) {
this._viewer?.console.error('SimplifyModifierPlugin cannot be initialized')
return
}
}
const geometries: IGeometry[] = []
root.traverse((o) => {
if (o.geometry && !geometries.includes(o.geometry)) geometries.push(o.geometry)
})
if (!geometries.length) {
console.error('SimplifyModifierPlugin: No geometries found')
return
}
return this.simplifyGeometries(geometries, options)
}

@uiButton('Simplify Selected')
async simplifySelected() {
if (!this._viewer) return
if (!this.initialized) {
await this.initialize()
if (!this.initialized) {
await this._viewer.dialog.alert('SimplifyModifierPlugin cannot be initialized')
return
}
}
const selected = this._pickingPlugin?.getSelectedObject()
if (!selected) {
await this._viewer.dialog.alert('Nothing Selected')
return
}
let doAll = false
if (!selected.geometry) doAll = true
else if (selected.children.length === 0) doAll = true
if (!doAll) {
const resp = await this._viewer.dialog.confirm('Simplify all in hierarchy?')
if (resp) doAll = true
}
if (doAll) {
this.simplifyGeometries()
} else {
this.simplifyGeometry(selected.geometry)
}
}

}

+ 2
- 0
src/plugins/index.ts Vedi File

export {Object3DWidgetsPlugin} from './extras/Object3DWidgetsPlugin' export {Object3DWidgetsPlugin} from './extras/Object3DWidgetsPlugin'
export {Object3DGeneratorPlugin} from './extras/Object3DGeneratorPlugin' export {Object3DGeneratorPlugin} from './extras/Object3DGeneratorPlugin'
export {ContactShadowGroundPlugin} from './extras/ContactShadowGroundPlugin' export {ContactShadowGroundPlugin} from './extras/ContactShadowGroundPlugin'
export {SimplifyModifierPlugin} from './extras/SimplifyModifierPlugin'
export {MeshOptSimplifyModifierPlugin} from './extras/MeshOptSimplifyModifierPlugin'

Loading…
Annulla
Salva