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);
}
Пример #2
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);
	}
Пример #9
0
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();
}
Пример #14
0
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();
}
Пример #15
0
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();
}