void KisPrescaledProjection::viewportMoved(const QPointF &offset)
{
    // FIXME: \|/
    if (m_d->prescaledQImage.isNull()) return;
    if (offset.isNull()) return;

    QPoint alignedOffset = offset.toPoint();

    if(offset != alignedOffset) {
        /**
         * We can't optimize anything when offset is float :(
         * Just prescale entire image.
         */
        dbgRender << "prescaling the entire image because the offset is float";
        preScale();
        return;
    }

    QImage newImage = QImage(m_d->viewportSize, QImage::Format_ARGB32);
    newImage.fill(0);

    /**
     * TODO: viewport rects should be cropped by the borders of
     * the image, because it may be requested to read/write
     * outside QImage and copyQImage will not chatch it
     */
    QRect newViewportRect = QRect(QPoint(0,0), m_d->viewportSize);
    QRect oldViewportRect = newViewportRect.translated(alignedOffset);

    QRegion updateRegion = newViewportRect;
    QRect savedArea = newViewportRect & oldViewportRect;

    if(!savedArea.isEmpty()) {
        copyQImage(alignedOffset.x(), alignedOffset.y(), &newImage, m_d->prescaledQImage);
        updateRegion -= savedArea;
    }

    QPainter gc(&newImage);
    QVector<QRect> rects = updateRegion.rects();

    foreach(const QRect &rect, rects) {

        QRect imageRect =
            m_d->coordinatesConverter->viewportToImage(rect).toAlignedRect();
        QVector<QRect> patches =
            KritaUtils::splitRectIntoPatches(imageRect, m_d->updatePatchSize);

        foreach(const QRect& rc, patches) {
            QRect viewportPatch =
                m_d->coordinatesConverter->imageToViewport(rc).toAlignedRect();

            KisPPUpdateInfoSP info = getInitialUpdateInformation(QRect());
            fillInUpdateInformation(viewportPatch, info);
            drawUsingBackend(gc, info);
        }
示例#2
0
void MayaCameraWriter::write()
{
    MFnCamera mfnCamera(mDagPath);

    mSamp.setFocalLength(mfnCamera.focalLength());
    mSamp.setLensSqueezeRatio(mfnCamera.lensSqueezeRatio());
    mSamp.setHorizontalAperture(mfnCamera.horizontalFilmAperture() * 2.54);
    mSamp.setVerticalAperture(mfnCamera.verticalFilmAperture() * 2.54);
    mSamp.setHorizontalFilmOffset(mfnCamera.horizontalFilmOffset() * 2.54);
    mSamp.setVerticalFilmOffset(mfnCamera.verticalFilmOffset() * 2.54);
    double overscan = mfnCamera.overscan() - 1.0;
    mSamp.setOverScanLeft(overscan);
    mSamp.setOverScanRight(overscan);
    mSamp.setOverScanTop(overscan);
    mSamp.setOverScanBottom(overscan);
    mSamp.setNearClippingPlane(mfnCamera.nearClippingPlane());
    mSamp.setFarClippingPlane(mfnCamera.farClippingPlane());
    mSamp.setFStop(mfnCamera.fStop());
    mSamp.setFocusDistance(mfnCamera.focusDistance());

    // should this be based on the shutterAngle?  or the settings passed in?

    if (mUseRenderShutter)
    {
        mSamp.setShutterOpen(mShutterOpen);
        mSamp.setShutterClose(mShutterClose);
    }
    else
    {
        MTime sec(1.0, MTime::kSeconds);
        mSamp.setShutterOpen(0.0);
        mSamp.setShutterClose(
            Alembic::AbcGeom::RadiansToDegrees(mfnCamera.shutterAngle()) /
            ( 360.0 * sec.as(MTime::uiUnit()) ));
    }

    // build up the film fit and post projection matrix
    if (mSchema.getNumSamples() == 0)
    {
        // film fit first
        std::string filmFitName = "filmFit";
        mFilmFit = mfnCamera.filmFit();
        switch (mFilmFit)
        {
            case MFnCamera::kFillFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitFill");
                mSamp.addOp(fit);
            }
            break;

            case MFnCamera::kHorizontalFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitHorz");
                mSamp.addOp(fit);

                Alembic::AbcGeom::FilmBackXformOp offset(
                    Alembic::AbcGeom::kTranslateFilmBackOperation,
                    "filmFitOffs");
                mSamp.addOp(offset);
            }
            break;

            case MFnCamera::kVerticalFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitVert");
                mSamp.addOp(fit);

                Alembic::AbcGeom::FilmBackXformOp offset(
                    Alembic::AbcGeom::kTranslateFilmBackOperation,
                    "filmFitOffs");
                mSamp.addOp(offset);
            }
            break;

            case MFnCamera::kOverscanFilmFit:
            {
                Alembic::AbcGeom::FilmBackXformOp fit(
                    Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitOver");
                mSamp.addOp(fit);
            }
            break;

            default:
            break;
        }

        Alembic::AbcGeom::FilmBackXformOp preScale(
            Alembic::AbcGeom::kScaleFilmBackOperation, "preScale");
        mSamp.addOp(preScale);

        Alembic::AbcGeom::FilmBackXformOp filmTranslate(
            Alembic::AbcGeom::kTranslateFilmBackOperation, "filmTranslate");
        mSamp.addOp(filmTranslate);

        // skip film roll for now

        Alembic::AbcGeom::FilmBackXformOp postScale(
            Alembic::AbcGeom::kScaleFilmBackOperation, "postScale");
        mSamp.addOp(postScale);

        Alembic::AbcGeom::FilmBackXformOp cameraScale(
            Alembic::AbcGeom::kScaleFilmBackOperation, "cameraScale");
        mSamp.addOp(cameraScale);

    }

    std::size_t filmBackIndex = 0;

    switch (mFilmFit)
    {
        case MFnCamera::kFillFilmFit:
        {
            if (mSamp.getLensSqueezeRatio() > 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
                mSamp[0].setChannelValue(1, 1.0);
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
            }
            filmBackIndex = 1;
        }
        break;

        case MFnCamera::kHorizontalFilmFit:
        {
            if (mSamp.getLensSqueezeRatio() > 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
                mSamp[1].setChannelValue(0, 0.0);
                mSamp[1].setChannelValue(1, 2.0 *
                    mfnCamera.filmFitOffset()/
                    mfnCamera.horizontalFilmAperture() );
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, 1.0);
                mSamp[1].setChannelValue(0, 0.0);
                mSamp[1].setChannelValue(1, 0.0);
            }
            filmBackIndex = 2;
        }
        break;

        case MFnCamera::kVerticalFilmFit:
        {
            if (1.0/mSamp.getLensSqueezeRatio() > 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
                mSamp[0].setChannelValue(1, 1.0);
                mSamp[1].setChannelValue(0, 2.0 *
                    mfnCamera.filmFitOffset() /
                    mfnCamera.horizontalFilmAperture() );
                mSamp[1].setChannelValue(1, 0.0);
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, 1.0);
                mSamp[1].setChannelValue(0, 0.0);
                mSamp[1].setChannelValue(1, 0.0);
            }
            filmBackIndex = 2;
        }
        break;

        case MFnCamera::kOverscanFilmFit:
        {
            if (mSamp.getLensSqueezeRatio() < 1.0)
            {
                mSamp[0].setChannelValue(0, 1.0);
                mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
            }
            else
            {
                mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
                mSamp[0].setChannelValue(1, 1.0);
            }
            filmBackIndex = 1;
        }
        break;

        default:
        break;
    }

    mSamp[filmBackIndex].setChannelValue(0, 1.0/mfnCamera.preScale());
    mSamp[filmBackIndex].setChannelValue(1, 1.0/mfnCamera.preScale());

    mSamp[filmBackIndex+1].setChannelValue(0, mfnCamera.filmTranslateH());
    mSamp[filmBackIndex+1].setChannelValue(1, mfnCamera.filmTranslateV());

    mSamp[filmBackIndex+2].setChannelValue(0, 1.0/mfnCamera.postScale());
    mSamp[filmBackIndex+2].setChannelValue(1, 1.0/mfnCamera.postScale());

    mSamp[filmBackIndex+3].setChannelValue(0, mfnCamera.cameraScale());
    mSamp[filmBackIndex+3].setChannelValue(1, mfnCamera.cameraScale());

    mSchema.set(mSamp);
}