mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Add selfInters
This commit is contained in:
@ -758,12 +758,26 @@ CGraphicsPath&& CBooleanOperations::GetResult()
|
|||||||
return std::move(Result);
|
return std::move(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CBooleanOperations::IsSelfInters(const CGraphicsPath& p)
|
||||||
|
{
|
||||||
|
PreparePath(p, 1, Segments1, Curves1);
|
||||||
|
PreparePath(p, 2, Segments2, Curves2);
|
||||||
|
|
||||||
|
OriginCurves1 = Curves1;
|
||||||
|
OriginCurves2 = Curves2;
|
||||||
|
|
||||||
|
GetIntersection();
|
||||||
|
|
||||||
|
return !Locations.empty();
|
||||||
|
}
|
||||||
|
|
||||||
void CBooleanOperations::TraceBoolean()
|
void CBooleanOperations::TraceBoolean()
|
||||||
{
|
{
|
||||||
bool reverse = false;
|
bool reverse = false;
|
||||||
if ((Op == Subtraction || Op == Exclusion) ^
|
bool self = Path1 == Path2;
|
||||||
Path1.IsClockwise() ^
|
if (((Op == Subtraction || Op == Exclusion) ^
|
||||||
Path2.IsClockwise())
|
Path1.IsClockwise() ^
|
||||||
|
Path2.IsClockwise()) && !self)
|
||||||
reverse = true;
|
reverse = true;
|
||||||
|
|
||||||
PreparePath(Path1, 1, Segments1, Curves1);
|
PreparePath(Path1, 1, Segments1, Curves1);
|
||||||
@ -774,6 +788,32 @@ void CBooleanOperations::TraceBoolean()
|
|||||||
|
|
||||||
GetIntersection();
|
GetIntersection();
|
||||||
|
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
if (Op == Subtraction)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::vector<int>> adj_matr(Locations.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < Locations.size(); i++)
|
||||||
|
{
|
||||||
|
std::vector<int> adj_vec;
|
||||||
|
|
||||||
|
if (CheckLocation(Locations[i], true))
|
||||||
|
adj_vec.push_back(Locations[i]->C.Segment1.Index);
|
||||||
|
if (CheckLocation(Locations[i], false))
|
||||||
|
adj_vec.push_back(Locations[i]->C.Segment2.Index);
|
||||||
|
if (CheckLocation(Locations[i]->Inters, true))
|
||||||
|
adj_vec.push_back(Locations[i]->Inters->C.Segment1.Index);
|
||||||
|
if (CheckLocation(Locations[i]->Inters, false))
|
||||||
|
adj_vec.push_back(Locations[i]->Inters->C.Segment2.Index);
|
||||||
|
adj_matr[i] = adj_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateNewPath(adj_matr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!Locations.empty())
|
if (!Locations.empty())
|
||||||
{
|
{
|
||||||
int length = static_cast<int>(Locations.size());
|
int length = static_cast<int>(Locations.size());
|
||||||
@ -1357,6 +1397,218 @@ void CBooleanOperations::SetVisited(const Segment& segment)
|
|||||||
Segments2[segment.Index].Visited = true;
|
Segments2[segment.Index].Visited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBooleanOperations::CreateNewPath(const std::vector<std::vector<int>>& adjMatr) noexcept
|
||||||
|
{
|
||||||
|
int* loc_visited = new int[Locations.size()];
|
||||||
|
memset(loc_visited, false, Locations.size());
|
||||||
|
bool* seg_visited = new bool[Segments1.size()];
|
||||||
|
memset(seg_visited, false, Segments1.size());
|
||||||
|
|
||||||
|
Result.StartFigure();
|
||||||
|
for (int i = 0; i < Locations.size(); i++)
|
||||||
|
{
|
||||||
|
auto loc = Locations[i];
|
||||||
|
if (loc_visited[i] == 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool finish = true;
|
||||||
|
for (size_t j = 0; j < Segments1.size(); j++)
|
||||||
|
finish = finish && seg_visited[j];
|
||||||
|
|
||||||
|
if (finish)
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto add_seg = [&](int x, int prev_x) {
|
||||||
|
for (size_t j = adjMatr[x].size() - 1; j >= 0; j--)
|
||||||
|
{
|
||||||
|
int ver = adjMatr[x][j];
|
||||||
|
if (seg_visited[ver] || ver == prev_x)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
seg_visited[ver] = true;
|
||||||
|
if (Segments1[ver].IsCurve)
|
||||||
|
{
|
||||||
|
Segment seg;
|
||||||
|
auto curve = Curves1[ver];
|
||||||
|
auto curve1 = Curves1[ver == 0 ? Curves1.size() - 1 : ver - 1];
|
||||||
|
if (curve.Segment2.Index == Locations[x]->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
auto new_curve = curve.DivideAtTime(Locations[x]->Time);
|
||||||
|
seg = new_curve.Segment1;
|
||||||
|
}
|
||||||
|
if (curve.Segment2.Index == Locations[x]->Inters->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
auto new_curve = curve.DivideAtTime(Locations[x]->Inters->Time);
|
||||||
|
seg = new_curve.Segment1;
|
||||||
|
}
|
||||||
|
if (curve1.Segment2.Index == Locations[x]->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
auto new_curve = curve1.DivideAtTime(Locations[x]->Time);
|
||||||
|
seg = new_curve.Segment2;
|
||||||
|
}
|
||||||
|
if (curve1.Segment2.Index == Locations[x]->Inters->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
auto new_curve = curve1.DivideAtTime(Locations[x]->Inters->Time);
|
||||||
|
seg = new_curve.Segment2;
|
||||||
|
}
|
||||||
|
Result.CurveTo(seg.HI.X + seg.P.X, seg.HI.Y + seg.P.Y,
|
||||||
|
seg.HO.X + seg.P.X, seg.HO.Y + seg.P.Y,
|
||||||
|
seg.P.X, seg.P.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Result.LineTo(Segments1[ver].P.X, Segments1[ver].P.Y);
|
||||||
|
|
||||||
|
return ver;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto add_loc = [&](int x, int prev_x) {
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < adjMatr.size(); j++)
|
||||||
|
{
|
||||||
|
if (std::find(adjMatr[j].begin(), adjMatr[j].end(), x) != adjMatr[j].end())
|
||||||
|
{
|
||||||
|
if (loc_visited[j] == 2 || j == prev_x)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (j != i)
|
||||||
|
loc_visited[j]++;
|
||||||
|
auto ll = Locations[j];
|
||||||
|
Curve curve;
|
||||||
|
double t;
|
||||||
|
if ((x == Curves1.size() - 1 ? 0 : x + 1) == ll->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
curve = Curves1[x];
|
||||||
|
t = ll->Time;
|
||||||
|
}
|
||||||
|
if ((x == Curves1.size() - 1 ? 0 : x + 1) == ll->Inters->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
curve = Curves1[x];
|
||||||
|
t = ll->Inters->Time;
|
||||||
|
}
|
||||||
|
if (x == ll->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
curve = Curves1[x == 0 ? Curves1.size() - 1 : x - 1];
|
||||||
|
t = ll->Time;
|
||||||
|
}
|
||||||
|
if (x == ll->Inters->C.Segment2.Index)
|
||||||
|
{
|
||||||
|
curve = Curves1[x == 0 ? Curves1.size() - 1 : x - 1];
|
||||||
|
t = ll->Inters->Time;
|
||||||
|
}
|
||||||
|
if (curve.Segment2.IsCurve)
|
||||||
|
{
|
||||||
|
auto new_curve = curve.DivideAtTime(t);
|
||||||
|
Result.CurveTo(new_curve.Segment1.HI.X + new_curve.Segment1.P.X, new_curve.Segment1.HI.Y + new_curve.Segment1.P.Y,
|
||||||
|
new_curve.Segment1.HO.X + new_curve.Segment1.P.X, new_curve.Segment1.HO.Y + new_curve.Segment1.P.Y,
|
||||||
|
new_curve.Segment1.P.X, new_curve.Segment1.P.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto pt = curve.GetPoint(t);
|
||||||
|
Result.LineTo(pt.X, pt.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x = x + 1;
|
||||||
|
prev_x = -1;
|
||||||
|
if (Curves1[x].Segment2.IsCurve)
|
||||||
|
Result.CurveTo(Curves1[x].Segment2.HI.X + Curves1[x].Segment2.P.X, Curves1[x].Segment2.HI.Y + Curves1[x].Segment2.P.Y,
|
||||||
|
Curves1[x].Segment2.HO.X + Curves1[x].Segment2.P.X, Curves1[x].Segment2.HO.Y + Curves1[x].Segment2.P.Y,
|
||||||
|
Curves1[x].Segment2.P.X, Curves1[x].Segment2.P.Y);
|
||||||
|
else
|
||||||
|
Result.LineTo(Curves1[x].Segment2.P.X, Curves1[x].Segment2.P.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
loc_visited[i]++;
|
||||||
|
auto p = loc->C.GetPoint(loc->Time);
|
||||||
|
Result.MoveTo(p.X, p.Y);
|
||||||
|
int cur_seg = -1;
|
||||||
|
int cur_loc = i;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
cur_seg = add_seg(cur_loc, cur_seg);
|
||||||
|
if (cur_seg == -1)
|
||||||
|
break;
|
||||||
|
cur_loc = add_loc(cur_seg, cur_loc);
|
||||||
|
if (cur_loc == i || cur_loc == -1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < Locations.size(); i++)
|
||||||
|
{
|
||||||
|
if (loc_visited[i] != 2)
|
||||||
|
{
|
||||||
|
loc_visited[i]++;
|
||||||
|
auto p = Locations[i]->C.GetPoint(Locations[i]->Time);
|
||||||
|
Result.MoveTo(p.X, p.Y);
|
||||||
|
auto prev_loc = Locations[i];
|
||||||
|
|
||||||
|
auto add_loc = [&](std::shared_ptr<Location> l1, std::shared_ptr<Location> l2) {
|
||||||
|
auto add_pt = [&](std::shared_ptr<Location> lc, std::shared_ptr<Location> prev){
|
||||||
|
if (prev->C.Segment2.IsCurve)
|
||||||
|
{
|
||||||
|
auto new_curve = prev->C;
|
||||||
|
double t1 = prev->Time;
|
||||||
|
double t2 = lc->Time;
|
||||||
|
if (t2 < t1)
|
||||||
|
{
|
||||||
|
new_curve.Flip();
|
||||||
|
t1 = 1.0 - t1;
|
||||||
|
t2 = 1.0 - t2;
|
||||||
|
}
|
||||||
|
new_curve = new_curve.DivideAtTime(t1);
|
||||||
|
new_curve = new_curve.DivideAtTime((t2 - t1) / (1.0 - t1));
|
||||||
|
|
||||||
|
Result.CurveTo(new_curve.Segment1.HI.X + new_curve.Segment1.P.X, new_curve.Segment1.HI.Y + new_curve.Segment1.P.Y,
|
||||||
|
new_curve.Segment1.HO.X + new_curve.Segment1.P.X, new_curve.Segment1.HO.Y + new_curve.Segment1.P.Y,
|
||||||
|
new_curve.Segment1.P.X, new_curve.Segment1.P.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto pt = lc->C.GetPoint(lc->Time);
|
||||||
|
Result.LineTo(pt.X, pt.Y);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (l1->C.Segment2.Index == l2->C.Segment2.Index)
|
||||||
|
add_pt(l1, l2);
|
||||||
|
else if (l1->C.Segment2.Index == l2->Inters->C.Segment2.Index)
|
||||||
|
add_pt(l1, l2->Inters);
|
||||||
|
else if (l1->Inters->C.Segment2.Index == l2->C.Segment2.Index)
|
||||||
|
add_pt(l1->Inters, l2);
|
||||||
|
else if (l1->Inters->C.Segment2.Index == l2->Inters->C.Segment2.Index)
|
||||||
|
add_pt(l1->Inters, l2->Inters);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int j = i + 1; j < Locations.size(); j++)
|
||||||
|
{
|
||||||
|
if (loc_visited[j] == 2)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
loc_visited[j]++;
|
||||||
|
add_loc(Locations[j], prev_loc);
|
||||||
|
prev_loc = Locations[j];
|
||||||
|
}
|
||||||
|
add_loc(Locations[i], prev_loc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Result.CloseFigure();
|
||||||
|
|
||||||
|
delete[] seg_visited;
|
||||||
|
delete[] loc_visited;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::vector<int>> CBooleanOperations::FindBoundsCollisions()
|
std::vector<std::vector<int>> CBooleanOperations::FindBoundsCollisions()
|
||||||
{
|
{
|
||||||
std::vector<std::vector<double>> allBounds, bounds2;
|
std::vector<std::vector<double>> allBounds, bounds2;
|
||||||
@ -1400,13 +1652,14 @@ std::vector<std::vector<int>> CBooleanOperations::FindBoundsCollisions()
|
|||||||
|
|
||||||
activeIndicesByPri2.erase(activeIndicesByPri2.begin(),
|
activeIndicesByPri2.erase(activeIndicesByPri2.begin(),
|
||||||
activeIndicesByPri2.begin() + pruneCount);
|
activeIndicesByPri2.begin() + pruneCount);
|
||||||
|
|
||||||
for (int j = 0; j < static_cast<int>(activeIndicesByPri2.size()); j++)
|
for (int j = 0; j < static_cast<int>(activeIndicesByPri2.size()); j++)
|
||||||
{
|
{
|
||||||
bool isActive1 = activeIndicesByPri2[j] < length1,
|
bool isActive1 = activeIndicesByPri2[j] < length1,
|
||||||
isActive2 = self || !isActive1,
|
isActive2 = self || !isActive1,
|
||||||
isActive1Or2 = (isCurrent1 && isActive2) || (isCurrent2 && isActive1),
|
isActive1Or2 = (isCurrent1 && isActive2) || (isCurrent2 && isActive1),
|
||||||
inRange1 = allBounds[allIdicesByPri1[i]][1] <= allBounds[activeIndicesByPri2[j]][3] + GEOMETRIC_EPSILON,
|
inRange1 = allBounds[allIdicesByPri1[i]][1] <= allBounds[activeIndicesByPri2[j]][3] + GEOMETRIC_EPSILON,
|
||||||
inRange2 = allBounds[allIdicesByPri1[i]][3] >= allBounds[activeIndicesByPri2[j]][1] - GEOMETRIC_EPSILON;
|
inRange2 = allBounds[allIdicesByPri1[i]][3] >= allBounds[activeIndicesByPri2[j]][1] - GEOMETRIC_EPSILON;
|
||||||
|
|
||||||
if (isActive1Or2 && (inRange2 && inRange1))
|
if (isActive1Or2 && (inRange2 && inRange1))
|
||||||
{
|
{
|
||||||
@ -1418,10 +1671,7 @@ std::vector<std::vector<int>> CBooleanOperations::FindBoundsCollisions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isCurrent1)
|
if (isCurrent1)
|
||||||
{
|
|
||||||
if (self) curCollisions.push_back(allIdicesByPri1[i]);
|
|
||||||
allCollisions[allIdicesByPri1[i]] = curCollisions;
|
allCollisions[allIdicesByPri1[i]] = curCollisions;
|
||||||
}
|
|
||||||
if (activeIndicesByPri2.size() > 0)
|
if (activeIndicesByPri2.size() > 0)
|
||||||
{
|
{
|
||||||
int index = 1 + binarySearch(allBounds, activeIndicesByPri2, 2, allBounds[allIdicesByPri1[i]][2]);
|
int index = 1 + binarySearch(allBounds, activeIndicesByPri2, 2, allBounds[allIdicesByPri1[i]][2]);
|
||||||
@ -1431,8 +1681,23 @@ std::vector<std::vector<int>> CBooleanOperations::FindBoundsCollisions()
|
|||||||
activeIndicesByPri2.push_back(allIdicesByPri1[i]);
|
activeIndicesByPri2.push_back(allIdicesByPri1[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
std::vector<std::vector<int>> erase_ver(length1);
|
||||||
for (auto& c : allCollisions)
|
for (auto& c : allCollisions)
|
||||||
|
{
|
||||||
std::sort(c.begin(), c.end());
|
std::sort(c.begin(), c.end());
|
||||||
|
if (self)
|
||||||
|
{
|
||||||
|
c.erase(std::remove(c.begin(), c.end(), index), c.end());
|
||||||
|
c.erase(std::remove(c.begin(), c.end(), index == allLength - 1 ? 0 : index + 1), c.end());
|
||||||
|
c.erase(std::remove(c.begin(), c.end(), index == 0 ? allLength - 1 : index - 1), c.end());
|
||||||
|
for (const auto& ind : erase_ver[index])
|
||||||
|
c.erase(std::remove(c.begin(), c.end(), ind), c.end());
|
||||||
|
for (const auto& ind : c)
|
||||||
|
erase_ver[ind].push_back(index);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
return allCollisions;
|
return allCollisions;
|
||||||
}
|
}
|
||||||
@ -2038,6 +2303,29 @@ void CBooleanOperations::AddOffsets(std::vector<double>& offsets,
|
|||||||
offsets.push_back(count != 0 ? offset : offset / 32);
|
offsets.push_back(count != 0 ? offset : offset / 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CBooleanOperations::CheckLocation(std::shared_ptr<Location> loc, bool start) const noexcept
|
||||||
|
{
|
||||||
|
for (const auto& l : Locations)
|
||||||
|
{
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
if (l->C.Segment1.Index == loc->C.Segment1.Index && l->Time != loc->Time)
|
||||||
|
return loc->Time < l->Time;
|
||||||
|
if (l->Inters->C.Segment1.Index == loc->C.Segment1.Index && l->Inters->Time != loc->Time)
|
||||||
|
return loc->Time < l->Inters->Time;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (l->C.Segment2.Index == loc->C.Segment2.Index && l->Time != loc->Time)
|
||||||
|
return loc->Time > l->Time;
|
||||||
|
if (l->Inters->C.Segment2.Index == loc->C.Segment2.Index && l->Inters->Time != loc->Time)
|
||||||
|
return loc->Time > l->Inters->Time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1,
|
CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1,
|
||||||
const CGraphicsPath& path2,
|
const CGraphicsPath& path2,
|
||||||
BooleanOpType op,
|
BooleanOpType op,
|
||||||
@ -2048,30 +2336,42 @@ CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1,
|
|||||||
paths2 = path2.GetSubPaths(),
|
paths2 = path2.GetSubPaths(),
|
||||||
paths;
|
paths;
|
||||||
|
|
||||||
if (op == Subtraction)
|
for (size_t i = 0; i < paths2.size(); i++)
|
||||||
{
|
{
|
||||||
for (const auto& p2 : paths2)
|
if (CBooleanOperations o; o.IsSelfInters(paths2[i]))
|
||||||
{
|
{
|
||||||
for (const auto& p1 : paths1)
|
CBooleanOperations operation(paths2[i], paths2[i], Intersection, fillType, isLuminosity);
|
||||||
|
CGraphicsPath p = std::move(operation.GetResult());
|
||||||
|
|
||||||
|
std::vector<CGraphicsPath> tmp_paths = p.GetSubPaths();
|
||||||
|
paths2[i] = tmp_paths[0];
|
||||||
|
for (size_t k = 1; k < tmp_paths.size(); k++)
|
||||||
|
paths2.insert(paths2.begin() + i + k, tmp_paths[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < paths1.size(); j++)
|
||||||
|
{
|
||||||
|
if (CBooleanOperations o; o.IsSelfInters(paths1[j]))
|
||||||
{
|
{
|
||||||
CBooleanOperations operation(p1, p2, op, fillType, isLuminosity);
|
CBooleanOperations operation(paths1[j], paths1[j], Intersection, fillType, isLuminosity);
|
||||||
paths.push_back(operation.GetResult());
|
CGraphicsPath p = std::move(operation.GetResult());
|
||||||
|
|
||||||
|
std::vector<CGraphicsPath> tmp_paths = p.GetSubPaths();
|
||||||
|
paths1[j] = tmp_paths[0];
|
||||||
|
for (size_t k = 1; k < tmp_paths.size(); k++)
|
||||||
|
paths1.insert(paths1.begin() + i + k, tmp_paths[k]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CBooleanOperations operation(paths1[j], paths2[i], op, fillType, isLuminosity);
|
||||||
|
paths.push_back(operation.GetResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op == Subtraction)
|
||||||
|
{
|
||||||
paths1 = CGraphicsPath(paths).GetSubPaths();
|
paths1 = CGraphicsPath(paths).GetSubPaths();
|
||||||
paths.clear();
|
paths.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
for (const auto& p1 : paths1)
|
|
||||||
{
|
|
||||||
for (const auto& p2 : paths2)
|
|
||||||
{
|
|
||||||
CBooleanOperations operation(p1, p2, op, fillType, isLuminosity);
|
|
||||||
paths.push_back(operation.GetResult());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return op == Subtraction ? CGraphicsPath(paths1) : CGraphicsPath(paths);
|
return op == Subtraction ? CGraphicsPath(paths1) : CGraphicsPath(paths);
|
||||||
}
|
}
|
||||||
@ -2080,7 +2380,7 @@ CGraphicsPath CalcBooleanOperation(const CGraphicsPath& path1,
|
|||||||
bool CGraphicsPath::operator==(const CGraphicsPath& other) noexcept
|
bool CGraphicsPath::operator==(const CGraphicsPath& other) noexcept
|
||||||
{
|
{
|
||||||
unsigned pointsCount = GetPointCount(),
|
unsigned pointsCount = GetPointCount(),
|
||||||
otherPointsCount = other.GetPointCount();
|
otherPointsCount = other.GetPointCount();
|
||||||
|
|
||||||
if (pointsCount != otherPointsCount)
|
if (pointsCount != otherPointsCount)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -107,9 +107,11 @@ namespace Aggplus
|
|||||||
class CBooleanOperations
|
class CBooleanOperations
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
CBooleanOperations() {};
|
||||||
CBooleanOperations(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op, long fillType, bool isLuminosity);
|
CBooleanOperations(const CGraphicsPath& path1, const CGraphicsPath& path2, BooleanOpType op, long fillType, bool isLuminosity);
|
||||||
~CBooleanOperations();
|
~CBooleanOperations();
|
||||||
CGraphicsPath&& GetResult();
|
CGraphicsPath&& GetResult();
|
||||||
|
bool IsSelfInters(const CGraphicsPath& p);
|
||||||
|
|
||||||
// BooleanOp
|
// BooleanOp
|
||||||
void TraceBoolean();
|
void TraceBoolean();
|
||||||
@ -129,6 +131,7 @@ namespace Aggplus
|
|||||||
Segment GetPreviousSegment(const Segment& segment) const noexcept;
|
Segment GetPreviousSegment(const Segment& segment) const noexcept;
|
||||||
Segment GetNextSegment(const Segment& segment) const noexcept;
|
Segment GetNextSegment(const Segment& segment) const noexcept;
|
||||||
void SetVisited(const Segment& segment);
|
void SetVisited(const Segment& segment);
|
||||||
|
void CreateNewPath(const std::vector<std::vector<int>>& adjMatr) noexcept;
|
||||||
|
|
||||||
// Bounds
|
// Bounds
|
||||||
std::vector<std::vector<int>> FindBoundsCollisions();
|
std::vector<std::vector<int>> FindBoundsCollisions();
|
||||||
@ -155,6 +158,7 @@ namespace Aggplus
|
|||||||
bool AllInters(const std::vector<Segment>& segments) const noexcept;
|
bool AllInters(const std::vector<Segment>& segments) const noexcept;
|
||||||
bool IsOneCurvePath(int pathIndex) const noexcept;
|
bool IsOneCurvePath(int pathIndex) const noexcept;
|
||||||
void AddOffsets(std::vector<double>& offsets, const Curve& curve, bool end);
|
void AddOffsets(std::vector<double>& offsets, const Curve& curve, bool end);
|
||||||
|
bool CheckLocation(std::shared_ptr<Location> loc, bool start) const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BooleanOpType Op = Intersection;
|
BooleanOpType Op = Intersection;
|
||||||
@ -166,9 +170,9 @@ namespace Aggplus
|
|||||||
// c_nStroke, c_nWindingFillMode, c_nEvenOddFillMode
|
// c_nStroke, c_nWindingFillMode, c_nEvenOddFillMode
|
||||||
long FillType = c_nWindingFillMode;
|
long FillType = c_nWindingFillMode;
|
||||||
|
|
||||||
CGraphicsPath Path1;
|
CGraphicsPath Path1{};
|
||||||
CGraphicsPath Path2;
|
CGraphicsPath Path2{};
|
||||||
CGraphicsPath Result;
|
CGraphicsPath Result{};
|
||||||
|
|
||||||
std::vector<Segment> Segments1;
|
std::vector<Segment> Segments1;
|
||||||
std::vector<Segment> Segments2;
|
std::vector<Segment> Segments2;
|
||||||
|
|||||||
Reference in New Issue
Block a user