diff --git a/js/texturing/layers.js b/js/texturing/layers.js index e0395f02..03c5b753 100644 --- a/js/texturing/layers.js +++ b/js/texturing/layers.js @@ -58,8 +58,9 @@ class TextureLayer { if (undo) { Undo.initEdit({textures: [this.texture], bitmap: true}); } - this.texture.layers.remove(this); - if (this.texture.selected_layer == this) this.texture.selected_layer = null; + let index = this.texture.layers.indexOf(this); + this.texture.layers.splice(index, 1); + if (this.texture.selected_layer == this) this.texture.selected_layer = this.texture.layers[index-1] || this.texture.layers[index]; if (undo) { this.texture.updateLayerChanges(true); Undo.finishEdit('Remove layer'); diff --git a/js/texturing/painter.js b/js/texturing/painter.js index 8343e77a..ad87813f 100644 --- a/js/texturing/painter.js +++ b/js/texturing/painter.js @@ -14,25 +14,18 @@ const Painter = { if (texture.mode === 'link') { texture.convertToInternal(); } - if (!Painter.current.cached_canvases) Painter.current.cached_canvases = {}; let edit_name = options.no_undo ? null : (options.edit_name || 'Edit texture'); let {canvas, ctx} = texture.getActiveCanvas(); Painter.current.ctx = ctx; + if (!Painter.current.textures) Painter.current.textures = []; + Painter.current.textures.safePush(texture); + Painter.current.texture = texture; - if (options.use_cache && - Painter.current.cached_canvases[texture.uuid] - ) { - //IS CACHED - callback(canvas); - if (options.no_update === true) { - return; - } - } else { - //IS UNCACHED - Painter.current.texture = texture - Painter.current.cached_canvases[texture.uuid] = canvas; - callback(canvas); + callback(canvas); + + if (options.use_cache && options.no_update === true) { + return; } if (options.no_undo && options.use_cache) { @@ -42,8 +35,7 @@ const Painter = { texture.display_canvas = true; UVEditor.vue.updateTextureCanvas(); } else { - texture.updateLayerChanges(true); - texture.updateSource(canvas.toDataURL()); + texture.updateChangesAfterEdit(); if (!options.no_undo && !options.no_undo_finish) { Undo.finishEdit(edit_name) } @@ -271,7 +263,9 @@ const Painter = { if (result == false) return; } if (Painter.brushChanges) { - texture.updateLayerChanges(true); + Painter.current.textures.forEach(texture => { + texture.updateChangesAfterEdit(); + }) Undo.finishEdit('Paint texture'); Painter.brushChanges = false; } @@ -280,7 +274,8 @@ const Painter = { } delete Painter.current.alpha_matrix; delete Painter.editing_area; - delete Painter.current.cached_canvases; + delete Painter.texture; + delete Painter.textures; Painter.painting = false; Painter.currentPixel = [-1, -1]; }, @@ -421,10 +416,10 @@ const Painter = { tool.brush.draw({ctx, x, y, size, softness, texture, event}); } else { + let face_matrix = settings.paint_side_restrict.value && Painter.current.face_matrices[matrix_id]; let run_per_pixel = (pxcolor, local_opacity, px, py) => { - if (Painter.current.face_matrices[matrix_id] && settings.paint_side_restrict.value) { - let matrix = Painter.current.face_matrices[matrix_id]; - if (!matrix[px] || !matrix[px][py % texture.display_height]) { + if (face_matrix) { + if (!face_matrix[px] || !face_matrix[px][py % texture.display_height]) { return pxcolor; } } @@ -1060,7 +1055,6 @@ const Painter = { texture.selection.maskCanvas(ctx); let rect = texture.selection.getBoundingRect(true); ctx.rect(rect.start_x, rect.start_y, rect.width, rect.height); - console.log(rect) } ctx.fillStyle = gradient; ctx.fill(); @@ -1744,6 +1738,13 @@ class IntMatrix { } return rect; } + hasSelection() { + if (this.is_custom) { + return this.array.findIndex(v => v) != -1; + } else { + return this.override; + } + } /** * Set the value at a specified pixel * @param {number} x @@ -1764,8 +1765,7 @@ class IntMatrix { * If there was a selection, whether override or not, clear it */ clear() { - if (this.override == true) this.override = false; - if (this.array) this.array.fill(0); + this.setOverride(false); } /** * Change override mode @@ -2423,7 +2423,7 @@ BARS.defineActions(function() { }, onSelect() { let texture = Texture.selected; - if (texture && texture.selection.is_custom && (!texture.selected_layer || !texture.selected_layer.in_limbo)) { + if (texture && texture.selection.is_custom && texture.selection.hasSelection() && (!texture.selected_layer || !texture.selected_layer.in_limbo)) { Texture.selected.selectionToLayer(); } } @@ -2718,7 +2718,7 @@ BARS.defineActions(function() { tool_setting: 'brush_size', category: 'paint', settings: { - min: 1, max: 50, interval: 1, default: 1, + min: 1, max: 1024, interval: 1, default: 1, } }) new NumSlider('slider_brush_softness', { diff --git a/js/texturing/textures.js b/js/texturing/textures.js index 3f90ffe9..1abfb30c 100644 --- a/js/texturing/textures.js +++ b/js/texturing/textures.js @@ -319,9 +319,6 @@ class Texture { } getUndoCopy(bitmap) { var copy = {}; - if (this.display_canvas && bitmap) { - this.updateSource(this.canvas.toDataURL()); - } for (var key in Texture.properties) { Texture.properties[key].copy(this, copy) } @@ -341,7 +338,7 @@ class Texture { } if (bitmap || this.internal) { copy.source = this.source - if (!this.internal) { + if (!this.layers_enabled) { copy.image_data = this.getDataURL(); } } @@ -349,9 +346,6 @@ class Texture { } getSaveCopy(bitmap) { var copy = {}; - if (this.display_canvas && bitmap) { - this.updateSource(this.canvas.toDataURL()); - } for (var key in Texture.properties) { Texture.properties[key].copy(this, copy) } @@ -1627,6 +1621,14 @@ class Texture { this.updateImageFromCanvas(); } } + updateChangesAfterEdit() { + if (this.layers_enabled) { + return this.updateLayerChanges(true); + } + this.getMaterial().map.needsUpdate = true; + this.source = this.canvas.toDataURL(); + this.updateImageFromCanvas(); + } updateImageFromCanvas() { this.img.update_from_canvas = true; this.img.src = this.source; diff --git a/js/texturing/uv.js b/js/texturing/uv.js index 2f842bd5..89d773b8 100644 --- a/js/texturing/uv.js +++ b/js/texturing/uv.js @@ -2198,6 +2198,7 @@ Interface.definePanels(function() { if (this.$refs.viewport && this.zoom == 1 && ((!this.$refs.viewport.scrollLeft && !this.$refs.viewport.scrollTop) || this.centered_view)) { this.centerView(); } + this.updateCanvasImageRendering(); UVEditor.updateSelectionOutline(false); }, centerView() { @@ -2268,6 +2269,13 @@ Interface.definePanels(function() { (Toolbox.selected.id == 'selection_tool' && this.texture && this.texture.selection.get(this.mouse_coords.x, this.mouse_coords.y) && BarItems.selection_tool_operation_mode.value == 'create'); this.$refs.frame.style.cursor = grab ? 'move' : ''; }, + updateCanvasImageRendering() { + if (this.texture && this.texture.display_canvas) { + let wrapper = this.$refs.texture_canvas_wrapper; + if (!wrapper) return; + this.texture.canvas.style.imageRendering = this.texture.width < this.inner_width ? 'inherit' : 'auto'; + } + }, onMouseWheel(event) { if (event.ctrlOrCmd) { @@ -2301,6 +2309,8 @@ Interface.definePanels(function() { if (this.zoom == 1 && Panels.uv.isInSidebar() && diagonal_offset/UVEditor.width < 0.12) { this.centerView(); } + + this.updateCanvasImageRendering(); if (this.mode == 'paint') { this.mouse_coords.active = false; @@ -3413,7 +3423,7 @@ Interface.definePanels(function() { texture.display_canvas = true; UVEditor.vue.updateTextureCanvas(); } - if (!layer.in_limbo && texture.selection.is_custom) { + if (!layer.in_limbo && texture.selection.is_custom && texture.selection.hasSelection()) { texture.selectionToLayer(); layer = texture.selected_layer; initial_offset = layer.offset.slice(); @@ -3429,12 +3439,13 @@ Interface.definePanels(function() { selection_rect.active = false; if (create_selection) { - if (!calcrect) { - texture.selection.clear(); - UVEditor.updateSelectionOutline(); + if (!calcrect || selection_rect.width == 0 || selection_rect.height == 0) { + if (!texture.selection.hasSelection()) { + texture.selection.clear(); + UVEditor.updateSelectionOutline(); + } return; } - if (selection_rect.width == 0 || selection_rect.height == 0) return; if (op_mode == 'create') { texture.selection.clear(); @@ -3499,6 +3510,9 @@ Interface.definePanels(function() { } } } + if (!texture.selection.hasSelection()) { + texture.selection.clear(); + } UVEditor.updateSelectionOutline(); } else { texture.updateLayerChanges(true); diff --git a/js/undo.js b/js/undo.js index cbd9240c..86061361 100644 --- a/js/undo.js +++ b/js/undo.js @@ -359,7 +359,8 @@ class UndoSystem { } } } - Canvas.updateAllFaces() + Canvas.updateAllFaces(); + updateInterfacePanels(); } if (save.layers) { @@ -659,11 +660,13 @@ UndoSystem.save = class { addTextureOrLayer(texture) { if (texture.layers_enabled && texture.layers[0]) { let layer = texture.getActiveLayer(); + if (!this.aspects.layers) this.aspects.layers = []; if (this.aspects.layers.safePush(layer)) { if (!this.layers) this.layers = {}; this.layers[layer.uuid] = layer.getUndoCopy(this.aspects.bitmap); } } else { + if (!this.aspects.textures) this.aspects.textures = []; if (this.aspects.textures.safePush(texture)) { if (!this.textures) this.textures = {}; this.textures[texture.uuid] = texture.getUndoCopy(this.aspects.bitmap)