Fixed path splitting making duplicates

This commit is contained in:
Yousef Khadadeh 2026-05-29 17:20:52 +03:00
parent 2c4a451195
commit d901597391
5 changed files with 15 additions and 54 deletions

View file

@ -68,48 +68,23 @@ bool clipper2_polygon_to_skpath_builder(SkPathBuilder& skPathBuilder, const Clip
return true;
}
void sort_clipper_polytreed_into_skpaths(std::vector<SkPath>& paths, const Clipper2Lib::PolyTreeD& tree) {
void sort_clipper_polytreed_into_skpaths_CHILD(std::vector<SkPath> &paths, const Clipper2Lib::PolyTreeD &tree) {
using namespace Clipper2Lib;
SkPathBuilder newPath;
if(!clipper2_polygon_to_skpath_builder(newPath, tree.Polygon()))
return;
for(auto& treeChild : tree) {
SkPathBuilder newPath;
if(!clipper2_polygon_to_skpath_builder(newPath, treeChild->Polygon()))
continue;
for(auto& child : *treeChild) {
if(child->IsHole()) {
clipper2_polygon_to_skpath_builder(newPath, child->Polygon());
for(auto& childChild : *child) {
if(childChild->IsHole())
continue;
else
sort_clipper_polytreed_into_skpaths(paths, *child);
}
}
else
sort_clipper_polytreed_into_skpaths(paths, *child);
}
paths.emplace_back(newPath.detach());
clipper2_polygon_to_skpath_builder(newPath, treeChild->Polygon());
for(auto& childChild : *treeChild)
sort_clipper_polytreed_into_skpaths_CHILD(paths, *childChild);
}
paths.emplace_back(newPath.detach());
}
void sort_clipper_polytreed_into_skpath_builder(SkPathBuilder& skPathBuilder, const Clipper2Lib::PolyTreeD& tree) {
void sort_clipper_polytreed_into_skpaths(std::vector<SkPath>& paths, const Clipper2Lib::PolyTreeD& tree) {
using namespace Clipper2Lib;
for(auto& treeChild : tree) {
if(!clipper2_polygon_to_skpath_builder(skPathBuilder, treeChild->Polygon()))
continue;
for(auto& child : *treeChild) {
if(child->IsHole()) {
clipper2_polygon_to_skpath_builder(skPathBuilder, child->Polygon());
for(auto& childChild : *child) {
if(childChild->IsHole())
continue;
else
sort_clipper_polytreed_into_skpath_builder(skPathBuilder, *child);
}
}
else
sort_clipper_polytreed_into_skpath_builder(skPathBuilder, *child);
}
}
for(auto& treeChild : tree)
sort_clipper_polytreed_into_skpaths_CHILD(paths, *treeChild);
}
void clipper2_polygons_to_skpath_builder(SkPathBuilder& skPathBuilder, const Clipper2Lib::PathsD& clipperPath) {

View file

@ -151,7 +151,7 @@ void CanvasComponentContainer::commit_transform_dont_invalidate_cache() {
CanvasComponentEraseDetailResult CanvasComponentContainer::collides_with_erase_detail(const CoordSpaceHelper& camCoords, const SkPath& checkAgainstCam) const {
if(!worldAABB.has_value())
return CanvasComponentEraseDetailResult::NO_CHANGE;
if((camCoords.inverseScale << COMP_MAX_SHIFT_BEFORE_STOP_COLLISIONS) < coords.inverseScale) // Object is too large, just dismiss the collision
if((camCoords.inverseScale << COMP_MAX_SHIFT_BEFORE_STOP_ERASE) < coords.inverseScale) // Object is too large, just dismiss the collision
return CanvasComponentEraseDetailResult::NO_CHANGE;
else if(coords.inverseScale < (camCoords.inverseScale >> COMP_COLLIDE_MIN_SHIFT_TINY)) {
if(checkAgainstCam.contains(convert_vec2<SkPoint>(camCoords.to_space(worldAABB.value().min))))
@ -212,7 +212,7 @@ void CanvasComponentContainer::canvas_do_transform(SkCanvas* canvas, const Trans
}
bool CanvasComponentContainer::should_draw(const DrawData& drawData) const {
return (!drawData.clampDrawBetween || (drawData.clampDrawMinimum < coords.inverseScale)) && worldAABB.has_value() && SCollision::collide(worldAABB.value(), drawData.cam.viewingAreaGenerousCollider) && get_comp().should_draw_extra(drawData, coords);
return (drawData.clampDrawMinimum < coords.inverseScale) && worldAABB.has_value() && SCollision::collide(worldAABB.value(), drawData.cam.viewingAreaGenerousCollider) && get_comp().should_draw_extra(drawData, coords);
}
CanvasComponentContainer::PreDrawData CanvasComponentContainer::calculate_predraw_data(const DrawData& drawData) const {
@ -238,15 +238,6 @@ void CanvasComponentContainer::scale_up(const WorldScalar& scaleUpAmount) {
calculate_world_bounds();
}
unsigned CanvasComponentContainer::get_mipmap_level(const DrawData& drawData) const {
if(drawData.mipMapLevelTwo > coords.inverseScale)
return 2;
else if(drawData.mipMapLevelOne > coords.inverseScale)
return 1;
else
return 0;
}
void CanvasComponentContainer::calculate_world_bounds() {
worldAABB = coords.collider_to_world<SCollision::AABB<WorldScalar>, SCollision::AABB<float>>(get_comp().get_obj_coord_bounds());
WorldVec dim = worldAABB.value().dim();

View file

@ -44,6 +44,7 @@ class CanvasComponentContainer {
typedef NetworkingObjects::NetObjOrderedListObjectInfo<CanvasComponentContainer> ObjInfo;
typedef NetworkingObjects::NetObjOrderedListIterator<CanvasComponentContainer> ObjInfoIterator;
constexpr static int COMP_MAX_SHIFT_BEFORE_STOP_ERASE = 7;
constexpr static int COMP_MAX_SHIFT_BEFORE_STOP_COLLISIONS = 14;
constexpr static int COMP_MAX_SHIFT_BEFORE_STOP_SCALING = 14;
constexpr static float COMP_MAX_BEFORE_STOP_SCALING = 1 << COMP_MAX_SHIFT_BEFORE_STOP_SCALING;
@ -107,10 +108,10 @@ class CanvasComponentContainer {
static void write_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<CanvasComponentContainer>& o, cereal::PortableBinaryOutputArchive& a);
unsigned get_mipmap_level(const DrawData& drawData) const;
CanvasComponent* allocate_comp(CanvasComponentType type);
void calculate_world_bounds();
std::optional<SCollision::AABB<WorldScalar>> worldAABB;
NetworkingObjects::NetObjOwnerPtr<CanvasComponentAllocator> compAllocator;
};

View file

@ -20,8 +20,5 @@
#include "CanvasComponents/CanvasComponentContainer.hpp"
void DrawData::refresh_draw_optimizing_values() {
clampDrawBetween = true;
clampDrawMinimum = cam.c.inverseScale >> CanvasComponentContainer::COMP_MIN_SHIFT_BEFORE_DISAPPEAR;
mipMapLevelOne = cam.c.inverseScale >> CanvasComponentContainer::COMP_MIPMAP_LEVEL_ONE;
mipMapLevelTwo = cam.c.inverseScale >> CanvasComponentContainer::COMP_MIPMAP_LEVEL_TWO;
}

View file

@ -32,12 +32,9 @@ struct DrawData {
MainProgram* main;
bool takingScreenshot = false;
bool isSVGRender = false;
bool clampDrawBetween = true;
bool drawGrids = true;
bool transparentBackground = false;
bool skiaAA = false;
WorldScalar clampDrawMinimum;
WorldScalar mipMapLevelOne;
WorldScalar mipMapLevelTwo;
void refresh_draw_optimizing_values();
};