diff --git a/src/CanvasComponents/BrushComponentCode.cpp b/src/CanvasComponents/BrushComponentCode.cpp index d1c3e9b..ca4057c 100644 --- a/src/CanvasComponents/BrushComponentCode.cpp +++ b/src/CanvasComponents/BrushComponentCode.cpp @@ -129,7 +129,7 @@ std::optional skpath_simplify_only_lines(const SkPath& skPath) { if(!clipper.Execute(ClipType::Union, skPath.getFillType() == SkPathFillType::kEvenOdd ? FillRule::EvenOdd : FillRule::NonZero, solutionPaths)) return std::nullopt; - SimplifyPaths(solutionPaths, 0.01); + SimplifyPaths(solutionPaths, CLIPPER_SIMPLIFY_EPSILON); SkPathBuilder newPath; newPath.setFillType(skPath.getFillType()); diff --git a/src/CanvasComponents/CanvasComponent.cpp b/src/CanvasComponents/CanvasComponent.cpp index d448201..e099e47 100644 --- a/src/CanvasComponents/CanvasComponent.cpp +++ b/src/CanvasComponents/CanvasComponent.cpp @@ -78,6 +78,9 @@ bool CanvasComponent::can_erase_detail() const { void CanvasComponent::simplify_paths() { } +void CanvasComponent::normalize_object_coordinates(CoordSpaceHelper& coords) { +} + std::vector CanvasComponent::attempt_split(DrawingProgram& drawP) const { return {}; } CanvasComponentEraseDetailResult CanvasComponent::erase_detail(const SkPath& eraseAgainst) { diff --git a/src/CanvasComponents/CanvasComponent.hpp b/src/CanvasComponents/CanvasComponent.hpp index 64021e8..b79b59c 100644 --- a/src/CanvasComponents/CanvasComponent.hpp +++ b/src/CanvasComponents/CanvasComponent.hpp @@ -44,6 +44,7 @@ class CanvasComponent { virtual std::vector attempt_split(DrawingProgram& drawP) const; virtual void simplify_paths(); virtual std::optional get_stroke_color() const; + virtual void normalize_object_coordinates(CoordSpaceHelper& coords); virtual void set_data_from(const CanvasComponent& other) = 0; virtual std::unique_ptr get_data_copy() const = 0; diff --git a/src/CanvasComponents/CanvasComponentContainer.cpp b/src/CanvasComponents/CanvasComponentContainer.cpp index cc6fe8f..a0c738e 100644 --- a/src/CanvasComponents/CanvasComponentContainer.cpp +++ b/src/CanvasComponents/CanvasComponentContainer.cpp @@ -104,6 +104,12 @@ void CanvasComponentContainer::load_file(cereal::PortableBinaryInputArchive& a, compAllocator->comp->load_file(a, version); compAllocator->comp->compContainer = this; } + if(version < VersionNumber(0, 6, 0)) + normalize_object_coordinates(); +} + +void CanvasComponentContainer::normalize_object_coordinates() { + get_comp().normalize_object_coordinates(coords); } void CanvasComponentContainer::draw(SkCanvas* canvas, const DrawData& drawData) const { diff --git a/src/CanvasComponents/CanvasComponentContainer.hpp b/src/CanvasComponents/CanvasComponentContainer.hpp index 5d00a18..3198494 100644 --- a/src/CanvasComponents/CanvasComponentContainer.hpp +++ b/src/CanvasComponents/CanvasComponentContainer.hpp @@ -95,6 +95,7 @@ class CanvasComponentContainer { bool collides_with_point(const CoordSpaceHelper& camCoords, const Vector2f& checkAgainstCam) const; void send_comp_update(DrawingProgram& drawP, bool finalUpdate); void scale_up(const WorldScalar& scaleUpAmount); + void normalize_object_coordinates(); std::weak_ptr cacheParentBvhNode; DrawingProgramLayerListItem* parentLayer = nullptr; diff --git a/src/CanvasComponents/MeshCanvasComponent.cpp b/src/CanvasComponents/MeshCanvasComponent.cpp index 887c7cd..195647a 100644 --- a/src/CanvasComponents/MeshCanvasComponent.cpp +++ b/src/CanvasComponents/MeshCanvasComponent.cpp @@ -311,6 +311,26 @@ std::vector MeshCanvasComponent::attempt_split(Drawin return toRet; } +void MeshCanvasComponent::normalize_object_coordinates(CoordSpaceHelper& coords) { + SkRect pathBounds = d.meshPath.getBounds(); + SkPoint center = pathBounds.center(); + float maxDimScaleFactor = 1.0 / (std::max(pathBounds.width(), pathBounds.height()) * 0.5f); // Scale must be uniform. This scale factor should force the maximum coordinate = 1 after translation + SkMatrix m = SkMatrix::I(); + // Might not be in correct order. Translate to origin first, then scale to normalize coordinates + m.postTranslate(-center.x(), -center.y()).postScale(maxDimScaleFactor, maxDimScaleFactor); + std::optional tryTransformPath = d.meshPath.tryMakeTransform(m); + if(tryTransformPath) { + d.meshPath = tryTransformPath.value(); + //for(auto& p : d.meshPath.points()) + // std::cout << vec_pretty(convert_vec2(p)) << std::endl; + WorldVec newCenter = WorldVec{center.x(), center.y()} * coords.inverseScale; + newCenter = rotate_world_coord(newCenter, coords.rotation); + coords.translate(newCenter); + coords.scale_about_double(coords.pos, maxDimScaleFactor); + } + //std::cout << vec_pretty(convert_vec2(center)) << " " << coords.pos.x().display_int_str(3) << " " << coords.pos.y().display_int_str(3) << " " << coords.inverseScale << std::endl; +} + CanvasComponentEraseDetailResult MeshCanvasComponent::erase_detail(const SkPath& eraseAgainst) { bool intersectsAABB = d.meshPath.getBounds().intersects(eraseAgainst.getBounds()); if(!intersectsAABB) diff --git a/src/CanvasComponents/MeshCanvasComponent.hpp b/src/CanvasComponents/MeshCanvasComponent.hpp index 91171eb..941d96f 100644 --- a/src/CanvasComponents/MeshCanvasComponent.hpp +++ b/src/CanvasComponents/MeshCanvasComponent.hpp @@ -37,6 +37,7 @@ class MeshCanvasComponent : public CanvasComponent { virtual std::optional get_stroke_color() const override; virtual void set_data_from(const CanvasComponent& other) override; virtual void simplify_paths() override; + virtual void normalize_object_coordinates(CoordSpaceHelper& coords) override; struct Data { SkPath meshPath;