Add UV overlay in Paint mode

Improve project closing time
Fix Box UV not resetting face rotations
This commit is contained in:
JannisX11 2021-11-23 23:46:57 +01:00
parent 8beef0e1f0
commit 1b529c1b08
6 changed files with 59 additions and 26 deletions

View File

@ -1136,11 +1136,26 @@
border: 4px solid var(--color-ui);
box-shadow: 0 0 0 800px var(--color-back);
box-sizing: content-box;
--color-unselected: var(--color-grid);
--color-uv-unselected: var(--color-grid);
--color-uv-selected: white;
--color-uv-hover: var(--color-accent);
--color-uv-background: rgba(50, 70, 240, 0.14);
--color-uv-background-hover: rgba(50, 70, 240, 0.3);
--uv-line-width: 2px;
}
#uv_frame .selection_rectangle {
z-index: 8;
}
#uv_frame.overlay_mode {
--color-uv-unselected: var(--color-grid);
--color-uv-selected: var(--color-grid);
--color-uv-hover: var(--color-grid);
--color-uv-background: transparent;
--uv-line-width: 1px;
}
#uv_frame.overlay_mode * {
pointer-events: none;
}
body[mode=paint] #uv_frame {
cursor: crosshair !important;
@ -1175,14 +1190,14 @@
position: absolute;
z-index: 2;
cursor: move;
border: 2px solid var(--color-accent);
border: var(--uv-line-width) solid var(--color-accent);
box-sizing: border-box;
}
.cube_box_uv > div.uv_fill {
background-color: rgba(50, 70, 240, 0.14);
background-color: var(--color-uv-background);
}
.cube_box_uv:hover > div {
border-color: white;
border-color: var(--color-uv-selected);
z-index: 3;
}
.cube_uv_face {
@ -1191,19 +1206,19 @@
width: var(--width);
height: var(--height);
cursor: move;
border: 2px solid var(--color-text);
border: var(--uv-line-width) solid var(--color-text);
box-sizing: border-box;
background-color: rgba(50, 70, 240, 0.14);
background-color: var(--color-uv-background);
text-align: center;
color: var(--color-subtle_text);
}
.cube_uv_face:hover {
border-color: white;
background-color: rgba(50, 70, 240, 0.3);
border-color: var(--color-uv-hover);
background-color: var(--color-uv-background-hover);
z-index: 3;
}
.cube_uv_face.selected:not(.unselected) {
border-color: white;
border-color: var(--color-uv-hover);
z-index: 4;
box-shadow: 0 0 4px #000000cc;
}
@ -1214,7 +1229,7 @@
}
.cube_uv_face.unselected div,
.cube_box_uv.unselected div {
border-color: var(--color-unselected) !important;
border-color: var(--color-uv-unselected) !important;
}
.uv_resize_side {
@ -1268,15 +1283,16 @@
}
.mesh_uv_face polygon {
pointer-events: initial;
fill: rgba(50, 70, 240, 0.3);
stroke: var(--color-text);
stroke-width: 2px;
fill: var(--color-uv-background);
stroke: var(--color-uv-unselected);
stroke-width: var(--uv-line-width);
}
.mesh_uv_face:hover polygon {
stroke: white;
stroke: var(--color-uv-hover);
fill: var(--color-uv-background-hover);
}
.mesh_uv_face.selected polygon {
stroke: var(--color-accent);
stroke: var(--color-uv-selected);
}
.uv_mesh_vertex {
position: absolute;

View File

@ -363,6 +363,7 @@ window.onbeforeunload = function (event) {
} else {
setTimeout(async function() {
let projects = ModelProject.all.slice();
if (projects[0]) await projects[0].select();
for (let project of projects) {
let closed = await project.close();
if (!closed) return false;

View File

@ -206,8 +206,8 @@ class ModelProject {
})
return true;
}
unselect() {
this.thumbnail = Preview.selected.canvas.toDataURL();
unselect(closing) {
if (!closing) this.thumbnail = Preview.selected.canvas.toDataURL();
Interface.tab_bar.last_opened_project = this.uuid;
if (Format && typeof Format.onDeactivation == 'function') {
@ -277,7 +277,7 @@ class ModelProject {
Blockbench.dispatchEvent('close_project');
this.unselect();
this.unselect(true);
Texture.all.forEach(tex => tex.stopWatcher());
let index = ModelProject.all.indexOf(this);

View File

@ -11,6 +11,12 @@ function switchBoxUV(state) {
}
cube.uv_offset[1] = cube.faces.up.uv[3];
})
} else {
Cube.all.forEach(cube => {
for (let fkey in cube.faces) {
cube.faces[fkey].rotation = 0;
}
})
}
UVEditor.vue.box_uv = state;
UVEditor.setGrid(1);
@ -1243,6 +1249,7 @@ const UVEditor = {
}},
'focus_on_selection',
'uv_checkerboard',
'paint_mode_uv_overlay',
'_',
'copy',
'paste',
@ -1609,6 +1616,14 @@ BARS.defineActions(function() {
Undo.finishEdit('Set automatic cullface')
}
})
new Toggle('paint_mode_uv_overlay', {
icon: 'splitscreen',
category: 'animation',
condition: {modes: ['paint']},
onChange(value) {
UVEditor.vue.uv_overlay = value;
}
})
})
Interface.definePanels(function() {
@ -1637,6 +1652,7 @@ Interface.definePanels(function() {
height: 320,
zoom: 1,
checkerboard: settings.uv_checkerboard.value,
uv_overlay: false,
texture: 0,
mouse_coords: {x: -1, y: -1},
helper_lines: {x: -1, y: -1},
@ -1647,9 +1663,7 @@ Interface.definePanels(function() {
height: 0,
active: false
},
copy_overlay: {
},
copy_overlay: {},
project_resolution: [16, 16],
elements: [],
@ -2442,9 +2456,9 @@ Interface.definePanels(function() {
:style="{width: (width+8) + 'px', height: (height+8) + 'px', overflowX: (zoom > 1) ? 'scroll' : 'hidden', overflowY: (inner_height > height) ? 'scroll' : 'hidden'}"
>
<div id="uv_frame" @click.stop="reverseSelect($event)" ref="frame" :style="{width: inner_width + 'px', height: inner_height + 'px'}" v-if="texture !== null">
<div id="uv_frame" @click.stop="reverseSelect($event)" ref="frame" :class="{overlay_mode: uv_overlay && mode == 'paint'}" :style="{width: inner_width + 'px', height: inner_height + 'px'}" v-if="texture !== null">
<template v-if="mode == 'uv'" v-for="element in (display_uv === 'all_elements' ? all_mappable_elements : mappable_elements)">
<template id="uv_allocations" v-if="mode == 'uv' || uv_overlay" v-for="element in (display_uv === 'all_elements' ? all_mappable_elements : mappable_elements)">
<template v-if="element.type == 'cube' && !box_uv">
<div class="cube_uv_face"
@ -2462,7 +2476,7 @@ Interface.definePanels(function() {
'--height': toPixels(Math.abs(face.uv_size[1]), 2),
}"
>
<template v-if="selected_faces.includes(key) && !(display_uv === 'all_elements' && !mappable_elements.includes(element))">
<template v-if="selected_faces.includes(key) && mode == 'uv' && !(display_uv === 'all_elements' && !mappable_elements.includes(element))">
{{ face_names[key] || '' }}
<div class="uv_resize_side horizontal" @mousedown="resizeFace(key, $event, 0, -1)" @touchstart.prevent="resizeFace(key, $event, 0, -1)" style="width: var(--width)"></div>
<div class="uv_resize_side horizontal" @mousedown="resizeFace(key, $event, 0, 1)" @touchstart.prevent="resizeFace(key, $event, 0, 1)" style="top: var(--height); width: var(--width)"></div>
@ -2515,7 +2529,7 @@ Interface.definePanels(function() {
<svg>
<polygon :points="getMeshFaceOutline(face)" />
</svg>
<template v-if="selected_faces.includes(key)">
<template v-if="selected_faces.includes(key) && mode == 'uv'">
<div class="uv_mesh_vertex" v-for="(key, index) in face.vertices"
:class="{main_corner: index == 0, selected: selected_vertices[element.uuid] && selected_vertices[element.uuid].includes(key)}"
@mousedown.prevent.stop="dragVertices(element, key, $event)" @touchstart.prevent.stop="dragVertices(element, key, $event)"

File diff suppressed because one or more lines are too long

View File

@ -1191,6 +1191,8 @@
"action.slider_face_tint.desc": "Set the tint index of the current face. -1 means unset.",
"action.snap_uv_to_pixels": "Snap UV to Pixels",
"action.snap_uv_to_pixels.desc": "Snaps the selected UV vertices to the pixel grid",
"action.paint_mode_uv_overlay": "UV Overlay",
"action.paint_mode_uv_overlay.desc": "Display the UV map as an overlay in paint mode",
"action.remove_blank_faces": "Remove Blank Faces",
"action.remove_blank_faces.desc": "Deletes all untextured faces of the selection",