From 1d0a7fc495e9411d9d2aa10018bf7365781424c1 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Tue, 29 Jul 2025 14:11:36 +0300 Subject: [PATCH] Improved transform and clipboard paste performance, and share memory between copied brush strokes in some instances --- src/DrawComponents/DrawBrushStroke.cpp | 48 +++++++++++-------- src/DrawComponents/DrawBrushStroke.hpp | 5 +- src/DrawComponents/DrawComponent.cpp | 25 +++++----- src/DrawComponents/DrawComponent.hpp | 5 +- src/DrawComponents/DrawEllipse.cpp | 10 +++- src/DrawComponents/DrawEllipse.hpp | 2 + src/DrawComponents/DrawImage.cpp | 10 +++- src/DrawComponents/DrawImage.hpp | 2 + src/DrawComponents/DrawRectangle.cpp | 10 +++- src/DrawComponents/DrawRectangle.hpp | 2 + src/DrawComponents/DrawTextBox.cpp | 11 ++++- src/DrawComponents/DrawTextBox.hpp | 2 + src/DrawingProgram/BrushTool.cpp | 30 ++++++------ src/DrawingProgram/DrawingProgram.cpp | 4 +- .../DrawingProgramSelection.cpp | 10 ++-- 15 files changed, 115 insertions(+), 61 deletions(-) diff --git a/src/DrawComponents/DrawBrushStroke.cpp b/src/DrawComponents/DrawBrushStroke.cpp index a346f05..c12a259 100644 --- a/src/DrawComponents/DrawBrushStroke.cpp +++ b/src/DrawComponents/DrawBrushStroke.cpp @@ -15,11 +15,11 @@ #define DEFAULT_SMOOTHNESS 5 void DrawBrushStroke::save(cereal::PortableBinaryOutputArchive& a) const { - a(d.points, d.color, d.hasRoundCaps); + a(d->points, d->color, d->hasRoundCaps); } void DrawBrushStroke::load(cereal::PortableBinaryInputArchive& a) { - a(d.points, d.color, d.hasRoundCaps); + a(d->points, d->color, d->hasRoundCaps); } DrawComponentType DrawBrushStroke::get_type() const { @@ -35,6 +35,18 @@ std::shared_ptr DrawBrushStroke::copy() const { return a; } +std::shared_ptr DrawBrushStroke::deep_copy() const { + auto a = std::make_shared(); + a->d = d; + a->coords = coords; + // Just copy pointers over, brush strokes cant be edited so they can share the same memory + a->vertices = vertices; + a->verticesMipMap = verticesMipMap; + a->bounds = bounds; + + return a; +} + void DrawBrushStroke::update_from_delayed_ptr() { std::shared_ptr newPtr = std::static_pointer_cast(delayedUpdatePtr); d = newPtr->d; @@ -63,11 +75,11 @@ void DrawBrushStroke::draw(SkCanvas* canvas, const DrawData& drawData) { // return; SkPaint paint; - if(d.color.w() == 1.0) // Fully opaque, dont bother with blending + if(d->color.w() == 1.0) // Fully opaque, dont bother with blending canvas->save(); else - canvas->saveLayerAlphaf(nullptr, d.color.w()); - paint.setColor4f(SkColor4f{d.color.x(), d.color.y(), d.color.z(), 1.0f}); + canvas->saveLayerAlphaf(nullptr, d->color.w()); + paint.setColor4f(SkColor4f{d->color.x(), d->color.y(), d->color.z(), 1.0f}); canvas_do_calculated_transform(canvas); if(drawSetupData.mipmapLevel == 0) canvas->drawVertices(vertices, SkBlendMode::kClear, paint); @@ -87,9 +99,9 @@ void DrawBrushStroke::draw(SkCanvas* canvas, const DrawData& drawData) { } void DrawBrushStroke::initialize_draw_data(DrawingProgram& drawP) { - if(!d.points.empty()) { + if(!d->points.empty()) { std::vector vertexData; - std::vector points = smooth_points(0, d.points.size() - 1, DEFAULT_SMOOTHNESS); + std::vector points = smooth_points(0, d->points.size() - 1, DEFAULT_SMOOTHNESS); auto triangleFunc = [&](Vector2f a, Vector2f b, Vector2f c) { vertexData.emplace_back(a.x(), a.y()); vertexData.emplace_back(b.x(), b.y()); @@ -126,7 +138,7 @@ std::vector DrawBrushStroke::get_wedge_indices(const std::vector DrawBrushStroke::smooth_points(size_t beginIndex, size_t endIndex, unsigned numOfDivisions) { - std::vector& points = d.points; + std::vector& points = d->points; size_t pointsSize = endIndex - beginIndex + 1; if(pointsSize < 2) @@ -170,7 +182,7 @@ std::vector DrawBrushStroke::smooth_points(size_t beginInd } std::vector DrawBrushStroke::smooth_points_avg(size_t beginIndex, size_t endIndex, unsigned numOfDivisions) { - std::vector& points = d.points; + std::vector& points = d->points; size_t pointsSize = endIndex - beginIndex + 1; if(pointsSize < 2) @@ -201,9 +213,9 @@ std::vector DrawBrushStroke::smooth_points_avg(size_t begi void DrawBrushStroke::create_triangles(const std::function& passTriangleFunc, const std::vector& points, unsigned skipVertexCount) { const int ARC_SMOOTHNESS = 10; const int CIRCLE_SMOOTHNESS = 20; - std::vector& pointsN = d.points; + std::vector& pointsN = d->points; - if(pointsN.size() == 1 && d.hasRoundCaps) { + if(pointsN.size() == 1 && d->hasRoundCaps) { std::vector circlePoints = gen_circle_points(pointsN.front().pos, pointsN.front().width / 2.0f, CIRCLE_SMOOTHNESS); for(size_t i = 0; i < circlePoints.size(); i++) if(passTriangleFunc(pointsN.front().pos, circlePoints[i], circlePoints[(i + 1) % circlePoints.size()])) return; @@ -228,7 +240,7 @@ void DrawBrushStroke::create_triangles(const std::functionhasRoundCaps && pointsBegin == 0) { Vector2f arcDirStart = (convert_vec2(vertArray[0]) - points[0].pos).normalized(); Vector2f arcDirEnd = (convert_vec2(vertArray[1]) - points[0].pos).normalized(); Vector2f arcDirCenter = (points[0].pos - points[1].pos).normalized(); @@ -320,7 +332,7 @@ void DrawBrushStroke::create_triangles(const std::functionhasRoundCaps) { // It's the last point, cap it off Vector2f arcDirStart = (convert_vec2(vertArray[(newIndex + 1) % 3]) - points.back().pos).normalized(); Vector2f arcDirEnd = (convert_vec2(vertArray[(newIndex + 2) % 3]) - points.back().pos).normalized(); Vector2f arcDirCenter = -rectDir; @@ -335,10 +347,10 @@ void DrawBrushStroke::create_triangles(const std::functionpoints.empty()) return; ColliderCollection strokeObjects; - std::vector points = smooth_points(0, d.points.size() - 1, DEFAULT_SMOOTHNESS); + std::vector points = smooth_points(0, d->points.size() - 1, DEFAULT_SMOOTHNESS); create_triangles([&](Vector2f a, Vector2f b, Vector2f c) { strokeObjects.triangle.emplace_back(a, b, c); return false; @@ -352,8 +364,6 @@ void DrawBrushStroke::create_collider() { add_precheck_aabb_level(0, collisionTree.children); bounds = collisionTree.objects.bounds; - - calculate_world_bounds(); } void DrawBrushStroke::add_precheck_aabb_level(size_t level, const std::vector>& levelArray) { @@ -366,7 +376,7 @@ void DrawBrushStroke::add_precheck_aabb_level(size_t level, const std::vector& vertexDataPtr, const std::vector& vertexData) { - if((d.points.size() == 1 && d.hasRoundCaps) || d.points.size() >= 2) + if((d->points.size() == 1 && d->hasRoundCaps) || d->points.size() >= 2) vertexDataPtr = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, vertexData.size(), vertexData.data(), nullptr, nullptr); else vertexDataPtr = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, 0, nullptr, nullptr, nullptr); @@ -390,7 +400,7 @@ bool DrawBrushStroke::collides_within_coords(const SCollision::ColliderCollectio return false; bool toRet = false; - std::vector points = smooth_points(0, d.points.size() - 1, DEFAULT_SMOOTHNESS); + std::vector points = smooth_points(0, d->points.size() - 1, DEFAULT_SMOOTHNESS); create_triangles([&](Vector2f a, Vector2f b, Vector2f c) { toRet = SCollision::collide(checkAgainst, SCollision::Triangle{a, b, c}); return toRet; diff --git a/src/DrawComponents/DrawBrushStroke.hpp b/src/DrawComponents/DrawBrushStroke.hpp index 015f492..beb23fb 100644 --- a/src/DrawComponents/DrawBrushStroke.hpp +++ b/src/DrawComponents/DrawBrushStroke.hpp @@ -30,10 +30,13 @@ class DrawBrushStroke : public DrawComponent { std::vector points; Vector4f color; bool hasRoundCaps; - } d; + }; + std::shared_ptr d = std::make_shared(); // It's a pointer here since brush strokes cant be edited #ifndef IS_SERVER virtual std::shared_ptr copy() const override; + virtual std::shared_ptr deep_copy() const override; + virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void initialize_draw_data(DrawingProgram& drawP) override; virtual void update(DrawingProgram& drawP) override; diff --git a/src/DrawComponents/DrawComponent.cpp b/src/DrawComponents/DrawComponent.cpp index 11240d1..5d8c5f1 100644 --- a/src/DrawComponents/DrawComponent.cpp +++ b/src/DrawComponents/DrawComponent.cpp @@ -122,19 +122,24 @@ void DrawComponent::check_timers(DrawingProgram& drawP) { } void DrawComponent::temp_update(DrawingProgram& drawP) { - drawP.compCache.preupdate_component(collabListInfo.lock()); + if(collabListInfo.lock()) + drawP.compCache.preupdate_component(collabListInfo.lock()); worldAABB = std::nullopt; initialize_draw_data(drawP); } -void DrawComponent::transform_temp_update(DrawingProgram& drawP) { - drawP.compCache.preupdate_component(collabListInfo.lock()); - worldAABB = std::nullopt; -} - void DrawComponent::final_update(DrawingProgram& drawP, bool invalidateCache) { + if(invalidateCache && collabListInfo.lock()) + drawP.compCache.preupdate_component(collabListInfo.lock()); initialize_draw_data(drawP); - finalize_update(drawP, invalidateCache); + create_collider(); + calculate_world_bounds(); +} + +void DrawComponent::transform_update(DrawingProgram& drawP, bool invalidateCache) { + if(invalidateCache && collabListInfo.lock()) + drawP.compCache.preupdate_component(collabListInfo.lock()); + calculate_world_bounds(); } void DrawComponent::client_send_place_many(DrawingProgram& drawP, std::vector& comps) { @@ -169,12 +174,6 @@ void DrawComponent::client_send_erase_set(DrawingProgram& drawP, const std::unor drawP.world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_ERASE_MANY_COMPONENTS, ids); } -void DrawComponent::finalize_update(DrawingProgram& drawP, bool invalidateCache) { - if(invalidateCache && collabListInfo.lock()) - drawP.compCache.preupdate_component(collabListInfo.lock()); - create_collider(); -} - bool DrawComponent::collides_with_world_coords(const CoordSpaceHelper& camCoords, const SCollision::ColliderCollection& checkAgainstWorld) { return collides_with(camCoords, checkAgainstWorld, camCoords.world_collider_to_coords>(checkAgainstWorld)); } diff --git a/src/DrawComponents/DrawComponent.hpp b/src/DrawComponents/DrawComponent.hpp index 2dc8f45..969835e 100644 --- a/src/DrawComponents/DrawComponent.hpp +++ b/src/DrawComponents/DrawComponent.hpp @@ -103,13 +103,14 @@ class DrawComponent { virtual SCollision::AABB get_obj_coord_bounds() const = 0; virtual std::shared_ptr copy() const = 0; + virtual std::shared_ptr deep_copy() const = 0; + virtual void create_collider() = 0; virtual void draw(SkCanvas* canvas, const DrawData& drawData) = 0; void temp_update(DrawingProgram& drawP); void final_update(DrawingProgram& drawP, bool invalidateCache = true); // invalidateCache = false version should be thread safe - void transform_temp_update(DrawingProgram& drawP); + void transform_update(DrawingProgram& drawP, bool invalidateCache = true); virtual void initialize_draw_data(DrawingProgram& drawP) = 0; - virtual void finalize_update(DrawingProgram& drawP, bool invalidateCache = true); virtual void update(DrawingProgram& drawP) = 0; virtual bool collides_within_coords(const SCollision::ColliderCollection& checkAgainst) = 0; bool collides_with_world_coords(const CoordSpaceHelper& camCoords, const SCollision::ColliderCollection& checkAgainstWorld); diff --git a/src/DrawComponents/DrawEllipse.cpp b/src/DrawComponents/DrawEllipse.cpp index 7c453a9..23efabc 100644 --- a/src/DrawComponents/DrawEllipse.cpp +++ b/src/DrawComponents/DrawEllipse.cpp @@ -26,6 +26,15 @@ std::shared_ptr DrawEllipse::copy() const { return a; } +std::shared_ptr DrawEllipse::deep_copy() const { + auto a = std::make_shared(); + a->d = d; + a->coords = coords; + a->ellipsePath = ellipsePath; + a->collisionTree = collisionTree; + return a; +} + void DrawEllipse::update_from_delayed_ptr() { std::shared_ptr newPtr = std::static_pointer_cast(delayedUpdatePtr); d = newPtr->d; @@ -125,7 +134,6 @@ void DrawEllipse::create_collider() { collisionTree.clear(); collisionTree.calculate_bvh_recursive(strokeObjects); - calculate_world_bounds(); } SCollision::AABB DrawEllipse::get_obj_coord_bounds() const { diff --git a/src/DrawComponents/DrawEllipse.hpp b/src/DrawComponents/DrawEllipse.hpp index b15dec7..bba06e7 100644 --- a/src/DrawComponents/DrawEllipse.hpp +++ b/src/DrawComponents/DrawEllipse.hpp @@ -26,6 +26,8 @@ class DrawEllipse : public DrawComponent { #ifndef IS_SERVER virtual std::shared_ptr copy() const override; + virtual std::shared_ptr deep_copy() const override; + virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void initialize_draw_data(DrawingProgram& drawP) override; virtual void update(DrawingProgram& drawP) override; diff --git a/src/DrawComponents/DrawImage.cpp b/src/DrawComponents/DrawImage.cpp index d8d3d2e..fd63e24 100644 --- a/src/DrawComponents/DrawImage.cpp +++ b/src/DrawComponents/DrawImage.cpp @@ -40,6 +40,15 @@ std::shared_ptr DrawImage::copy() const { return a; } +std::shared_ptr DrawImage::deep_copy() const { + auto a = std::make_shared(); + a->d = d; + a->coords = coords; + a->imRect = imRect; + a->collisionTree = collisionTree; + return a; +} + void DrawImage::update_from_delayed_ptr() { std::shared_ptr newPtr = std::static_pointer_cast(delayedUpdatePtr); d = newPtr->d; @@ -86,7 +95,6 @@ void DrawImage::create_collider() { strokeObjects.triangle.emplace_back(newT[2], newT[3], newT[0]); collisionTree.clear(); collisionTree.calculate_bvh_recursive(strokeObjects); - calculate_world_bounds(); } SCollision::AABB DrawImage::get_obj_coord_bounds() const { diff --git a/src/DrawComponents/DrawImage.hpp b/src/DrawComponents/DrawImage.hpp index 778a639..729a41e 100644 --- a/src/DrawComponents/DrawImage.hpp +++ b/src/DrawComponents/DrawImage.hpp @@ -25,6 +25,8 @@ class DrawImage : public DrawComponent { #ifndef IS_SERVER virtual std::shared_ptr copy() const override; + virtual std::shared_ptr deep_copy() const override; + virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void initialize_draw_data(DrawingProgram& drawP) override; virtual void update(DrawingProgram& drawP) override; diff --git a/src/DrawComponents/DrawRectangle.cpp b/src/DrawComponents/DrawRectangle.cpp index eb07f7c..e69926d 100644 --- a/src/DrawComponents/DrawRectangle.cpp +++ b/src/DrawComponents/DrawRectangle.cpp @@ -29,6 +29,15 @@ std::shared_ptr DrawRectangle::copy() const { return a; } +std::shared_ptr DrawRectangle::deep_copy() const { + auto a = std::make_shared(); + a->d = d; + a->coords = coords; + a->rectPath = rectPath; + a->collisionTree = collisionTree; + return a; +} + void DrawRectangle::update_from_delayed_ptr() { std::shared_ptr newPtr = std::static_pointer_cast(delayedUpdatePtr); d = newPtr->d; @@ -108,7 +117,6 @@ void DrawRectangle::create_collider() { collisionTree.clear(); collisionTree.calculate_bvh_recursive(strokeObjects); - calculate_world_bounds(); } SCollision::AABB DrawRectangle::get_obj_coord_bounds() const { diff --git a/src/DrawComponents/DrawRectangle.hpp b/src/DrawComponents/DrawRectangle.hpp index 0822686..5fdd3e6 100644 --- a/src/DrawComponents/DrawRectangle.hpp +++ b/src/DrawComponents/DrawRectangle.hpp @@ -27,6 +27,8 @@ class DrawRectangle : public DrawComponent { #ifndef IS_SERVER virtual std::shared_ptr copy() const override; + virtual std::shared_ptr deep_copy() const override; + virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void initialize_draw_data(DrawingProgram& drawP) override; virtual void update(DrawingProgram& drawP) override; diff --git a/src/DrawComponents/DrawTextBox.cpp b/src/DrawComponents/DrawTextBox.cpp index ab53492..5d30c97 100644 --- a/src/DrawComponents/DrawTextBox.cpp +++ b/src/DrawComponents/DrawTextBox.cpp @@ -33,6 +33,16 @@ std::shared_ptr DrawTextBox::copy() const { return a; } +std::shared_ptr DrawTextBox::deep_copy() const { + auto a = std::make_shared(); + a->d = d; + a->coords = coords; + a->textboxUpdate = false; + a->collisionTree = collisionTree; + a->textBox = textBox; + return a; +} + void DrawTextBox::update_from_delayed_ptr() { std::shared_ptr newPtr = std::static_pointer_cast(delayedUpdatePtr); d = newPtr->d; @@ -118,7 +128,6 @@ void DrawTextBox::create_collider() { strokeObjects.triangle.emplace_back(newT[2], newT[3], newT[0]); collisionTree.clear(); collisionTree.calculate_bvh_recursive(strokeObjects); - calculate_world_bounds(); } SCollision::AABB DrawTextBox::get_obj_coord_bounds() const { diff --git a/src/DrawComponents/DrawTextBox.hpp b/src/DrawComponents/DrawTextBox.hpp index 0253a4c..1f0074d 100644 --- a/src/DrawComponents/DrawTextBox.hpp +++ b/src/DrawComponents/DrawTextBox.hpp @@ -29,6 +29,8 @@ class DrawTextBox : public DrawComponent { #ifndef IS_SERVER virtual std::shared_ptr copy() const override; + virtual std::shared_ptr deep_copy() const override; + virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void initialize_draw_data(DrawingProgram& drawP) override; virtual bool collides_within_coords(const SCollision::ColliderCollection& checkAgainst) override; diff --git a/src/DrawingProgram/BrushTool.cpp b/src/DrawingProgram/BrushTool.cpp index 89c840c..e3a565d 100644 --- a/src/DrawingProgram/BrushTool.cpp +++ b/src/DrawingProgram/BrushTool.cpp @@ -24,7 +24,7 @@ void BrushTool::reset_tool() { } bool BrushTool::extensive_point_checking(const Vector2f& newPoint) { - auto& points = controls.intermediateItem->d.points; + auto& points = controls.intermediateItem->d->points; if(points.size() >= 1 && (newPoint - points[points.size() - 1].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT) return false; if(points.size() >= 2 && (newPoint - points[points.size() - 2].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT) @@ -35,7 +35,7 @@ bool BrushTool::extensive_point_checking(const Vector2f& newPoint) { } bool BrushTool::extensive_point_checking_back(const Vector2f& newPoint) { - auto& points = controls.intermediateItem->d.points; + auto& points = controls.intermediateItem->d->points; if(points.size() >= 2 && (newPoint - points[points.size() - 2].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT) return false; if(points.size() >= 3 && (newPoint - points[points.size() - 3].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT) @@ -100,9 +100,9 @@ void BrushTool::tool_update() { p.pos = drawP.world.main.input.mouse.pos; p.width = drawP.controls.relativeWidth * controls.penWidth; controls.prevPointUnaltered = p.pos; - controls.intermediateItem->d.points.emplace_back(p); - controls.intermediateItem->d.color = drawP.controls.foregroundColor; - controls.intermediateItem->d.hasRoundCaps = controls.hasRoundCaps; + controls.intermediateItem->d->points.emplace_back(p); + controls.intermediateItem->d->color = drawP.controls.foregroundColor; + controls.intermediateItem->d->hasRoundCaps = controls.hasRoundCaps; controls.intermediateItem->coords = drawP.world.drawData.cam.c; controls.intermediateItem->lastUpdateTime = std::chrono::steady_clock::now(); uint64_t placement = drawP.components.client_list().size(); @@ -123,29 +123,29 @@ void BrushTool::tool_update() { if(!controls.addedTemporaryPoint) { if(extensive_point_checking(p.pos)) { - controls.intermediateItem->d.points.emplace_back(p); + controls.intermediateItem->d->points.emplace_back(p); controls.addedTemporaryPoint = true; } else - controls.intermediateItem->d.points.back().width = std::max(controls.intermediateItem->d.points.back().width, p.width); + controls.intermediateItem->d->points.back().width = std::max(controls.intermediateItem->d->points.back().width, p.width); } if(controls.addedTemporaryPoint) { - const DrawBrushStrokePoint& prevP = controls.intermediateItem->d.points[controls.intermediateItem->d.points.size() - 2]; + const DrawBrushStrokePoint& prevP = controls.intermediateItem->d->points[controls.intermediateItem->d->points.size() - 2]; float distToPrev = (p.pos - prevP.pos).norm(); if(extensive_point_checking_back(p.pos)) { - controls.intermediateItem->d.points.back().pos = p.pos; - controls.intermediateItem->d.points.back().width = std::max(controls.intermediateItem->d.points.back().width, p.width); - controls.intermediateItem->d.points[controls.intermediateItem->d.points.size() - 2].width = std::max(controls.intermediateItem->d.points[controls.intermediateItem->d.points.size() - 2].width, p.width); + controls.intermediateItem->d->points.back().pos = p.pos; + controls.intermediateItem->d->points.back().width = std::max(controls.intermediateItem->d->points.back().width, p.width); + controls.intermediateItem->d->points[controls.intermediateItem->d->points.size() - 2].width = std::max(controls.intermediateItem->d->points[controls.intermediateItem->d->points.size() - 2].width, p.width); } if((!controls.drawingMinimumRelativeToSize && distToPrev >= 10.0) || (controls.drawingMinimumRelativeToSize && distToPrev >= drawP.controls.relativeWidth * DRAW_MINIMUM_LIMIT)) { - controls.intermediateItem->d.points.back() = p; + controls.intermediateItem->d->points.back() = p; controls.addedTemporaryPoint = false; controls.intermediateItem->client_send_update_temp(drawP); if(controls.midwayInterpolation) { - if(controls.intermediateItem->d.points.size() != 2) // Don't interpolate the first point - controls.intermediateItem->d.points[controls.intermediateItem->d.points.size() - 2].pos = (controls.prevPointUnaltered + p.pos) * 0.5; + if(controls.intermediateItem->d->points.size() != 2) // Don't interpolate the first point + controls.intermediateItem->d->points[controls.intermediateItem->d->points.size() - 2].pos = (controls.prevPointUnaltered + p.pos) * 0.5; controls.prevPointUnaltered = p.pos; } } @@ -174,7 +174,7 @@ bool BrushTool::prevent_undo_or_redo() { void BrushTool::commit_stroke() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { - if(!controls.intermediateItem->d.points.empty()) { + if(!controls.intermediateItem->d->points.empty()) { controls.intermediateItem->client_send_update_final(drawP); controls.intermediateItem->final_update(drawP); } diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 8d3903e..0358340 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -106,7 +106,7 @@ void DrawingProgram::init_client_callbacks() { return; comp->coords = coords; objsActuallyTransformed++; - comp->finalize_update(*this, false); + comp->transform_update(*this, false); }); if(objsActuallyTransformed != 0) force_rebuild_cache(); @@ -120,7 +120,7 @@ void DrawingProgram::init_client_callbacks() { if(comp->coords == coords) return; comp->coords = coords; - comp->finalize_update(*this); // No need to update draw data during transformation + comp->transform_update(*this); } } }); diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index ef6f34f..e96851e 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -94,7 +94,7 @@ void DrawingProgramSelection::deselect_all() { bool isSingleThread = a.size() < DrawingProgramCache::MINIMUM_COMPONENTS_TO_START_REBUILD; parallel_loop_container(a, [&](auto& obj) { obj->obj->coords = selectionTransformCoords.other_coord_space_from_this_space(obj->obj->coords); - obj->obj->finalize_update(drawP, false); + obj->obj->transform_update(drawP, false); }, isSingleThread); if(!isSingleThread) drawP.force_rebuild_cache(); @@ -128,7 +128,7 @@ void DrawingProgramSelection::deselect_all() { parallel_loop_container(transformsFrom, [&](auto& p) { auto& [comp, coords] = p; comp->obj->coords = coords; - comp->obj->finalize_update(drawP, isSingleThread); + comp->obj->transform_update(drawP, isSingleThread); }, isSingleThread); DrawComponent::client_send_transform_many(drawP, transformsToSend); @@ -154,7 +154,7 @@ void DrawingProgramSelection::deselect_all() { parallel_loop_container(transformsTo, [&](auto& p) { auto& [comp, coords] = p; comp->obj->coords = coords; - comp->obj->finalize_update(drawP, isSingleThread); + comp->obj->transform_update(drawP, isSingleThread); }, isSingleThread); DrawComponent::client_send_transform_many(drawP, transformsToSend); @@ -328,13 +328,13 @@ void DrawingProgramSelection::paste_clipboard() { for(auto& r : clipboard.resources) resourceRemapIDs[r.first] = drawP.world.rMan.add_resource(r.second); for(auto& c : clipboard.components) - placedComponents.emplace_back(c->copy()); + placedComponents.emplace_back(c->deep_copy()); drawP.addToCompCacheOnInsert = false; auto compListInserted = drawP.components.client_insert_ordered_vector_items(allPlacement, placedComponents); parallel_loop_container(compListInserted, [&](auto& c) { c->obj->remap_resource_ids(resourceRemapIDs); c->obj->coords.translate(-moveVec); - c->obj->final_update(drawP, false); + c->obj->transform_update(drawP, false); }); DrawComponent::client_send_place_many(drawP, compListInserted); drawP.addToCompCacheOnInsert = true;