Implement per element selection system in UV editor

Fixes #2167
This commit is contained in:
JannisX11 2024-03-22 19:53:56 +01:00
parent 7b9f07e740
commit 1deccb8967
10 changed files with 273 additions and 224 deletions

View File

@ -152,7 +152,6 @@ var codec = new Codec('project', {
selected_elements: Project.selected_elements.map(e => e.uuid),
selected_group: Project.selected_group?.uuid,
mesh_selection: JSON.parse(JSON.stringify(Project.mesh_selection)),
selected_faces: Project.selected_faces,
selected_texture: Project.selected_texture?.uuid,
};
}
@ -437,10 +436,6 @@ var codec = new Codec('project', {
Project.selected_elements.push(el);
})
Group.selected = (state.selected_group && Group.all.find(g => g.uuid == state.selected_group));
for (let key in state.selected_vertices) {
Project.mesh_selection[key] = state.mesh_selection[key];
}
Project.selected_faces.replace(state.selected_faces);
(state.selected_texture && Texture.all.find(t => t.uuid == state.selected_texture))?.select();
Project.loadEditorState();

View File

@ -57,7 +57,6 @@ class ModelProject {
this.selected_elements = [];
this.selected_group = null;
this.mesh_selection = {};
this.selected_faces = [];
this.textures = [];
this.selected_texture = null;
this.outliner = [];
@ -202,15 +201,10 @@ class ModelProject {
UVEditor.vue.elements = this.selected_elements;
UVEditor.vue.all_elements = this.elements;
UVEditor.vue.selected_vertices = {};
UVEditor.vue.selected_faces = this.selected_faces;
UVEditor.vue.box_uv = this.box_uv;
UVEditor.vue.display_uv = this.display_uv;
BarItems.edit_mode_uv_overlay.value = this.display_uv == 'all_elements';
BarItems.edit_mode_uv_overlay.updateEnabledState();
for (let uuid in this.mesh_selection) {
UVEditor.vue.selected_vertices[uuid] = this.mesh_selection[uuid].vertices;
}
Panels.textures.inside_vue.textures = Texture.all;
Panels.layers.inside_vue.layers = Texture.selected ? Texture.selected.layers : [];
@ -586,11 +580,6 @@ function selectNoProject() {
UVEditor.vue.elements = [];
UVEditor.vue.all_elements = [];
UVEditor.vue.selected_vertices = {};
UVEditor.vue.selected_faces = [];
for (let uuid in UVEditor.vue.selected_vertices) {
delete UVEditor.vue.selected_vertices[uuid];
}
Interface.Panels.textures.inside_vue.textures = [];

View File

@ -107,6 +107,9 @@ function updateSelection(options = {}) {
obj.selectLow()
} else if ((!included || obj.locked) && obj.selected) {
obj.unselect()
if (UVEditor.selected_element_faces[obj.uuid]) {
delete UVEditor.selected_element_faces[obj.uuid];
}
}
if (obj instanceof Mesh && Project.mesh_selection[obj.uuid]) {
if (!included) {
@ -160,13 +163,6 @@ function updateSelection(options = {}) {
UVEditor.vue.mode = 'uv';
}
}
if (Outliner.selected.length || (Format.single_texture && Modes.paint)) {
UVEditor.selected_faces.forEachReverse((fkey, i) => {
if (!UVEditor.getMappableElements().find(el => el.faces[fkey])) {
UVEditor.selected_faces.splice(i, 1);
}
})
}
if (Condition(Panels.uv.condition)) {
UVEditor.loadData();
}

View File

@ -229,6 +229,7 @@ async function autoFixMeshEdit() {
let meshes = Mesh.selected.filter(m => concave_faces[m.uuid]);
Undo.initEdit({ elements: meshes });
for (let mesh of meshes) {
let selected_faces = mesh.getSelectedFaces(true);
for (let [fkey, concave_vkey] of concave_faces[mesh.uuid]) {
let face = mesh.faces[fkey];
@ -263,7 +264,7 @@ async function autoFixMeshEdit() {
delete face.uv[off_corners[1]];
let [face_key] = mesh.addFaces(new_face);
UVEditor.selected_faces.push(face_key);
selected_faces.safePush(face_key);
if (face.getAngleTo(new_face) > 90) {
new_face.invert();
}
@ -837,7 +838,6 @@ BARS.defineActions(function() {
if (Group.selected) Group.selected.unselect()
mesh.select()
UVEditor.setAutoSize(null, true, Object.keys(mesh.faces));
UVEditor.selected_faces.empty();
Undo.finishEdit('Add primitive');
Blockbench.dispatchEvent( 'add_mesh', {object: mesh} )
@ -889,12 +889,13 @@ BARS.defineActions(function() {
delete Project.mesh_selection[mesh.uuid];
})
} else if (value === 'face') {
UVEditor.vue.selected_faces.empty();
Mesh.selected.forEach(mesh => {
let selected_faces = mesh.getSelectedFaces(true);
selected_faces.empty();
for (let fkey in mesh.faces) {
let face = mesh.faces[fkey];
if (face.isSelected(fkey)) {
UVEditor.vue.selected_faces.safePush(fkey);
selected_faces.safePush(fkey);
}
}
})
@ -906,7 +907,6 @@ BARS.defineActions(function() {
for (let fkey in mesh.faces) {
let face = mesh.faces[fkey];
if (face.vertices.allAre(vkey => vertices.includes(vkey))) {
UVEditor.vue.selected_faces.safePush(fkey);
faces.safePush(fkey);
}
}
@ -1033,8 +1033,9 @@ BARS.defineActions(function() {
Undo.initEdit({elements: Mesh.selected});
let faces_to_autouv = [];
Mesh.selected.forEach(mesh => {
UVEditor.selected_faces.empty();
let selected_vertices = mesh.getSelectedVertices();
let selected_faces = mesh.getSelectedFaces(true);
selected_faces.empty();
if (selected_vertices.length >= 2 && selected_vertices.length <= 4) {
let reference_face;
let reference_face_strength = 0;
@ -1075,7 +1076,7 @@ BARS.defineActions(function() {
delete reference_face.uv[reference_corner_vertex];
let [face_key] = mesh.addFaces(new_face);
UVEditor.selected_faces.push(face_key);
selected_faces.push(face_key);
if (reference_face.getAngleTo(new_face) > 90) {
@ -1090,7 +1091,7 @@ BARS.defineActions(function() {
texture: reference_face?.texture,
} );
let [face_key] = mesh.addFaces(new_face);
UVEditor.selected_faces.push(face_key);
selected_faces.push(face_key);
faces_to_autouv.push(face_key);
// Correct direction
@ -1174,7 +1175,7 @@ BARS.defineActions(function() {
vertices.push(face_vertices[0]);
let new_face = new MeshFace(mesh, {vertices: face_vertices, texture: reference_face.texture});
let [face_key] = mesh.addFaces(new_face);
UVEditor.selected_faces.push(face_key);
selected_faces.push(face_key);
if (face_vertices.length < 4) break;
start_index += 3;

View File

@ -815,7 +815,7 @@ class Mesh extends OutlinerElement {
if (faces === true) {
var sides = Object.keys(this.faces);
} else if (faces === undefined) {
var sides = UVEditor.vue.selected_faces
var sides = this.getSelectedFaces()
} else {
var sides = faces
}

View File

@ -425,7 +425,7 @@ class OutlinerElement extends OutlinerNode {
Blockbench.showQuickMessage('message.group_required_to_animate');
return false;
}
//Shiftv
//Shift
var just_selected = []
if (event && (event.shiftKey === true || Pressing.overrides.shift) && this.getParentArray().includes(selected[selected.length-1]) && !Modes.paint && isOutlinerClick) {
var starting_point;

View File

@ -762,11 +762,12 @@ class Preview {
}
if (Toolbox.selected.selectElements && Modes.selected.selectElements && data.type === 'element') {
if (Toolbox.selected.selectFace && data.face) {
if (data.element instanceof Mesh && select_mode == 'face' && (event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift)) {
UVEditor.vue.selected_faces.safePush(data.face)
if (Toolbox.selected.selectFace && data.face && data.element.type != 'mesh') {
let face_selection = UVEditor.getSelectedFaces(data.element, true);
if (event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift) {
face_selection.safePush(data.face);
} else {
UVEditor.setFace(data.face, false);
face_selection.replace([data.face]);
}
}
Blockbench.dispatchEvent('canvas_select', data)
@ -828,13 +829,11 @@ class Preview {
selected_vertices.empty();
selected_edges.empty();
selected_faces.empty();
UVEditor.vue.selected_faces.empty();
}
processed_faces.forEach(face => {
selected_vertices.safePush(...face.vertices);
let fkey = face.getFaceKey();
UVEditor.vue.selected_faces.push(fkey);
selected_faces.push(fkey);
});
} else {
@ -850,17 +849,14 @@ class Preview {
})
if (vkeys_to_remove.length == 0) vkeys_to_remove.push(face_vkeys[0]);
selected_vertices.remove(...vkeys_to_remove);
UVEditor.vue.selected_faces.remove(data.face);
selected_faces.remove(data.face);
} else {
selected_vertices.safePush(...face_vkeys);
UVEditor.vue.selected_faces.safePush(data.face);
selected_faces.safePush(data.face);
}
} else {
selected_edges.empty();
selected_vertices.replace(face_vkeys);
UVEditor.vue.selected_faces.replace([data.face]);
selected_faces.replace([data.face]);
}
}
@ -881,7 +877,6 @@ class Preview {
selected_vertices.empty();
selected_edges.empty();
selected_faces.empty();
UVEditor.vue.selected_faces.empty();
}
let start_face = mesh.faces[data.face];
@ -890,7 +885,6 @@ class Preview {
if (selected_faces.includes(fkey)) return;
selected_faces.push(fkey);
UVEditor.vue.selected_faces.push(fkey);
selected_vertices.safePush(...face.vertices);
for (let fkey2 in mesh.faces) {
@ -1321,7 +1315,6 @@ class Preview {
} else {
if (selection_mode != 'object' && !extend_selection) {
mesh_selection.faces.empty();
UVEditor.vue.selected_faces.empty();
}
for (let fkey in element.faces) {
let face = element.faces[fkey];
@ -1346,7 +1339,6 @@ class Preview {
if (face_intersects) {
mesh_selection.vertices.safePush(...face.vertices);
mesh_selection.faces.safePush(fkey);
UVEditor.vue.selected_faces.safePush(fkey);
}
}
}

View File

@ -1003,10 +1003,11 @@ class Texture {
var scope = this;
Undo.initEdit({elements: affected})
affected.forEach(function(obj) {
for (var face in obj.faces) {
if (all || obj.box_uv || UVEditor.vue.selected_faces.includes(face)) {
var f = obj.faces[face]
affected.forEach((element) => {
let selected_faces = UVEditor.getSelectedFaces(element);
for (var face in element.faces) {
if (all || element.box_uv || selected_faces.includes(face)) {
var f = element.faces[face]
if (all !== 'blank' || (f.texture !== null && !f.getTexture())) {
f.texture = scope.uuid
}

File diff suppressed because it is too large Load Diff

View File

@ -1163,10 +1163,10 @@
"action.uv_slider_pos_x.desc": "Move all selected UV faces horizontally",
"action.uv_slider_pos_y": "Move Vertical",
"action.uv_slider_pos_y.desc": "Move all selected UV faces vertically",
"action.uv_slider_size_x": "Scale Horizontal",
"action.uv_slider_size_x.desc": "Scale all selected UV faces horizontally",
"action.uv_slider_size_y": "Scale Vertical",
"action.uv_slider_size_y.desc": "Scale all selected UV faces vertically",
"action.uv_slider_size_x": "Size Horizontal",
"action.uv_slider_size_x.desc": "Resize all selected UV faces horizontally",
"action.uv_slider_size_y": "Size Vertical",
"action.uv_slider_size_y.desc": "Resize all selected UV faces vertically",
"action.vertex_snap_mode": "Snap Mode",
"action.vertex_snap_mode.desc": "Select if Vertex Snap moves elements to the selected position or resizes them",