Skip to content

Commit

Permalink
Make difference operation combine paths if they do not intersect.
Browse files Browse the repository at this point in the history
  • Loading branch information
MaurycyLiebner committed Feb 22, 2021
1 parent dc3baa9 commit 9640387
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/core/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ class CORE_EXPORT Canvas : public CanvasBase {
qsptr<ColorAnimator> mBackgroundColor = enve::make_shared<ColorAnimator>();

SmartVectorPath *getPathResultingFromOperation(const SkPathOp &pathOp);
SmartVectorPath *getPathResultingFromCombine();

// void sortSelectedBoxesAsc();
void sortSelectedBoxesDesc();
Expand Down
78 changes: 51 additions & 27 deletions src/core/canvasselectedboxesactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,49 @@ SmartVectorPath *Canvas::getPathResultingFromOperation(const SkPathOp& pathOp) {
}
SkPath resultPath;
builder.resolve(&resultPath);
newPath->loadSkPath(resultPath);
if(resultPath.isEmpty()) {
return getPathResultingFromCombine();
} else {
newPath->loadSkPath(resultPath);
}
mCurrentContainer->addContained(newPath);
return newPath.get();
}

SmartVectorPath *Canvas::getPathResultingFromCombine() {
SmartVectorPath *newPath = nullptr;
for(const auto &box : mSelectedBoxes) {
if(const auto path = enve_cast<SmartVectorPath*>(box)) {
newPath = path;
break;
}
}
if(!newPath) {
const auto newPathT = enve::make_shared<SmartVectorPath>();
newPathT->planCenterPivotPosition();
mCurrentContainer->addContained(newPathT);
newPath = newPathT.get();
}

const auto targetVP = newPath->getPathAnimator();
const QMatrix firstTranf = newPath->getTotalTransform();
for(const auto &box : mSelectedBoxes) {
if(box == newPath) continue;
if(const auto boxPath = enve_cast<SmartVectorPath*>(box)) {
const QMatrix relTransf = boxPath->getTotalTransform()*
firstTranf.inverted();
const auto srcVP = boxPath->getPathAnimator();
srcVP->applyTransform(relTransf);
targetVP->moveAllFrom(srcVP);
box->removeFromParent_k();
}
}
return newPath;
}

void Canvas::selectedPathsDifference() {
if(mSelectedBoxes.isEmpty()) return;

SmartVectorPath * const newPath = getPathResultingFromOperation(
SkPathOp::kDifference_SkPathOp);

Expand All @@ -621,6 +658,8 @@ void Canvas::selectedPathsDifference() {
}

void Canvas::selectedPathsIntersection() {
if(mSelectedBoxes.isEmpty()) return;

SmartVectorPath * const newPath = getPathResultingFromOperation(
SkPathOp::kIntersect_SkPathOp);

Expand All @@ -629,6 +668,8 @@ void Canvas::selectedPathsIntersection() {
}

void Canvas::selectedPathsDivision() {
if(mSelectedBoxes.isEmpty()) return;

SmartVectorPath * const newPath1 = getPathResultingFromOperation(
SkPathOp::kDifference_SkPathOp);

Expand All @@ -641,6 +682,8 @@ void Canvas::selectedPathsDivision() {
}

void Canvas::selectedPathsExclusion() {
if(mSelectedBoxes.isEmpty()) return;

SmartVectorPath * const newPath1 = getPathResultingFromOperation(
SkPathOp::kDifference_SkPathOp);
SmartVectorPath * const newPath2 = getPathResultingFromOperation(
Expand All @@ -654,6 +697,7 @@ void Canvas::selectedPathsExclusion() {

void Canvas::selectedPathsBreakApart() {
if(mSelectedBoxes.isEmpty()) return;

QList<qsptr<SmartVectorPath>> created;
for(const auto &box : mSelectedBoxes) {
if(const auto path = enve_cast<SmartVectorPath*>(box)) {
Expand All @@ -667,6 +711,8 @@ void Canvas::selectedPathsBreakApart() {
}

void Canvas::selectedPathsUnion() {
if(mSelectedBoxes.isEmpty()) return;

SmartVectorPath * const newPath = getPathResultingFromOperation(
SkPathOp::kUnion_SkPathOp);

Expand All @@ -676,33 +722,11 @@ void Canvas::selectedPathsUnion() {

void Canvas::selectedPathsCombine() {
if(mSelectedBoxes.isEmpty()) return;
SmartVectorPath *firstVectorPath = nullptr;
for(const auto &box : mSelectedBoxes) {
if(const auto path = enve_cast<SmartVectorPath*>(box)) {
firstVectorPath = path;
break;
}
}
if(!firstVectorPath) {
const auto newPath = enve::make_shared<SmartVectorPath>();
newPath->planCenterPivotPosition();
mCurrentContainer->addContained(newPath);
firstVectorPath = newPath.get();
}

const auto targetVP = firstVectorPath->getPathAnimator();
const QMatrix firstTranf = firstVectorPath->getTotalTransform();
for(const auto &box : mSelectedBoxes) {
if(box == firstVectorPath) continue;
if(const auto boxPath = enve_cast<SmartVectorPath*>(box)) {
const QMatrix relTransf = boxPath->getTotalTransform()*
firstTranf.inverted();
const auto srcVP = boxPath->getPathAnimator();
srcVP->applyTransform(relTransf);
targetVP->moveAllFrom(srcVP);
box->removeFromParent_k();
}
}
SmartVectorPath * const newPath = getPathResultingFromCombine();

clearBoxesSelection();
addBoxToSelection(newPath);
}

void Canvas::alignSelectedBoxes(const Qt::Alignment align,
Expand Down

2 comments on commit 9640387

@AlexKiryanov
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I understood correctly what this commit is about, then this is what I noticed.
the diference operation has a problem by the way.
If the objects do not intersect with lines with each other, then the difference operation does not occur.
more precisely, sometimes it works with such figures.
image
image
but does not work with a circle or rectangle, even if translated into a path object
image
image

@AlexKiryanov
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

found a solution to this in commits) even-odd option)

Please sign in to comment.