|
|
@ -567,7 +567,7 @@ bool UBGraphicsScene::inputDeviceRelease() |
|
|
|
} |
|
|
|
} |
|
|
|
}else if (mCurrentStroke) |
|
|
|
}else if (mCurrentStroke) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if(eDrawingMode_Vector == dc->drawingMode()){ |
|
|
|
if(eDrawingMode_Vector == DRAWING_MODE){ |
|
|
|
UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup(); |
|
|
|
UBGraphicsStrokesGroup* pStrokes = new UBGraphicsStrokesGroup(); |
|
|
|
|
|
|
|
|
|
|
|
// Remove the strokes that were just drawn here and replace them by a stroke item
|
|
|
|
// Remove the strokes that were just drawn here and replace them by a stroke item
|
|
|
@ -575,6 +575,7 @@ bool UBGraphicsScene::inputDeviceRelease() |
|
|
|
mPreviousPolygonItems.removeAll(poly); |
|
|
|
mPreviousPolygonItems.removeAll(poly); |
|
|
|
removeItem(poly); |
|
|
|
removeItem(poly); |
|
|
|
UBCoreGraphicsScene::removeItemFromDeletion(poly); |
|
|
|
UBCoreGraphicsScene::removeItemFromDeletion(poly); |
|
|
|
|
|
|
|
poly->setStrokesGroup(pStrokes); |
|
|
|
pStrokes->addToGroup(poly); |
|
|
|
pStrokes->addToGroup(poly); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -756,114 +757,169 @@ void UBGraphicsScene::eraseLineTo(const QPointF &pEndPoint, const qreal &pWidth) |
|
|
|
eraserPathVar.addPolygon(eraserPolygon); |
|
|
|
eraserPathVar.addPolygon(eraserPolygon); |
|
|
|
const QPainterPath eraserPath = eraserPathVar; |
|
|
|
const QPainterPath eraserPath = eraserPathVar; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get all the items that are intersecting with the eraser path
|
|
|
|
QList<QGraphicsItem*> collidItems = items(eraserBoundingRect, Qt::IntersectsItemBoundingRect); |
|
|
|
QList<QGraphicsItem*> collidItems = items(eraserBoundingRect, Qt::IntersectsItemBoundingRect); |
|
|
|
|
|
|
|
|
|
|
|
QSet<QGraphicsItem*> toBeAddedItems; |
|
|
|
if(eDrawingMode_Vector == UBDrawingController::drawingController()->drawingMode()){ |
|
|
|
QSet<QGraphicsItem*> toBeRemovedItems; |
|
|
|
// NOTE: I decided to reuse the 'artistic' eraser all the time in order to have a better eraser
|
|
|
|
|
|
|
|
// For this reason, the following code is not used but we will keep it for now, in case of
|
|
|
|
int collidItemsSize = collidItems.size(); |
|
|
|
// futur requirements.
|
|
|
|
|
|
|
|
foreach(QGraphicsItem* poly, collidItems){ |
|
|
|
|
|
|
|
UBGraphicsStrokesGroup* pGroup = dynamic_cast<UBGraphicsStrokesGroup*>(poly); |
|
|
|
|
|
|
|
if(NULL != pGroup){ |
|
|
|
|
|
|
|
// TODO: Ungroup the item, put back the polygons on the scene, deal with the
|
|
|
|
|
|
|
|
// eraser's bounding rect, remove the polygons that must be removed
|
|
|
|
|
|
|
|
// then create new groups.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Get all substrokes and verify if they are part of the eraserpath then deal with it
|
|
|
|
|
|
|
|
foreach(QGraphicsItem* item, poly->childItems()){ |
|
|
|
|
|
|
|
UBGraphicsPolygonItem* polygon = dynamic_cast<UBGraphicsPolygonItem*>(item); |
|
|
|
|
|
|
|
if(NULL != polygon){ |
|
|
|
|
|
|
|
if(eraserBoundingRect.intersects(polygon->boundingRect())){ |
|
|
|
|
|
|
|
pGroup->removeFromGroup(polygon); |
|
|
|
|
|
|
|
removeItem(polygon); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
toBeAddedItems.reserve(collidItemsSize); |
|
|
|
}else{ |
|
|
|
toBeRemovedItems.reserve(collidItemsSize); |
|
|
|
QSet<QGraphicsItem*> toBeAddedItems; |
|
|
|
|
|
|
|
QSet<QGraphicsItem*> toBeRemovedItems; |
|
|
|
|
|
|
|
int collidItemsSize = collidItems.size(); |
|
|
|
|
|
|
|
toBeAddedItems.reserve(collidItemsSize); |
|
|
|
|
|
|
|
toBeRemovedItems.reserve(collidItemsSize); |
|
|
|
|
|
|
|
|
|
|
|
if (mShouldUseOMP) |
|
|
|
if (mShouldUseOMP) |
|
|
|
{ |
|
|
|
|
|
|
|
#pragma omp parallel for |
|
|
|
|
|
|
|
for (int i = 0; i < collidItemsSize; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
UBGraphicsPolygonItem *collidingPolygonItem |
|
|
|
#pragma omp parallel for |
|
|
|
= qgraphicsitem_cast<UBGraphicsPolygonItem*> (collidItems.at(i)); |
|
|
|
for (int i = 0; i < collidItemsSize; i++) |
|
|
|
|
|
|
|
|
|
|
|
if (collidingPolygonItem) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) |
|
|
|
UBGraphicsPolygonItem *collidingPolygonItem = dynamic_cast<UBGraphicsPolygonItem*>(collidItems.at(i)); |
|
|
|
{ |
|
|
|
|
|
|
|
#pragma omp critical |
|
|
|
|
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QPolygonF collidingPolygon = collidingPolygonItem->polygon(); |
|
|
|
|
|
|
|
QPainterPath collidingPath; |
|
|
|
|
|
|
|
collidingPath.addPolygon(collidingPolygon); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QPainterPath croppedPath = collidingPath.subtracted(eraserPath); |
|
|
|
if (NULL != collidingPolygonItem) |
|
|
|
QPainterPath croppedPathSimplified = croppedPath.simplified(); |
|
|
|
{ |
|
|
|
|
|
|
|
UBGraphicsStrokesGroup* pGroup = collidingPolygonItem->strokesGroup(); |
|
|
|
|
|
|
|
|
|
|
|
if (croppedPath == collidingPath) |
|
|
|
if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// NOOP
|
|
|
|
#pragma omp critical |
|
|
|
} |
|
|
|
// Put the entire polygon into the remove list
|
|
|
|
else if (croppedPathSimplified.isEmpty()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#pragma omp critical |
|
|
|
|
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) |
|
|
|
// Here we get the polygon of the colliding item
|
|
|
|
|
|
|
|
QPolygonF collidingPolygon = collidingPolygonItem->polygon(); |
|
|
|
|
|
|
|
QPainterPath collidingPath; |
|
|
|
|
|
|
|
collidingPath.addPolygon(collidingPolygon); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Then we substract the eraser path to the polygon and we simplify it
|
|
|
|
|
|
|
|
QPainterPath croppedPath = collidingPath.subtracted(eraserPath); |
|
|
|
|
|
|
|
QPainterPath croppedPathSimplified = croppedPath.simplified(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (croppedPath == collidingPath) |
|
|
|
{ |
|
|
|
{ |
|
|
|
UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); |
|
|
|
// NOOP
|
|
|
|
#pragma omp critical |
|
|
|
} |
|
|
|
toBeAddedItems << croppedPolygonItem; |
|
|
|
else if (croppedPathSimplified.isEmpty()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#pragma omp critical |
|
|
|
|
|
|
|
// Put the entire polygon into the remove list if the eraser removes all its visible content
|
|
|
|
|
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Then we convert the remaining path to a list of polygons that will be converted in
|
|
|
|
|
|
|
|
// UBGraphicsPolygonItems and added to the scene
|
|
|
|
|
|
|
|
foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); |
|
|
|
|
|
|
|
#pragma omp critical |
|
|
|
|
|
|
|
// Add this new polygon to the 'added' list
|
|
|
|
|
|
|
|
toBeAddedItems << croppedPolygonItem; |
|
|
|
|
|
|
|
if(NULL != pGroup){ |
|
|
|
|
|
|
|
croppedPolygonItem->setStrokesGroup(pGroup); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#pragma omp critical |
|
|
|
|
|
|
|
// Remove the original polygonitem because it has been replaced by many smaller polygons
|
|
|
|
|
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
} |
|
|
|
} |
|
|
|
#pragma omp critical |
|
|
|
|
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
for (int i = 0; i < collidItemsSize; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
UBGraphicsPolygonItem *collidingPolygonItem |
|
|
|
for (int i = 0; i < collidItemsSize; i++) |
|
|
|
= qgraphicsitem_cast<UBGraphicsPolygonItem*> (collidItems.at(i)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (collidingPolygonItem) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) |
|
|
|
UBGraphicsPolygonItem *collidingPolygonItem |
|
|
|
{ |
|
|
|
= qgraphicsitem_cast<UBGraphicsPolygonItem*> (collidItems.at(i)); |
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
QPolygonF collidingPolygon = collidingPolygonItem->polygon(); |
|
|
|
|
|
|
|
QPainterPath collidingPath; |
|
|
|
|
|
|
|
collidingPath.addPolygon(collidingPolygon); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QPainterPath croppedPath = collidingPath.subtracted(eraserPath); |
|
|
|
if (collidingPolygonItem) |
|
|
|
QPainterPath croppedPathSimplified = croppedPath.simplified(); |
|
|
|
{ |
|
|
|
|
|
|
|
if(eraserInnerRect.contains(collidingPolygonItem->boundingRect())) |
|
|
|
if (croppedPath == collidingPath) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// NOOP
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (croppedPathSimplified.isEmpty()) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) |
|
|
|
QPolygonF collidingPolygon = collidingPolygonItem->polygon(); |
|
|
|
|
|
|
|
QPainterPath collidingPath; |
|
|
|
|
|
|
|
collidingPath.addPolygon(collidingPolygon); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QPainterPath croppedPath = collidingPath.subtracted(eraserPath); |
|
|
|
|
|
|
|
QPainterPath croppedPathSimplified = croppedPath.simplified(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (croppedPath == collidingPath) |
|
|
|
{ |
|
|
|
{ |
|
|
|
UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); |
|
|
|
// NOOP
|
|
|
|
toBeAddedItems << croppedPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else if (croppedPathSimplified.isEmpty()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
foreach(const QPolygonF &pol, croppedPathSimplified.toFillPolygons()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
UBGraphicsPolygonItem* croppedPolygonItem = collidingPolygonItem->deepCopy(pol); |
|
|
|
|
|
|
|
toBeAddedItems << croppedPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
toBeRemovedItems << collidingPolygonItem; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addItems(toBeAddedItems); |
|
|
|
addItems(toBeAddedItems); |
|
|
|
mAddedItems += toBeAddedItems; |
|
|
|
mAddedItems += toBeAddedItems; |
|
|
|
|
|
|
|
|
|
|
|
removeItems(toBeRemovedItems); |
|
|
|
if(eDrawingMode_Vector == DRAWING_MODE){ |
|
|
|
mRemovedItems += toBeRemovedItems; |
|
|
|
foreach(QGraphicsItem* item, toBeAddedItems){ |
|
|
|
|
|
|
|
UBGraphicsPolygonItem* poly = dynamic_cast<UBGraphicsPolygonItem*>(item); |
|
|
|
|
|
|
|
if(NULL != poly && NULL != poly->strokesGroup()){ |
|
|
|
|
|
|
|
poly->strokesGroup()->addToGroup(poly); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removeItems(toBeRemovedItems); |
|
|
|
|
|
|
|
mRemovedItems += toBeRemovedItems; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(eDrawingMode_Vector == DRAWING_MODE){ |
|
|
|
|
|
|
|
foreach(QGraphicsItem* item, toBeRemovedItems){ |
|
|
|
|
|
|
|
UBGraphicsPolygonItem* poly = dynamic_cast<UBGraphicsPolygonItem*>(item); |
|
|
|
|
|
|
|
if(NULL != poly && NULL != poly->strokesGroup()){ |
|
|
|
|
|
|
|
poly->strokesGroup()->removeFromGroup(poly); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
mPreviousPoint = pEndPoint; |
|
|
|
mPreviousPoint = pEndPoint; |
|
|
|
} |
|
|
|
} |
|
|
|