threepipe
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

MaterialConfiguratorPlugin.ts 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {CustomContextMenu, MaterialConfiguratorBasePlugin, MaterialVariations} from 'threepipe'
  2. import {GridItemListPlugin} from './GridItemListPlugin'
  3. /**
  4. * Material Configurator Plugin (Basic UI)
  5. * This plugin allows you to create variations of materials mapped to material names or uuids in the scene.
  6. * These variations can be applied to the materials in the scene. (This copies the properties to the same material instances instead of assigning new materials)
  7. * The plugin interfaces with the picking plugin and also provides uiConfig to show and edit the variations.
  8. * This functionality is inherited from `MaterialConfiguratorBasePlugin`
  9. *
  10. * Additionally this plugin adds a Grid UI using {@link GridItemListPlugin} in the DOM over the viewer canvas to show various material variations and allow the user to apply them.
  11. * The UI can also be used in the editor to edit the variations and apply them.
  12. */
  13. export class MaterialConfiguratorPlugin extends MaterialConfiguratorBasePlugin {
  14. public static PluginType = 'MaterialConfiguratorPlugin'
  15. enableEditContextMenus = false
  16. dependencies = [GridItemListPlugin]
  17. // must be called from preFrame
  18. protected async _refreshUi(): Promise<boolean> {
  19. if (!await super._refreshUi()) return false
  20. const grid = this._viewer?.getPlugin(GridItemListPlugin)
  21. if (!grid) return false
  22. grid.removeAll(MaterialConfiguratorPlugin.PluginType)
  23. for (const variation of this.variations) {
  24. const container = grid.create(MaterialConfiguratorPlugin.PluginType,
  25. variation.title + (this.enableEditContextMenus ? ' (' + variation.uuid + ')' : ''),
  26. 5,
  27. 20, 0,
  28. variation.materials.map(m => {
  29. const image = this.getPreview(m, variation.preview)
  30. return {
  31. id: m.uuid,
  32. image, // : (m as any).map?.image ? imageBitmapToBase64((m as any).map.image, 100) : makeColorSvg((m as any).color ?? '#ffffff'),
  33. onClick: (id:string) => this.applyVariation(variation, id),
  34. tooltip: m.name || m.uuid,
  35. }
  36. }), (d, item)=> {
  37. // todo test in shadow dom.
  38. d.oncontextmenu = (e) => {
  39. if (!this.enableEditContextMenus) return
  40. e.preventDefault()
  41. e.stopPropagation()
  42. const menu = CustomContextMenu.Create(this.materialContextMenuItems(variation, item.id), e.clientX, e.clientY)
  43. document.body.appendChild(menu)
  44. }
  45. })
  46. container.oncontextmenu = (e) => {
  47. if (!this.enableEditContextMenus) return
  48. e.preventDefault()
  49. e.stopPropagation()
  50. const menu = CustomContextMenu.Create(this.variationsContextMenuItems(variation), e.clientX, e.clientY)
  51. document.body.appendChild(menu)
  52. }
  53. }
  54. grid.rebuildUi()
  55. return true
  56. }
  57. materialContextMenuItems = (variation: MaterialVariations, uuid: string)=>({
  58. ['Remove']: async()=>{
  59. const conf = await this._viewer?.dialog.confirm('Remove material: Remove material from this variation list?')
  60. if (!conf) return
  61. variation.materials = variation.materials.filter(m => m.uuid !== uuid)
  62. this.refreshUi()
  63. CustomContextMenu.Remove()
  64. },
  65. // todo set icon url
  66. })
  67. variationsContextMenuItems = (variation: MaterialVariations)=>({
  68. ['Rename mapping']: async() => {
  69. const name = await this._viewer?.dialog.prompt('Change name: New material name to map to', variation.uuid, true)
  70. if (name) {
  71. variation.uuid = name
  72. this.refreshUi()
  73. }
  74. },
  75. ['Rename title']: async() => {
  76. const name = await this._viewer?.dialog.prompt('Change name: New material name to map to', variation.title, true)
  77. if (name) {
  78. variation.title = name
  79. this.refreshUi()
  80. }
  81. },
  82. ['Clear Materials']: async()=>{
  83. const conf = await this._viewer?.dialog.confirm('Remove all: Remove all materials from this variation list?')
  84. if (!conf) return
  85. variation.materials = []
  86. this.refreshUi()
  87. CustomContextMenu.Remove()
  88. },
  89. ['Remove Section']: async()=>{
  90. const conf = await this._viewer?.dialog.confirm('Remove variations: Remove this category of variations?')
  91. if (!conf) return
  92. this.removeVariation(variation)
  93. CustomContextMenu.Remove()
  94. },
  95. })
  96. }