Fix #2104 slow draw speed on complex meshes

This commit is contained in:
JannisX11 2023-11-20 23:34:23 +01:00
parent 5842e73c91
commit 4665122d69
2 changed files with 25 additions and 9 deletions

View File

@ -134,14 +134,15 @@ class MeshFace extends Face {
}
return matrix;
}
getUVIsland() {
getUVIsland(max_depth = 4096) {
let keys = [this.getFaceKey()];
function crawl(face) {
let epsilon = 0.2;
function crawl(face, depth) {
if (depth >= max_depth) return;
for (let i = 0; i < face.vertices.length; i++) {
let adjacent = face.getAdjacentFace(i);
if (!adjacent) continue;
if (keys.includes(adjacent.key)) continue;
let epsilon = 0.2;
let uv_a1 = adjacent.face.uv[adjacent.edge[0]];
let uv_a2 = face.uv[adjacent.edge[0]];
if (!Math.epsilon(uv_a1[0], uv_a2[0], epsilon) || !Math.epsilon(uv_a1[1], uv_a2[1], epsilon)) continue;
@ -149,10 +150,10 @@ class MeshFace extends Face {
let uv_b2 = face.uv[adjacent.edge[1]];
if (!Math.epsilon(uv_b1[0], uv_b2[0], epsilon) || !Math.epsilon(uv_b1[1], uv_b2[1], epsilon)) continue;
keys.push(adjacent.key);
crawl(adjacent.face);
crawl(adjacent.face, depth+1);
}
}
crawl(this);
crawl(this, 0);
return keys;
}
getAngleTo(other) {

View File

@ -124,7 +124,7 @@ const Painter = {
if (
Painter.current.element !== data.element ||
(Painter.current.face !== data.face && !(data.element.faces[data.face] instanceof MeshFace && data.element.faces[data.face].getUVIsland().includes(Painter.current.face)))
(Painter.current.face !== data.face && !(data.element.faces[data.face] instanceof MeshFace && Painter.getMeshUVIsland(data.face, data.element.faces[data.face]).includes(Painter.current.face)))
) {
if (Toolbox.selected.id === 'draw_shape_tool' || Toolbox.selected.id === 'gradient_tool') {
return;
@ -149,6 +149,13 @@ const Painter = {
removeEventListeners(document, 'mouseup touchend', Painter.stopPaintToolCanvas, false );
Painter.stopPaintTool();
},
getMeshUVIsland(fkey, face) {
if (!Painter.current.uv_islands) Painter.current.uv_islands = {};
if (!Painter.current.uv_islands[fkey]) {
Painter.current.uv_islands[fkey] = face.getUVIsland();
}
return Painter.current.uv_islands[fkey];
},
// Paint Tool Main
startPaintTool(texture, x, y, uvTag, event, data) {
//Called directly by startPaintToolCanvas and startBrushUV
@ -203,7 +210,7 @@ const Painter = {
is_line = (event.shiftKey || Pressing.overrides.shift)
&& Painter.current.element == data.element
&& (Painter.current.face == data.face ||
(data.element.faces[data.face] instanceof MeshFace && data.element.faces[data.face].getUVIsland().includes(Painter.current.face))
(data.element.faces[data.face] instanceof MeshFace && Painter.getMeshUVIsland(data.face, data.element.faces[data.face]).includes(Painter.current.face))
)
Painter.current.element = data.element;
Painter.current.face = data.face;
@ -279,11 +286,18 @@ const Painter = {
delete Painter.current.last_pixel;
delete Painter.current.texture;
delete Painter.current.textures;
delete Painter.current.uv_rects;
Painter.painting = false;
Painter.currentPixel = [-1, -1];
},
// Tools
setupRectFromFace(uvTag, texture) {
if (!Painter.current.uv_rects) {
Painter.current.uv_rects = new Map();
}
let val = Painter.current.uv_rects.get(uvTag);
if (val) return val;
let rect;
let uvFactorX = texture.width / texture.getUVWidth();
let uvFactorY = texture.display_height / texture.getUVHeight();
@ -313,7 +327,7 @@ const Painter = {
let current_face = Mesh.selected[0] && Mesh.selected[0].faces[Painter.current.face];
if (current_face) {
let island = current_face.getUVIsland();
let island = Painter.getMeshUVIsland(Painter.current.face, current_face);
island.forEach(fkey => {
let face = Mesh.selected[0].faces[fkey];
for (let vkey in face.uv) {
@ -333,6 +347,7 @@ const Painter = {
} else {
rect = Painter.editing_area = [0, 0, texture.img.naturalWidth, texture.img.naturalHeight]
}
Painter.current.uv_rects.set(uvTag, rect);
return rect;
},
useBrushlike(texture, x, y, event, uvTag, no_update, is_opposite) {
@ -393,7 +408,7 @@ const Painter = {
let face = Painter.current.element.faces[Painter.current.face];
if (face && face.vertices.length > 2 && !Painter.current.face_matrices[matrix_id]) {
Painter.current.face_matrices[matrix_id] = face.getOccupationMatrix(true, [0, 0]);
let island = face.getUVIsland();
let island = Painter.getMeshUVIsland(Painter.current.face, face);
for (let fkey of island) {
let face = Painter.current.element.faces[fkey];
face.getOccupationMatrix(true, [0, 0], Painter.current.face_matrices[matrix_id]);