Merge branch 'face-selection' into next

This commit is contained in:
JannisX11 2022-12-18 16:05:51 +01:00
commit d005c7661c
12 changed files with 179 additions and 139 deletions

View File

@ -1700,31 +1700,30 @@ const BARS = {
icon: 'delete',
category: 'edit',
keybind: new Keybind({key: 46}),
click: function () {
click() {
let mesh_selection = Project.mesh_selection[Mesh.selected[0].uuid];
if (Prop.active_panel == 'textures' && Texture.selected) {
Texture.selected.remove()
} else if (Prop.active_panel == 'color' && ['palette', 'both'].includes(ColorPanel.vue._data.open_tab)) {
if (ColorPanel.vue._data.palette.includes(ColorPanel.vue._data.main_color)) {
ColorPanel.vue._data.palette.remove(ColorPanel.vue._data.main_color)
}
} else if (Modes.edit && Mesh.selected.length && Project.selected_vertices[Mesh.selected[0].uuid] && Project.selected_vertices[Mesh.selected[0].uuid].length < Mesh.selected[0].vertice_list.length) {
} else if (Modes.edit && Mesh.selected.length && mesh_selection) {
Undo.initEdit({elements: Mesh.selected})
Mesh.selected.forEach(mesh => {
let has_selected_faces = false;
let selected_vertices = mesh.getSelectedVertices();
for (let key in mesh.faces) {
has_selected_faces = has_selected_faces || mesh.faces[key].isSelected();
}
if (BarItems.selection_mode.value == 'face' && has_selected_faces) {
for (let key in mesh.faces) {
let face = mesh.faces[key];
if (face.isSelected()) {
delete mesh.faces[key];
}
}
selected_vertices.forEach(vertex_key => {
let selected_edges = mesh.getSelectedEdges();
let selected_faces = mesh.getSelectedFaces();
if (BarItems.selection_mode.value == 'face' && selected_faces.length < Object.keys(mesh.faces).length) {
let affected_vertices = [];
selected_faces.forEach(fkey => {
affected_vertices.safePush(...mesh.faces[fkey].vertices);
delete mesh.faces[fkey];
})
affected_vertices.forEach(vertex_key => {
let used = false;
for (let key in mesh.faces) {
let face = mesh.faces[key];
@ -1734,31 +1733,35 @@ const BARS = {
delete mesh.vertices[vertex_key];
}
})
} else if (BarItems.selection_mode.value == 'edge' && selected_vertices.length) {
} else if (BarItems.selection_mode.value == 'edge') {
for (let key in mesh.faces) {
let face = mesh.faces[key];
let sorted_vertices = face.getSortedVertices();
let selected_corners = sorted_vertices.filter(vkey => selected_vertices.includes(vkey));
if (selected_corners.length >= 2) {
let index_diff = (sorted_vertices.indexOf(selected_corners[0]) - sorted_vertices.indexOf(selected_corners[1])) % sorted_vertices.length;
if ((sorted_vertices.length < 4 || Math.abs(index_diff) !== 2)) {
delete mesh.faces[key];
}
let has_edge = sorted_vertices.find((vkey_a, i) => {
let vkey_b = sorted_vertices[i+1] || sorted_vertices[0];
let edge = [vkey_a, vkey_b];
return selected_edges.find(edge2 => sameMeshEdge(edge, edge2))
})
if (has_edge) {
delete mesh.faces[key];
}
}
selected_vertices.forEach(vertex_key => {
let used = false;
for (let key in mesh.faces) {
let face = mesh.faces[key];
if (face.vertices.includes(vertex_key)) used = true;
}
if (!used) {
delete mesh.vertices[vertex_key];
}
selected_edges.forEachReverse(edge => {
edge.forEach(vkey => {
let used = false;
for (let key in mesh.faces) {
let face = mesh.faces[key];
if (face.vertices.includes(vkey)) used = true;
}
if (!used) {
delete mesh.vertices[vkey];
selected_vertices.remove(vkey);
selected_edges.remove(edge);
}
})
})
} else {
let selected_vertices = Project.selected_vertices[mesh.uuid];
} else if (BarItems.selection_mode.value == 'vertex' && selected_vertices.length < Object.keys(mesh.vertices).length) {
selected_vertices.forEach(vertex_key => {
delete mesh.vertices[vertex_key];
@ -1782,6 +1785,9 @@ const BARS = {
}
}
})
} else {
Mesh.selected.remove(mesh);
mesh.remove(false);
}
})

View File

@ -147,7 +147,7 @@ var codec = new Codec('project', {
selected_elements: Project.selected_elements.map(e => e.uuid),
selected_group: Project.selected_group?.uuid,
selected_vertices: JSON.parse(JSON.stringify(Project.selected_vertices)),
mesh_selection: JSON.parse(JSON.stringify(Project.mesh_selection)),
selected_faces: Project.selected_faces,
selected_texture: Project.selected_texture?.uuid,
};
@ -399,7 +399,7 @@ var codec = new Codec('project', {
})
Group.selected = (state.selected_group && Group.all.find(g => g.uuid == state.selected_group));
for (let key in state.selected_vertices) {
Project.selected_vertices[key] = state.selected_vertices[key];
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();

View File

@ -48,7 +48,7 @@ class ModelProject {
this.groups = [];
this.selected_elements = [];
this.selected_group = null;
this.selected_vertices = {};
this.mesh_selection = {};
this.selected_faces = [];
this.textures = [];
this.selected_texture = null;
@ -179,10 +179,13 @@ class ModelProject {
UVEditor.vue.elements = this.selected_elements;
UVEditor.vue.all_elements = this.elements;
UVEditor.vue.selected_vertices = this.selected_vertices;
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;
for (let uuid in this.mesh_selection) {
UVEditor.vue.selected_vertices[uuid] = this.mesh_selection[uuid].vertices;
}
Interface.Panels.textures.inside_vue.textures = Texture.all;
scene.add(this.model_3d);

View File

@ -102,15 +102,25 @@ function updateSelection(options = {}) {
obj.unselect()
}
if (obj instanceof Mesh) {
if (Project.selected_vertices[obj.uuid]) {
Project.selected_vertices[obj.uuid].forEachReverse(vkey => {
if (Project.mesh_selection[obj.uuid]) {
Project.mesh_selection[obj.uuid].vertices.forEachReverse(vkey => {
if (vkey in obj.vertices == false) {
Project.selected_vertices[obj.uuid].remove(vkey);
Project.mesh_selection[obj.uuid].vertices.remove(vkey);
}
})
Project.mesh_selection[obj.uuid].edges.forEachReverse(edge => {
if (!obj.vertices[edge[0]] || !obj.vertices[edge[1]]) {
Project.mesh_selection[obj.uuid].edges.remove(edge);
}
})
Project.mesh_selection[obj.uuid].faces.forEachReverse(fkey => {
if (fkey in obj.faces == false) {
Project.mesh_selection[obj.uuid].faces.remove(fkey);
}
})
}
if (Project.selected_vertices[obj.uuid] && (Project.selected_vertices[obj.uuid].length == 0 || !obj.selected)) {
delete Project.selected_vertices[obj.uuid];
if (Project.mesh_selection[obj.uuid] && (Project.mesh_selection[obj.uuid].vertices.length == 0 || !obj.selected)) {
delete Project.mesh_selection[obj.uuid];
}
}
})
@ -184,13 +194,13 @@ function updateSelection(options = {}) {
if (settings.highlight_cubes.value || (Mesh.all[0])) updateCubeHighlights();
if (Toolbox.selected.id == 'seam_tool' && Mesh.selected[0]) {
let value;
let selected_vertices = Mesh.selected[0].getSelectedVertices();
let selected_edges = Mesh.selected[0].getSelectedEdges();
Mesh.selected[0].forAllFaces((face) => {
if (value == '') return;
let vertices = face.getSortedVertices();
vertices.forEach((vkey_a, i) => {
let vkey_b = vertices[i+1] || vertices[0];
if (selected_vertices.includes(vkey_a) && selected_vertices.includes(vkey_b)) {
if (selected_edges.find(edge => sameMeshEdge(edge, [vkey_a, vkey_b]))) {
let seam = Mesh.selected[0].getSeam([vkey_a, vkey_b]) || 'auto';
if (value == undefined) {
value = seam;
@ -223,7 +233,7 @@ function selectAll() {
let unselect = Mesh.selected[0].getSelectedVertices().length == Object.keys(Mesh.selected[0].vertices).length;
Mesh.selected.forEach(mesh => {
if (unselect) {
delete Project.selected_vertices[mesh.uuid];
delete Project.mesh_selection[mesh.uuid];
} else {
mesh.getSelectedVertices(true).replace(Object.keys(mesh.vertices));
}
@ -253,8 +263,8 @@ function unselectAll() {
Group.all.forEach(function(s) {
s.selected = false
})
for (let key in Project.selected_vertices) {
delete Project.selected_vertices[key];
for (let key in Project.mesh_selection) {
delete Project.mesh_selection[key];
}
TickUpdates.selection = true;
}

View File

@ -1,3 +1,7 @@
function sameMeshEdge(edge_a, edge_b) {
return edge_a.equals(edge_b) || (edge_a[0] == edge_b[1] && edge_a[1] == edge_b[0])
}
BARS.defineActions(function() {
let add_mesh_dialog = new Dialog({
id: 'add_primitive',
@ -319,7 +323,7 @@ BARS.defineActions(function() {
onChange({value}) {
if (value === 'object') {
Mesh.selected.forEach(mesh => {
delete Project.selected_vertices[mesh.uuid];
delete Project.mesh_selection[mesh.uuid];
})
} else if (value === 'face') {
UVEditor.vue.selected_faces.empty();
@ -653,19 +657,16 @@ BARS.defineActions(function() {
Undo.initEdit({elements: Mesh.selected, selection: true}, amended);
Mesh.selected.forEach(mesh => {
let original_vertices = Project.selected_vertices[mesh.uuid].slice();
let original_vertices = mesh.getSelectedVertices().slice();
let new_vertices;
let new_face_keys = [];
let selected_faces = [];
let selected_face_keys = [];
let selected_face_keys = mesh.getSelectedFaces();
let selected_faces = selected_face_keys.map(fkey => mesh.faces[fkey]);
let combined_direction;
for (let fkey in mesh.faces) {
let face = mesh.faces[fkey];
if (face.isSelected()) {
selected_faces.push(face);
selected_face_keys.push(fkey);
}
}
selected_faces.forEach(face => {
original_vertices.safePush(...face.vertices);
})
if (original_vertices.length >= 3 && !selected_faces.length) {
let [a, b, c] = original_vertices.slice(0, 3).map(vkey => mesh.vertices[vkey].slice());
@ -738,7 +739,7 @@ BARS.defineActions(function() {
vector.V3_add(direction.map(v => v * extend));
return vector;
}))
Project.selected_vertices[mesh.uuid].replace(new_vertices);
Project.mesh_selection[mesh.uuid].vertices.replace(new_vertices);
// Move Faces
selected_faces.forEach(face => {
@ -850,7 +851,7 @@ BARS.defineActions(function() {
function runEdit(amended, offset = 50) {
Undo.initEdit({elements: Mesh.selected, selection: true}, amended);
Mesh.selected.forEach(mesh => {
let original_vertices = Project.selected_vertices[mesh.uuid].slice();
let original_vertices = mesh.getSelectedVertices();
if (original_vertices.length < 3) return;
let new_vertices;
let selected_faces = [];
@ -897,7 +898,7 @@ BARS.defineActions(function() {
}).filter(vec => vec instanceof Array))
if (!new_vertices.length) return;
Project.selected_vertices[mesh.uuid].replace(new_vertices);
Project.mesh_selection[mesh.uuid].vertices.replace(new_vertices);
// Move Faces
selected_faces.forEach(face => {
@ -1461,6 +1462,7 @@ BARS.defineActions(function() {
Mesh.selected.forEach(mesh => {
let selected_vertices = mesh.getSelectedVertices();
let mesh_selection = Project.mesh_selection[mesh.uuid];
let copy = new Mesh(mesh);
elements.push(copy);
@ -1497,8 +1499,8 @@ BARS.defineActions(function() {
copy.name += '_selection'
copy.sortInBefore(mesh, 1).init();
delete Project.selected_vertices[mesh.uuid];
Project.selected_vertices[copy.uuid] = selected_vertices;
delete Project.mesh_selection[mesh.uuid];
Project.mesh_selection[copy.uuid] = mesh_selection;
mesh.preview_controller.updateGeometry(mesh);
selected[selected.indexOf(mesh)] = copy;
})

View File

@ -347,12 +347,10 @@ const Vertexsnap = {
Vertexsnap.elements = Outliner.selected.slice();
Vertexsnap.group = Group.selected;
if (data.element instanceof Mesh && BarItems.selection_mode.value == 'vertex') {
if (!Project.selected_vertices[data.element.uuid]) {
Project.selected_vertices[data.element.uuid] = [];
}
Project.selected_vertices[data.element.uuid].safePush(data.vertex);
let vertices = data.element.getSelectedVertices(true);
vertices.safePush(data.vertex);
}
Vertexsnap.selected_vertices = JSON.parse(JSON.stringify(Project.selected_vertices));
Vertexsnap.selected_vertices = JSON.parse(JSON.stringify(Project.mesh_selection));
Vertexsnap.clearVertexGizmos()
$('#preview').css('cursor', (Vertexsnap.step1 ? 'copy' : 'alias'))
@ -441,7 +439,7 @@ const Vertexsnap = {
var cube_pos = new THREE.Vector3().copy(global_delta)
if (obj instanceof Mesh && Vertexsnap.selected_vertices && Vertexsnap.selected_vertices[obj.uuid]) {
let vertices = Vertexsnap.selected_vertices[obj.uuid];
let vertices = Vertexsnap.selected_vertices[obj.uuid].vertices;
var q = obj.mesh.getWorldQuaternion(Reusable.quat1).invert();
cube_pos.applyQuaternion(q);
let cube_pos_array = cube_pos.toArray();
@ -954,7 +952,7 @@ function rotateOnAxis(modify, axis, slider) {
}
}
if (!Group.selected && obj instanceof Mesh && Project.selected_vertices[obj.uuid] && Project.selected_vertices[obj.uuid].length > 0) {
if (!Group.selected && obj instanceof Mesh && Project.mesh_selection[obj.uuid] && Project.mesh_selection[obj.uuid].vertices.length > 0) {
let normal = axis == 0 ? THREE.NormalX : (axis == 1 ? THREE.NormalY : THREE.NormalZ)
let rotWorldMatrix = new THREE.Matrix4();
@ -976,7 +974,7 @@ function rotateOnAxis(modify, axis, slider) {
let vector = new THREE.Vector3();
let local_pivot = obj.mesh.worldToLocal(new THREE.Vector3().copy(Transformer.position))
Project.selected_vertices[obj.uuid].forEach(key => {
Project.mesh_selection[obj.uuid].vertices.forEach(key => {
vector.fromArray(obj.vertices[key]);
vector.sub(local_pivot);
vector.applyQuaternion(q);

View File

@ -910,7 +910,13 @@
//Center
if (Toolbox.selected.id === 'rotate_tool' || Toolbox.selected.id === 'pivot_tool') {
if (rotation_object instanceof Mesh && Toolbox.selected.id === 'rotate_tool' && Project.selected_vertices[rotation_object.uuid] && Project.selected_vertices[rotation_object.uuid].length > 0) {
if (rotation_object instanceof Mesh && Toolbox.selected.id === 'rotate_tool' &&
Project.mesh_selection[rotation_object.uuid] && (
Project.mesh_selection[rotation_object.uuid].vertices.length > 0 ||
Project.mesh_selection[rotation_object.uuid].edges.length > 0 ||
Project.mesh_selection[rotation_object.uuid].faces.length > 0
)
) {
this.position.copy(rotation_object.getWorldCenter())
} else if (rotation_object.mesh) {
rotation_object.mesh.getWorldPosition(this.position);

View File

@ -161,10 +161,7 @@ class MeshFace extends Face {
[this.vertices[0], this.vertices[1]] = [this.vertices[1], this.vertices[0]];
}
isSelected() {
let selected_vertices = Project.selected_vertices[this.mesh.uuid];
return selected_vertices
&& selected_vertices.length > 1
&& !this.vertices.find(key => !selected_vertices.includes(key))
return !!Project.mesh_selection[this.mesh.uuid] && Project.mesh_selection[this.mesh.uuid].faces.includes(this.getFaceKey());
}
getSortedVertices() {
if (this.vertices.length < 4) return this.vertices;
@ -322,13 +319,13 @@ class Mesh extends OutlinerElement {
let key = edge.slice(0, 2).sort().join('_');
return this.seams[key];
}
getWorldCenter(ignore_selected_vertices) {
getWorldCenter(ignore_mesh_selection) {
let m = this.mesh;
let pos = Reusable.vec1.set(0, 0, 0);
let vertice_count = 0;
for (let key in this.vertices) {
if (ignore_selected_vertices || !Project.selected_vertices[this.uuid] || (Project.selected_vertices[this.uuid] && Project.selected_vertices[this.uuid].includes(key))) {
if (ignore_mesh_selection || !Project.mesh_selection[this.uuid] || (Project.mesh_selection[this.uuid] && Project.mesh_selection[this.uuid].vertices.includes(key))) {
let vector = this.vertices[key];
pos.x += vector[0];
pos.y += vector[1];
@ -439,17 +436,16 @@ class Mesh extends OutlinerElement {
return el;
}
getSelectedVertices(make) {
if (make && !Project.selected_vertices[this.uuid]) Project.selected_vertices[this.uuid] = [];
return Project.selected_vertices[this.uuid] || [];
if (make && !Project.mesh_selection[this.uuid]) Project.mesh_selection[this.uuid] = {vertices: [], edges: [], faces: []};
return Project.mesh_selection[this.uuid]?.vertices || [];
}
getSelectedFaces() {
let faces = [];
for (let key in this.faces) {
if (this.faces[key].isSelected()) {
faces.push(key);
}
}
return faces;
getSelectedEdges(make) {
if (make && !Project.mesh_selection[this.uuid]) Project.mesh_selection[this.uuid] = {vertices: [], edges: [], faces: []};
return Project.mesh_selection[this.uuid]?.edges || [];
}
getSelectedFaces(make) {
if (make && !Project.mesh_selection[this.uuid]) Project.mesh_selection[this.uuid] = {vertices: [], edges: [], faces: []};
return Project.mesh_selection[this.uuid]?.faces || [];
}
getSelectionRotation() {
if (Transformer.dragging) {
@ -621,7 +617,7 @@ class Mesh extends OutlinerElement {
TickUpdates.selection = true;
}
resize(val, axis, negative, allow_negative, bidirectional) {
let selected_vertices = Project.selected_vertices[this.uuid] || Object.keys(this.vertices);
let selected_vertices = Project.mesh_selection[this.uuid]?.vertices || Object.keys(this.vertices);
let range = [Infinity, -Infinity];
let {vec1, vec2} = Reusable;
let rotation_inverted = new THREE.Euler().copy(Transformer.rotation_selection).invert();
@ -988,6 +984,8 @@ new NodePreviewController(Mesh, {
let join_selected = new THREE.Color(0x6bffcb);
let divide_selected = new THREE.Color(0xff8c69);
let selected_vertices = element.getSelectedVertices();
let selected_edges = element.getSelectedEdges();
let selected_faces = element.getSelectedFaces();
if (BarItems.selection_mode.value == 'vertex') {
let colors = [];
@ -1011,7 +1009,10 @@ new NodePreviewController(Mesh, {
let selected;
if (!Modes.edit || BarItems.selection_mode.value == 'object') {
color = gizmo_colors.outline;
} else if (selected_vertices.includes(key) && selected_vertices.includes(key_b)) {
} else if (BarItems.selection_mode.value == 'edge' && selected_edges.find(edge => sameMeshEdge([key, key_b], edge))) {
color = white;
selected = true;
} else if (BarItems.selection_mode.value == 'face' && selected_faces.find(fkey => element.faces[fkey].vertices.includes(key) && element.faces[fkey].vertices.includes(key_b))) {
color = white;
selected = true;
} else {
@ -1046,13 +1047,14 @@ new NodePreviewController(Mesh, {
) ? 1 : 0;
let array = new Array(mesh.geometry.attributes.highlight.count).fill(highlighted);
let selection_mode = BarItems.selection_mode.value;
if (!force_off && element.selected && Modes.edit) {
let i = 0;
for (let fkey in element.faces) {
let face = element.faces[fkey];
if (face.vertices.length < 3) continue;
if (face.isSelected()) {
if (face.isSelected() && selection_mode == 'face') {
for (let j = 0; j < face.vertices.length; j++) {
array[i] = 2;
i++;

View File

@ -1202,7 +1202,7 @@ BARS.defineActions(function() {
} else if (Modes.edit && Mesh.selected.length && Mesh.selected.length === Outliner.selected.length && BarItems.selection_mode.value !== 'object') {
Mesh.selected.forEach(mesh => {
delete Project.selected_vertices[mesh.uuid];
delete Project.mesh_selection[mesh.uuid];
})
updateSelection();

View File

@ -803,6 +803,8 @@ class Preview {
let mesh = data.element;
let selected_vertices = mesh.getSelectedVertices(true);
let selected_edges = mesh.getSelectedEdges(true);
let selected_faces = mesh.getSelectedFaces(true);
if (event.altKey || Pressing.overrides.alt) {
@ -829,21 +831,22 @@ class Preview {
if (!(event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift)) {
selected_vertices.empty();
selected_edges.empty();
selected_faces.empty();
UVEditor.vue.selected_faces.empty();
}
processed_faces.forEach(face => {
Project.selected_vertices[data.element.uuid].safePush(...face.vertices);
selected_vertices.safePush(...face.vertices);
let fkey = face.getFaceKey();
UVEditor.vue.selected_faces.push(fkey);
selected_faces.push(fkey);
});
} else {
if (!(event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift)) {
}
let face_vkeys = data.element.faces[data.face].vertices;
if (event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift) {
if (face_vkeys.allAre(vkey => selected_vertices.includes(vkey))) {
if (selected_faces.includes(data.face)) {
let selected_faces = data.element.getSelectedFaces();
let vkeys_to_remove = face_vkeys.filter(vkey => {
return !selected_faces.find(fkey => {
@ -853,13 +856,17 @@ 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]);
}
}
@ -878,34 +885,38 @@ class Preview {
} else if (data.type == 'vertex' && Toolbox.selected.id !== 'vertex_snap_tool') {
if (!Project.selected_vertices[data.element.uuid]) {
Project.selected_vertices[data.element.uuid] = [];
}
let list = Project.selected_vertices[data.element.uuid];
let list = data.element.getSelectedVertices(true);
let edges = data.element.getSelectedEdges(true);
let faces = data.element.getSelectedEdges(true);
if (event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift) {
list.toggle(data.vertex);
} else {
unselectOtherNodes()
unselectOtherNodes();
list.replace([data.vertex]);
edges.empty();
faces.empty();
}
updateSelection();
} else if (data.type == 'line') {
if (!Project.selected_vertices[data.element.uuid]) {
Project.selected_vertices[data.element.uuid] = [];
}
let list = Project.selected_vertices[data.element.uuid];
let vertices = data.element.getSelectedVertices(true);
let edges = data.element.getSelectedEdges(true);
let faces = data.element.getSelectedEdges(true);
if (event.ctrlOrCmd || Pressing.overrides.ctrl || event.shiftKey || Pressing.overrides.shift) {
if (list.includes(data.vertices[0]) && list.includes(data.vertices[1])) {
list.remove(...data.vertices);
let index = edges.findIndex(edge => sameMeshEdge(edge, data.vertices))
if (index >= 0) {
vertices.remove(...data.vertices);
edges.splice(index, 1);
} else {
list.remove(...data.vertices);
list.push(...data.vertices);
edges.push(data.vertices);
vertices.push(...data.vertices);
}
} else {
list.replace(data.vertices);
faces.empty();
edges.splice(0, Infinity, data.vertices);
vertices.replace(data.vertices);
unselectOtherNodes();
}
if (event.altKey || Pressing.overrides.alt) {
@ -935,7 +946,8 @@ class Preview {
let opposite_index_diff = sorted_vertices.indexOf(opposite_vertices[0]) - sorted_vertices.indexOf(opposite_vertices[1]);
if (opposite_index_diff == 1 || opposite_index_diff < -2) opposite_vertices.reverse();
list.safePush(...side_vertices);
vertices.safePush(...side_vertices);
edges.push(side_vertices);
// Find next (and previous) face
function doNextFace(index) {
@ -1080,10 +1092,7 @@ class Preview {
$(this.node).append(this.selection.box)
this.selection.activated = false;
this.selection.old_selected = Outliner.selected.slice();
this.selection.old_vertices_selected = {};
for (let uuid in Project.selected_vertices) {
this.selection.old_vertices_selected[uuid] = Project.selected_vertices[uuid].slice();
}
this.selection.old_mesh_selection = JSON.parse(JSON.stringify(Project.mesh_selection));
this.moveSelRect(event)
}
@ -1163,15 +1172,15 @@ class Preview {
if (element instanceof Mesh && (selection_mode == 'object' || scope.selection.old_selected.includes(element))) {
let selected_vertices;
let mesh_selection;
if (selection_mode != 'object') {
isSelected = true;
if (!Project.selected_vertices[element.uuid]) {
selected_vertices = Project.selected_vertices[element.uuid] = [];
if (!Project.mesh_selection[element.uuid]) {
mesh_selection = Project.mesh_selection[element.uuid] = {vertices: [], edges: [], faces: []};
} else {
selected_vertices = Project.selected_vertices[element.uuid];
mesh_selection = Project.mesh_selection[element.uuid];
}
if (!extend_selection) selected_vertices.empty();
if (!extend_selection) mesh_selection.vertices.empty();
}
let vertex_points = {};
@ -1183,19 +1192,17 @@ class Preview {
is_on_screen = true;
}
}
if (is_on_screen && extend_selection) {
for (let vkey in element.vertices) {
if (extend_selection && this.selection.old_vertices_selected[element.uuid] && this.selection.old_vertices_selected[element.uuid].includes(vkey)) {
selected_vertices.safePush(vkey);
}
}
if (extend_selection && this.selection.old_mesh_selection[element.uuid]) {
mesh_selection.vertices.safePush(...this.selection.old_mesh_selection[element.uuid].vertices);
mesh_selection.edges.safePush(...this.selection.old_mesh_selection[element.uuid].edges);
mesh_selection.faces.safePush(...this.selection.old_mesh_selection[element.uuid].faces);
}
if (!is_on_screen) {
} else if (selection_mode == 'vertex') {
for (let vkey in element.vertices) {
let point = vertex_points[vkey];
if (!selected_vertices.includes(vkey) && pointInRectangle(point, rect_start, rect_end)) {
selected_vertices.push(vkey);
if (!mesh_selection.vertices.includes(vkey) && pointInRectangle(point, rect_start, rect_end)) {
mesh_selection.vertices.push(vkey);
}
}
@ -1209,7 +1216,11 @@ class Preview {
let p1 = vertex_points[vkey];
let p2 = vertex_points[vkey2];
if (lineIntersectsReactangle(p1, p2, rect_start, rect_end)) {
selected_vertices.safePush(vkey);
mesh_selection.vertices.safePush(vkey);
let edge = [vkey, vkey2];
if (!mesh_selection.edges.find(edge2 => sameMeshEdge(edge, edge2))) {
mesh_selection.edges.push(edge);
}
}
}
}
@ -1229,16 +1240,18 @@ class Preview {
break;
}
}
if (face_intersects && selection_mode == 'object') {
if (selection_mode == 'object') {
if (face_intersects) {
isSelected = true;
break;
}
} else {
if (face_intersects) {
selected_vertices.safePush(...face.vertices);
mesh_selection.vertices.safePush(...face.vertices);
mesh_selection.faces.safePush(fkey);
UVEditor.vue.selected_faces.safePush(fkey);
} else {
mesh_selection.faces.remove(fkey);
UVEditor.vue.selected_faces.remove(fkey);
}
}

View File

@ -551,9 +551,9 @@ const UVEditor = {
obj.preview_controller.updateUV(obj);
})
Mesh.selected.forEach(mesh => {
let selected_vertices = Project.selected_vertices[mesh.uuid];
let selected_vertices = mesh.getSelectedVertices();
if (selected_vertices) {
if (selected_vertices.length) {
UVEditor.vue.selected_faces.forEach(fkey => {
if (!mesh.faces[fkey]) return
selected_vertices.forEach(vkey => {
@ -2344,7 +2344,7 @@ Interface.definePanels(function() {
UVEditor.getMappableElements().forEach(el => {
if (el instanceof Mesh) {
delete Project.selected_vertices[el.uuid];
delete Project.mesh_selection[el.uuid];
}
})
@ -3328,7 +3328,7 @@ Interface.definePanels(function() {
} else if (elements[0] instanceof Mesh) {
var face = UVEditor.getReferenceFace();
if (face) {
let selected_vertices = Project.selected_vertices[elements[0].uuid];
let selected_vertices = elements[0].getSelectedVertices();
let has_selected_vertices = selected_vertices && face.vertices.find(vkey => selected_vertices.includes(vkey))
let min = Infinity;
face.vertices.forEach(vkey => {

View File

@ -292,8 +292,8 @@ class UndoSystem {
elements.forEach(function(obj) {
if (save.selection.includes(obj.uuid)) {
obj.selectLow()
if (save.selected_vertices[obj.uuid]) {
Project.selected_vertices[obj.uuid] = save.selected_vertices[obj.uuid];
if (save.mesh_selection[obj.uuid]) {
Project.mesh_selection[obj.uuid] = save.mesh_selection[obj.uuid];
}
}
})
@ -496,11 +496,11 @@ UndoSystem.save = class {
if (aspects.selection) {
this.selection = [];
this.selected_vertices = {};
this.mesh_selection = {};
selected.forEach(obj => {
this.selection.push(obj.uuid);
if (obj instanceof Mesh) {
this.selected_vertices[obj.uuid] = Mesh.selected[0].getSelectedVertices().slice();
if (obj instanceof Mesh && Project.mesh_selection[obj.uuid]) {
this.mesh_selection[obj.uuid] = JSON.parse(JSON.stringify(Project.mesh_selection[obj.uuid]));
}
})
if (Group.selected) {