void KisProcessingApplicatorTest::testNoUIUpdates() { KisSurrogateUndoStore *undoStore = new KisSurrogateUndoStore(); KisPaintLayerSP paintLayer1; KisPaintLayerSP paintLayer2; KisImageSP image = createImage(undoStore, paintLayer1, paintLayer2); QSignalSpy uiSignalsCounter(image.data(), SIGNAL(sigImageUpdated(const QRect&))); QRect cropRect1(40,40,86,86); { KisProcessingApplicator applicator(image, image->rootLayer(), KisProcessingApplicator::RECURSIVE | KisProcessingApplicator::NO_UI_UPDATES); KisProcessingVisitorSP visitor = new KisCropProcessingVisitor(cropRect1, true, true); applicator.applyVisitor(visitor); applicator.end(); image->waitForDone(); } QCOMPARE(uiSignalsCounter.size(), 0); uiSignalsCounter.clear(); undoStore->undo(); image->waitForDone(); QCOMPARE(uiSignalsCounter.size(), 0); }
void operator()() { /* Figure out the number of threads */ unsigned int size; pfunc::get_num_threads (taskmgr, size); /* Prepare all the tasks for launch */ TaskType sub_tasks[size]; std::vector<applicator> funcs; for (unsigned int rank=0; rank<size; ++rank) { SpaceType subspace = PartitionerType::create (space.begin(), space.end(), rank, size); funcs.push_back (applicator(func.split(), subspace)); } /* Launch the tasks */ for (unsigned int rank=0; rank<size; ++rank) { pfunc::spawn (taskmgr, sub_tasks[rank], funcs[rank]); } /* wait for them */ pfunc::wait_all (taskmgr, sub_tasks, sub_tasks+size); /* aggregate the results */ for (unsigned int rank=0; rank<size; ++rank) { func.join(funcs[rank].func); } }
void KisThreadedApplicatorTest::testApplication() { const KoColorSpace * colorSpace = KoColorSpaceRegistry::instance()->rgb8(); TestJobFactory factory; TestUtil::TestProgressBar bar; KoProgressUpdater updater(&bar); KisPaintDeviceSP test = new KisPaintDevice(colorSpace); quint8 *bytes = test->colorSpace()->allocPixelBuffer(1); memset(bytes, 128, test->colorSpace()->pixelSize()); test->fill(0, 0, 1000, 1000, bytes); KisTransaction transaction("", test); KisThreadedApplicator applicator(test, QRect(0, 0, 1000, 1000), &factory, &updater); applicator.execute(); KisRectConstIteratorPixel it = test->createRectConstIterator(0, 0, 1000, 1000); while (!it.isDone()) { QCOMPARE((int)it.rawData()[0], (int)255); QCOMPARE((int)it.rawData()[1], (int)255); QCOMPARE((int)it.rawData()[2], (int)255); QCOMPARE((int)it.rawData()[3], (int)255); ++it; } }
void KisProcessingApplicatorTest::testRecursiveProcessing() { KisSurrogateUndoStore *undoStore = new KisSurrogateUndoStore(); KisPaintLayerSP paintLayer1; KisPaintLayerSP paintLayer2; KisImageSP image = createImage(undoStore, paintLayer1, paintLayer2); QRect cropRect1(40,40,86,86); QVERIFY(checkLayers(image, "recursive_initial")); { KisProcessingApplicator applicator(image, image->rootLayer(), KisProcessingApplicator::RECURSIVE); KisProcessingVisitorSP visitor = new KisCropProcessingVisitor(cropRect1, true, true); applicator.applyVisitor(visitor); applicator.end(); image->waitForDone(); } QVERIFY(checkLayers(image, "recursive_crop")); undoStore->undo(); image->waitForDone(); QVERIFY(checkLayers(image, "recursive_initial")); }
void KisSelectionToolHelper::addSelectionShapes(QList< KoShape* > shapes) { KisViewManager* view = m_canvas->viewManager(); if (view->image()->wrapAroundModePermitted()) { view->showFloatingMessage( i18n("Shape selection does not fully " "support wraparound mode. Please " "use pixel selection instead"), KisIconUtils::loadIcon("selection-info")); } KisProcessingApplicator applicator(view->image(), 0 /* we need no automatic updates */, KisProcessingApplicator::NONE, KisImageSignalVector() << ModifiedSignal, m_name); applicator.applyCommand(new LazyInitGlobalSelection(view)); struct ClearPixelSelection : public KisTransactionBasedCommand { ClearPixelSelection(KisViewManager *view) : m_view(view) {} KisViewManager *m_view; KUndo2Command* paint() { KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection(); KIS_ASSERT_RECOVER(pixelSelection) { return 0; } KisSelectionTransaction transaction(pixelSelection); pixelSelection->clear(); return transaction.endAndTake(); } }; applicator.applyCommand(new ClearPixelSelection(view)); struct AddSelectionShape : public KisTransactionBasedCommand { AddSelectionShape(KisViewManager *view, KoShape* shape) : m_view(view), m_shape(shape) {} KisViewManager *m_view; KoShape* m_shape; KUndo2Command* paint() { /** * Mark a shape that it belongs to a shape selection */ if(!m_shape->userData()) { m_shape->setUserData(new KisShapeSelectionMarker); } return m_view->canvasBase()->shapeController()->addShape(m_shape); } }; foreach(KoShape* shape, shapes) { applicator.applyCommand( new KisGuiContextCommand(new AddSelectionShape(view, shape), view)); }
void KisProcessingApplicatorTest::testNonRecursiveProcessing() { KisSurrogateUndoStore *undoStore = new KisSurrogateUndoStore(); KisPaintLayerSP paintLayer1; KisPaintLayerSP paintLayer2; KisImageSP image = createImage(undoStore, paintLayer1, paintLayer2); QRect cropRect1(25,25,75,75); QRect cropRect2(100,100,50,50); QVERIFY(checkLayers(image, "initial")); { KisProcessingApplicator applicator(image, paintLayer1, KisProcessingApplicator::NONE); KisProcessingVisitorSP visitor = new KisCropProcessingVisitor(cropRect1, true, false); applicator.applyVisitor(visitor); applicator.end(); image->waitForDone(); } QVERIFY(checkLayers(image, "crop_l1")); { KisProcessingApplicator applicator(image, paintLayer2, KisProcessingApplicator::NONE); KisProcessingVisitorSP visitor = new KisCropProcessingVisitor(cropRect2, true, false); applicator.applyVisitor(visitor); applicator.end(); image->waitForDone(); } QVERIFY(checkLayers(image, "crop_l2")); undoStore->undo(); image->waitForDone(); QVERIFY(checkLayers(image, "crop_l1")); undoStore->undo(); image->waitForDone(); QVERIFY(checkLayers(image, "initial")); }
void KisSelectionToolHelper::selectPixelSelection(KisPixelSelectionSP selection, SelectionAction action) { KisViewManager* view = m_canvas->viewManager(); if (selection->selectedExactRect().isEmpty()) { m_canvas->viewManager()->selectionManager()->deselect(); return; } KisProcessingApplicator applicator(view->image(), 0 /* we need no automatic updates */, KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE, KisImageSignalVector() << ModifiedSignal, m_name); applicator.applyCommand(new LazyInitGlobalSelection(view)); struct ApplyToPixelSelection : public KisTransactionBasedCommand { ApplyToPixelSelection(KisViewManager *view, KisPixelSelectionSP selection, SelectionAction action) : m_view(view), m_selection(selection), m_action(action) {} KisViewManager *m_view; KisPixelSelectionSP m_selection; SelectionAction m_action; KUndo2Command* paint() { KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection(); KIS_ASSERT_RECOVER(pixelSelection) { return 0; } bool hasSelection = !pixelSelection->isEmpty(); KisSelectionTransaction transaction(pixelSelection); if (!hasSelection && m_action == SELECTION_SUBTRACT) { pixelSelection->invert(); } pixelSelection->applySelection(m_selection, m_action); QRect dirtyRect = m_view->image()->bounds(); if (hasSelection && m_action != SELECTION_REPLACE && m_action != SELECTION_INTERSECT) { dirtyRect = m_selection->selectedRect(); } m_view->selection()->updateProjection(dirtyRect); KUndo2Command *savedCommand = transaction.endAndTake(); pixelSelection->setDirty(dirtyRect); return savedCommand; } }; applicator.applyCommand(new ApplyToPixelSelection(view, selection, action)); applicator.end(); }
void updateRegistration(cx::DataPtr fixed, cx::DataPtr moving, cx::Transform3D delta_pre_rMd) { QDateTime oldTime = QDateTime::currentDateTime(); cx::RegistrationTransform regTrans(delta_pre_rMd, QDateTime::currentDateTime(), "test"); regTrans.mFixed = fixed->getUid(); regTrans.mMoving = moving->getUid(); cx::RegistrationApplicator applicator(mData); applicator.updateRegistration(oldTime, regTrans); }
void OffsetImage::offsetImpl(const QString& actionName, KisNodeSP node, const QPoint& offsetPoint) { KisImageSignalVector emitSignals; emitSignals << ModifiedSignal; KisProcessingApplicator applicator(m_view->image(), node, KisProcessingApplicator::RECURSIVE, emitSignals, actionName); QRect rc = offsetWrapRect(); KisProcessingVisitorSP visitor = new KisOffsetProcessingVisitor(offsetPoint, rc); applicator.applyVisitor(visitor, KisStrokeJobData::CONCURRENT); applicator.end(); }
void KisFillActionFactory::run(const QString &fillSource, KisViewManager *view) { KisNodeSP node = view->activeNode(); if (!node || !node->hasEditablePaintDevice()) return; KisSelectionSP selection = view->selection(); QRect selectedRect = selection ? selection->selectedRect() : view->image()->bounds(); Q_UNUSED(selectedRect); KisPaintDeviceSP filled = node->paintDevice()->createCompositionSourceDevice(); Q_UNUSED(filled); bool usePattern = false; bool useBgColor = false; if (fillSource.contains("pattern")) { usePattern = true; } else if (fillSource.contains("bg")) { useBgColor = true; } KisProcessingApplicator applicator(view->image(), node, KisProcessingApplicator::NONE, KisImageSignalVector() << ModifiedSignal, kundo2_i18n("Flood Fill Layer")); KisResourcesSnapshotSP resources = new KisResourcesSnapshot(view->image(), node, 0, view->resourceProvider()->resourceManager()); if (!fillSource.contains("opacity")) { resources->setOpacity(1.0); } KisProcessingVisitorSP visitor = new FillProcessingVisitor(QPoint(0, 0), // start position selection, resources, false, // fast mode usePattern, true, // fill only selection, 0, // feathering radius 0, // sizemod 80, // threshold, false, // unmerged useBgColor); applicator.applyVisitor(visitor, KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::EXCLUSIVE); applicator.end(); }
void test(const QString &testname, KisProcessingVisitorSP visitor) { KisSurrogateUndoStore *undoStore = new KisSurrogateUndoStore(); KisImageSP image = createImage(undoStore); image->initialRefreshGraph(); QVERIFY(checkLayersInitial(image)); KisProcessingApplicator applicator(image, image->root(), KisProcessingApplicator::RECURSIVE); applicator.applyVisitor(visitor); applicator.end(); image->waitForDone(); QVERIFY(checkLayers(image, testname)); undoStore->undo(); image->waitForDone(); QVERIFY(checkLayersInitial(image)); }
void KisSelectionDecorationTest::testConcurrentSelectionFetches() { KisImageSP image = utils::createImage(0, QSize(3000, 3000)); for (int i = 0; i < 10000; i++) { KisProcessingApplicator applicator(image, 0 /* we need no automatic updates */, KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE, KisImageSignalVector() << ModifiedSignal, kundo2_noi18n("test stroke")); applicator.applyCommand(new KisSetEmptyGlobalSelectionCommand(image)); applicator.applyCommand(new KisDeselectGlobalSelectionCommand(image)); applicator.end(); for (int j = 0; j < 100; j++) { KisSelectionSP selection = image->globalSelection(); } } image->waitForDone(); }
/** Update the registration for data and all data connected to its space. * * Registration is done relative to masterFrame, i.e. data is moved relative to the masterFrame. * */ void RegistrationImplService::updateRegistration(QDateTime oldTime, RegistrationTransform deltaTransform, DataPtr data) { RegistrationApplicator applicator(mPatientModelService->getData()); applicator.updateRegistration(oldTime, deltaTransform, data); mPatientModelService->autoSave(); }
void RuleNode::apply(const Logger &logger, const std::unordered_map<QString, const ResolvedProduct *> &productsByName, const std::unordered_map<QString, const ResolvedProject *> &projectsByName, ApplicationResult *result) { ArtifactSet allCompatibleInputs = currentInputArtifacts(); const ArtifactSet explicitlyDependsOn = RulesApplicator::collectExplicitlyDependsOn(m_rule.get(), product.get()); const ArtifactSet auxiliaryInputs = RulesApplicator::collectAuxiliaryInputs(m_rule.get(), product.get()); const ArtifactSet addedInputs = allCompatibleInputs - m_oldInputArtifacts; const ArtifactSet removedInputs = m_oldInputArtifacts - allCompatibleInputs; const ArtifactSet changedInputs = changedInputArtifacts(allCompatibleInputs, explicitlyDependsOn, auxiliaryInputs); bool upToDate = changedInputs.empty() && addedInputs.empty() && removedInputs.empty(); qCDebug(lcBuildGraph).noquote().nospace() << "consider " << (m_rule->isDynamic() ? "dynamic " : "") << (m_rule->multiplex ? "multiplex " : "") << "rule node " << m_rule->toString() << "\n\tchanged: " << changedInputs.toString() << "\n\tcompatible: " << allCompatibleInputs.toString() << "\n\tadded: " << addedInputs.toString() << "\n\tremoved: " << removedInputs.toString(); ArtifactSet inputs = changedInputs; if (m_rule->multiplex) inputs = allCompatibleInputs; else inputs += addedInputs; for (Artifact * const input : allCompatibleInputs) { for (const Artifact * const output : input->parentArtifacts()) { if (output->transformer->rule != m_rule) continue; if (prepareScriptNeedsRerun(output->transformer.get(), output->transformer->product().get(), productsByName, projectsByName)) { upToDate = false; inputs += input; } break; } if (m_rule->multiplex) break; } // Handle rules without inputs: We want to run such a rule if and only if it has not run yet // or its transformer is not up to date regarding the prepare script. if (upToDate && (!m_rule->declaresInputs() || !m_rule->requiresInputs) && inputs.empty()) { bool hasOutputs = false; for (const Artifact * const output : filterByType<Artifact>(parents)) { if (output->transformer->rule != m_rule) continue; hasOutputs = true; if (prepareScriptNeedsRerun(output->transformer.get(), output->transformer->product().get(), productsByName, projectsByName)) { upToDate = false; break; } if (m_rule->multiplex) break; } if (!hasOutputs) upToDate = false; } if (upToDate) { qCDebug(lcExec) << "rule is up to date. Skipping."; return; } const bool mustApplyRule = !inputs.empty() || !m_rule->declaresInputs() || !m_rule->requiresInputs; // For a non-multiplex rule, the removal of an input always implies that the // corresponding outputs disappear. // For a multiplex rule, the outputs disappear only if *all* inputs are gone *and* // the rule requires inputs. This is exactly the opposite condition of whether to // re-apply the rule. const bool removedInputForcesOutputRemoval = !m_rule->multiplex || !mustApplyRule; ArtifactSet outputArtifactsToRemove; std::vector<std::pair<Artifact *, Artifact *>> connectionsToBreak; for (Artifact * const artifact : removedInputs) { if (!artifact) // dummy artifact continue; for (Artifact *parent : filterByType<Artifact>(artifact->parents)) { if (parent->transformer->rule != m_rule) { // parent was not created by our rule. continue; } // parent must always have a transformer, because it's generated. QBS_CHECK(parent->transformer); // artifact is a former input of m_rule and parent was created by m_rule // the inputs of the transformer must contain artifact QBS_CHECK(parent->transformer->inputs.contains(artifact)); if (removedInputForcesOutputRemoval) outputArtifactsToRemove += parent; else connectionsToBreak.push_back(std::make_pair(parent, artifact)); } disconnect(this, artifact); } for (const auto &connection : connectionsToBreak) disconnect(connection.first, connection.second); if (!outputArtifactsToRemove.empty()) { RulesApplicator::handleRemovedRuleOutputs(inputs, outputArtifactsToRemove, result->removedArtifacts, logger); } if (mustApplyRule) { RulesApplicator applicator(product.lock(), productsByName, projectsByName, logger); applicator.applyRule(this, inputs, explicitlyDependsOn); result->createdArtifacts = applicator.createdArtifacts(); result->invalidatedArtifacts = applicator.invalidatedArtifacts(); m_lastApplicationTime = FileTime::currentTime(); if (applicator.ruleUsesIo()) m_needsToConsiderChangedInputs = true; } else { qCDebug(lcExec).noquote() << "prepare script does not need to run"; } m_oldInputArtifacts = allCompatibleInputs; m_oldExplicitlyDependsOn = explicitlyDependsOn; m_oldAuxiliaryInputs = auxiliaryInputs; product->topLevelProject()->buildData->setDirty(); }
void KisSelectionToolHelper::selectPixelSelection(KisPixelSelectionSP selection, SelectionAction action) { KisViewManager* view = m_canvas->viewManager(); if (selection->selectedExactRect().isEmpty()) { m_canvas->viewManager()->selectionManager()->deselect(); return; } KisProcessingApplicator applicator(view->image(), 0 /* we need no automatic updates */, KisProcessingApplicator::SUPPORTS_WRAPAROUND_MODE, KisImageSignalVector() << ModifiedSignal, m_name); applicator.applyCommand(new LazyInitGlobalSelection(view)); struct ApplyToPixelSelection : public KisTransactionBasedCommand { ApplyToPixelSelection(KisViewManager *view, KisPixelSelectionSP selection, SelectionAction action) : m_view(view), m_selection(selection), m_action(action) {} KisViewManager *m_view; KisPixelSelectionSP m_selection; SelectionAction m_action; KUndo2Command* paint() override { KisPixelSelectionSP pixelSelection = m_view->selection()->pixelSelection(); KIS_ASSERT_RECOVER(pixelSelection) { return 0; } bool hasSelection = !pixelSelection->isEmpty(); KisSelectionTransaction transaction(pixelSelection); if (!hasSelection && m_action == SELECTION_SUBTRACT) { pixelSelection->invert(); } pixelSelection->applySelection(m_selection, m_action); const QRect imageBounds = m_view->image()->bounds(); QRect selectionExactRect = m_view->selection()->selectedExactRect(); if (!imageBounds.contains(selectionExactRect)) { pixelSelection->crop(imageBounds); if (pixelSelection->outlineCacheValid()) { QPainterPath cache = pixelSelection->outlineCache(); QPainterPath imagePath; imagePath.addRect(imageBounds); cache &= imagePath; pixelSelection->setOutlineCache(cache); } selectionExactRect &= imageBounds; } QRect dirtyRect = imageBounds; if (hasSelection && m_action != SELECTION_REPLACE && m_action != SELECTION_INTERSECT) { dirtyRect = m_selection->selectedRect(); } m_view->selection()->updateProjection(dirtyRect); KUndo2Command *savedCommand = transaction.endAndTake(); pixelSelection->setDirty(dirtyRect); if (selectionExactRect.isEmpty()) { KisCommandUtils::CompositeCommand *cmd = new KisCommandUtils::CompositeCommand(); cmd->addCommand(savedCommand); cmd->addCommand(new KisDeselectGlobalSelectionCommand(m_view->image())); savedCommand = cmd; } return savedCommand; } }; applicator.applyCommand(new ApplyToPixelSelection(view, selection, action)); applicator.end(); }