<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docsh2.cxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: rt $ $Date: 2006-05-04 15:03:15 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#ifndef _SVDPAGE_HXX //autogen
#include <svx/svdpage.hxx>
#endif

#pragma hdrstop

#include <svx/xtable.hxx>

#include "scitems.hxx"
#include <tools/gen.hxx>
#include <svtools/ctrltool.hxx>
#include <svx/flstitem.hxx>
#include <svx/drawitem.hxx>
#include <sfx2/printer.hxx>
#include <svtools/smplhint.hxx>
#include <svx/svditer.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdoole2.hxx>
#include <vcl/svapp.hxx>
#include <svx/asiancfg.hxx>
#include <svx/forbiddencharacterstable.hxx>
#include <svx/unolingu.hxx>
#include <rtl/logfile.hxx>

// INCLUDE ---------------------------------------------------------------
/*
#include <svdrwetc.hxx>
#include <svdrwobx.hxx>
#include <sostor.hxx>
*/
#include "drwlayer.hxx"
#include "stlpool.hxx"
#include "docsh.hxx"
#include "docfunc.hxx"
#include "sc.hrc"

using namespace com::sun::star;

//------------------------------------------------------------------

BOOL __EXPORT ScDocShell::InitNew( const uno::Reference < embed::XStorage >& xStor )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::InitNew" );

    BOOL bRet = SfxObjectShell::InitNew( xStor );

    aDocument.MakeTable(0);
    //  zusaetzliche Tabellen werden von der ersten View angelegt,
    //  wenn bIsEmpty dann noch TRUE ist

    if( bRet )
    {
        Size aSize( (long) ( STD_COL_WIDTH           * HMM_PER_TWIPS * OLE_STD_CELLS_X ),
                    (long) ( ScGlobal::nStdRowHeight * HMM_PER_TWIPS * OLE_STD_CELLS_Y ) );
        // hier muss auch der Start angepasst werden
        SetVisAreaOrSize( Rectangle( Point(), aSize ), TRUE );
    }

    // InitOptions sets the document languages, must be called before CreateStandardStyles
    InitOptions();

    aDocument.GetStyleSheetPool()->CreateStandardStyles();
    aDocument.UpdStlShtPtrsFrmNms();

    //  SetDocumentModified ist in Load/InitNew nicht mehr erlaubt!

    InitItems();
    CalcOutputFactor();

    return bRet;
}

//------------------------------------------------------------------

BOOL ScDocShell::IsEmpty() const
{
    return bIsEmpty;
}

void ScDocShell::ResetEmpty()
{
    bIsEmpty = FALSE;
}

//------------------------------------------------------------------

void ScDocShell::InitItems()
{
    // AllItemSet fuer Controller mit benoetigten Items fuellen:

    // if ( pFontList )
    //  delete pFontList;

    //  Druck-Optionen werden beim Drucken und evtl. in GetPrinter gesetzt

    // pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
    //PutItem( SvxFontListItem( pFontList, SID_ATTR_CHAR_FONTLIST ) );
    UpdateFontList();

    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    if (pDrawLayer)
    {
        PutItem( SvxColorTableItem  ( pDrawLayer->GetColorTable() ) );
        PutItem( SvxGradientListItem( pDrawLayer->GetGradientList() ) );
        PutItem( SvxHatchListItem   ( pDrawLayer->GetHatchList() ) );
        PutItem( SvxBitmapListItem  ( pDrawLayer->GetBitmapList() ) );
        PutItem( SvxDashListItem    ( pDrawLayer->GetDashList() ) );
        PutItem( SvxLineEndListItem ( pDrawLayer->GetLineEndList() ) );

            //  andere Anpassungen nach dem Anlegen des DrawLayers

        pDrawLayer->SetNotifyUndoActionHdl( LINK( pDocFunc, ScDocFunc, NotifyDrawUndo ) );

        //if (SfxObjectShell::HasSbxObject())
        pDrawLayer->UpdateBasic();          // DocShell-Basic in DrawPages setzen
    }
    else
    {
        //  always use global color table instead of local copy
        PutItem( SvxColorTableItem( XColorTable::GetStdColorTable() ) );
    }

    if ( !aDocument.GetForbiddenCharacters().isValid() ||
            !aDocument.IsValidAsianCompression() || !aDocument.IsValidAsianKerning() )
    {
        //  get settings from SvxAsianConfig
        SvxAsianConfig aAsian( sal_False );

        if ( !aDocument.GetForbiddenCharacters().isValid() )
        {
            // set forbidden characters if necessary
            uno::Sequence<lang::Locale> aLocales = aAsian.GetStartEndCharLocales();
            if (aLocales.getLength())
            {
                vos::ORef<SvxForbiddenCharactersTable> xForbiddenTable =
                        new SvxForbiddenCharactersTable( aDocument.GetServiceManager() );

                const lang::Locale* pLocales = aLocales.getConstArray();
                for (sal_Int32 i = 0; i < aLocales.getLength(); i++)
                {
                    i18n::ForbiddenCharacters aForbidden;
                    aAsian.GetStartEndChars( pLocales[i], aForbidden.beginLine, aForbidden.endLine );
                    LanguageType eLang = SvxLocaleToLanguage(pLocales[i]);
                    //pDoc->SetForbiddenCharacters( eLang, aForbidden );

                    xForbiddenTable->SetForbiddenCharacters( eLang, aForbidden );
                }

                aDocument.SetForbiddenCharacters( xForbiddenTable );
            }
        }

        if ( !aDocument.IsValidAsianCompression() )
        {
            // set compression mode from configuration if not already set (e.g. XML import)
            aDocument.SetAsianCompression( aAsian.GetCharDistanceCompression() );
        }

        if ( !aDocument.IsValidAsianKerning() )
        {
            // set asian punctuation kerning from configuration if not already set (e.g. XML import)
            aDocument.SetAsianKerning( !aAsian.IsKerningWesternTextOnly() );    // reversed
        }
    }
}

//------------------------------------------------------------------

void ScDocShell::ResetDrawObjectShell()
{
    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    if (pDrawLayer)
        pDrawLayer->SetObjectShell( NULL );
}

//------------------------------------------------------------------

void __EXPORT ScDocShell::Activate()
{
}

void __EXPORT ScDocShell::Deactivate()
{
}

//------------------------------------------------------------------

ScDrawLayer* ScDocShell::MakeDrawLayer()
{
    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    if (!pDrawLayer)
    {
        RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::MakeDrawLayer" );

        aDocument.InitDrawLayer(this);
        pDrawLayer = aDocument.GetDrawLayer();
        InitItems();                                            // incl. Undo und Basic
        Broadcast( SfxSimpleHint( SC_HINT_DRWLAYER_NEW ) );
        if (nDocumentLock)
            pDrawLayer->setLock(TRUE);
    }
    return pDrawLayer;
}

//------------------------------------------------------------------

void ScDocShell::RemoveUnknownObjects()
{
    //  OLE-Objekte loeschen, wenn kein Drawing-Objekt dazu existiert
    //  Loeschen wie in SvPersist::CleanUp

    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    uno::Sequence < rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();

        for( sal_Int32 i=0; i<aNames.getLength(); i++ )
        {
            String aObjName = aNames[i];
            BOOL bFound = FALSE;
            if ( pDrawLayer )
            {
                SCTAB nTabCount = static_cast<sal_Int16>(pDrawLayer->GetPageCount());
                for (SCTAB nTab=0; nTab<nTabCount && !bFound; nTab++)
                {
                    SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
                    DBG_ASSERT(pPage,"Page ?");
                    if (pPage)
                    {
                        SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
                        SdrObject* pObject = aIter.Next();
                        while (pObject && !bFound)
                        {
                            // name from InfoObject is PersistName
                            if ( pObject->ISA(SdrOle2Obj) &&
                                    static_cast<SdrOle2Obj*>(pObject)->GetPersistName() == aObjName )
                                bFound = TRUE;
                            pObject = aIter.Next();
                        }
                    }
                }
            }

            if (!bFound)
            {
                //TODO/LATER: hacks not supported anymore
                //DBG_ASSERT(pEle->GetRefCount()==2, "Loeschen von referenziertem Storage");
                GetEmbeddedObjectContainer().RemoveEmbeddedObject( aObjName );
            }
            else
                i++;
        }
}

<commit_msg>INTEGRATION: CWS pchfix01 (1.18.58); FILE MERGED 2006/07/12 10:02:32 kaib 1.18.58.1: #i67080# Converted cxx files in sc, added initial project level pch and stripped old PCH definitions.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docsh2.cxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 13:37:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#ifndef _SVDPAGE_HXX //autogen
#include <svx/svdpage.hxx>
#endif

#include <svx/xtable.hxx>

#include "scitems.hxx"
#include <tools/gen.hxx>
#include <svtools/ctrltool.hxx>
#include <svx/flstitem.hxx>
#include <svx/drawitem.hxx>
#include <sfx2/printer.hxx>
#include <svtools/smplhint.hxx>
#include <svx/svditer.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdoole2.hxx>
#include <vcl/svapp.hxx>
#include <svx/asiancfg.hxx>
#include <svx/forbiddencharacterstable.hxx>
#include <svx/unolingu.hxx>
#include <rtl/logfile.hxx>

// INCLUDE ---------------------------------------------------------------
/*
#include <svdrwetc.hxx>
#include <svdrwobx.hxx>
#include <sostor.hxx>
*/
#include "drwlayer.hxx"
#include "stlpool.hxx"
#include "docsh.hxx"
#include "docfunc.hxx"
#include "sc.hrc"

using namespace com::sun::star;

//------------------------------------------------------------------

BOOL __EXPORT ScDocShell::InitNew( const uno::Reference < embed::XStorage >& xStor )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::InitNew" );

    BOOL bRet = SfxObjectShell::InitNew( xStor );

    aDocument.MakeTable(0);
    //  zusaetzliche Tabellen werden von der ersten View angelegt,
    //  wenn bIsEmpty dann noch TRUE ist

    if( bRet )
    {
        Size aSize( (long) ( STD_COL_WIDTH           * HMM_PER_TWIPS * OLE_STD_CELLS_X ),
                    (long) ( ScGlobal::nStdRowHeight * HMM_PER_TWIPS * OLE_STD_CELLS_Y ) );
        // hier muss auch der Start angepasst werden
        SetVisAreaOrSize( Rectangle( Point(), aSize ), TRUE );
    }

    // InitOptions sets the document languages, must be called before CreateStandardStyles
    InitOptions();

    aDocument.GetStyleSheetPool()->CreateStandardStyles();
    aDocument.UpdStlShtPtrsFrmNms();

    //  SetDocumentModified ist in Load/InitNew nicht mehr erlaubt!

    InitItems();
    CalcOutputFactor();

    return bRet;
}

//------------------------------------------------------------------

BOOL ScDocShell::IsEmpty() const
{
    return bIsEmpty;
}

void ScDocShell::ResetEmpty()
{
    bIsEmpty = FALSE;
}

//------------------------------------------------------------------

void ScDocShell::InitItems()
{
    // AllItemSet fuer Controller mit benoetigten Items fuellen:

    // if ( pFontList )
    //  delete pFontList;

    //  Druck-Optionen werden beim Drucken und evtl. in GetPrinter gesetzt

    // pFontList = new FontList( GetPrinter(), Application::GetDefaultDevice() );
    //PutItem( SvxFontListItem( pFontList, SID_ATTR_CHAR_FONTLIST ) );
    UpdateFontList();

    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    if (pDrawLayer)
    {
        PutItem( SvxColorTableItem  ( pDrawLayer->GetColorTable() ) );
        PutItem( SvxGradientListItem( pDrawLayer->GetGradientList() ) );
        PutItem( SvxHatchListItem   ( pDrawLayer->GetHatchList() ) );
        PutItem( SvxBitmapListItem  ( pDrawLayer->GetBitmapList() ) );
        PutItem( SvxDashListItem    ( pDrawLayer->GetDashList() ) );
        PutItem( SvxLineEndListItem ( pDrawLayer->GetLineEndList() ) );

            //  andere Anpassungen nach dem Anlegen des DrawLayers

        pDrawLayer->SetNotifyUndoActionHdl( LINK( pDocFunc, ScDocFunc, NotifyDrawUndo ) );

        //if (SfxObjectShell::HasSbxObject())
        pDrawLayer->UpdateBasic();          // DocShell-Basic in DrawPages setzen
    }
    else
    {
        //  always use global color table instead of local copy
        PutItem( SvxColorTableItem( XColorTable::GetStdColorTable() ) );
    }

    if ( !aDocument.GetForbiddenCharacters().isValid() ||
            !aDocument.IsValidAsianCompression() || !aDocument.IsValidAsianKerning() )
    {
        //  get settings from SvxAsianConfig
        SvxAsianConfig aAsian( sal_False );

        if ( !aDocument.GetForbiddenCharacters().isValid() )
        {
            // set forbidden characters if necessary
            uno::Sequence<lang::Locale> aLocales = aAsian.GetStartEndCharLocales();
            if (aLocales.getLength())
            {
                vos::ORef<SvxForbiddenCharactersTable> xForbiddenTable =
                        new SvxForbiddenCharactersTable( aDocument.GetServiceManager() );

                const lang::Locale* pLocales = aLocales.getConstArray();
                for (sal_Int32 i = 0; i < aLocales.getLength(); i++)
                {
                    i18n::ForbiddenCharacters aForbidden;
                    aAsian.GetStartEndChars( pLocales[i], aForbidden.beginLine, aForbidden.endLine );
                    LanguageType eLang = SvxLocaleToLanguage(pLocales[i]);
                    //pDoc->SetForbiddenCharacters( eLang, aForbidden );

                    xForbiddenTable->SetForbiddenCharacters( eLang, aForbidden );
                }

                aDocument.SetForbiddenCharacters( xForbiddenTable );
            }
        }

        if ( !aDocument.IsValidAsianCompression() )
        {
            // set compression mode from configuration if not already set (e.g. XML import)
            aDocument.SetAsianCompression( aAsian.GetCharDistanceCompression() );
        }

        if ( !aDocument.IsValidAsianKerning() )
        {
            // set asian punctuation kerning from configuration if not already set (e.g. XML import)
            aDocument.SetAsianKerning( !aAsian.IsKerningWesternTextOnly() );    // reversed
        }
    }
}

//------------------------------------------------------------------

void ScDocShell::ResetDrawObjectShell()
{
    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    if (pDrawLayer)
        pDrawLayer->SetObjectShell( NULL );
}

//------------------------------------------------------------------

void __EXPORT ScDocShell::Activate()
{
}

void __EXPORT ScDocShell::Deactivate()
{
}

//------------------------------------------------------------------

ScDrawLayer* ScDocShell::MakeDrawLayer()
{
    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    if (!pDrawLayer)
    {
        RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::MakeDrawLayer" );

        aDocument.InitDrawLayer(this);
        pDrawLayer = aDocument.GetDrawLayer();
        InitItems();                                            // incl. Undo und Basic
        Broadcast( SfxSimpleHint( SC_HINT_DRWLAYER_NEW ) );
        if (nDocumentLock)
            pDrawLayer->setLock(TRUE);
    }
    return pDrawLayer;
}

//------------------------------------------------------------------

void ScDocShell::RemoveUnknownObjects()
{
    //  OLE-Objekte loeschen, wenn kein Drawing-Objekt dazu existiert
    //  Loeschen wie in SvPersist::CleanUp

    ScDrawLayer* pDrawLayer = aDocument.GetDrawLayer();
    uno::Sequence < rtl::OUString > aNames = GetEmbeddedObjectContainer().GetObjectNames();

        for( sal_Int32 i=0; i<aNames.getLength(); i++ )
        {
            String aObjName = aNames[i];
            BOOL bFound = FALSE;
            if ( pDrawLayer )
            {
                SCTAB nTabCount = static_cast<sal_Int16>(pDrawLayer->GetPageCount());
                for (SCTAB nTab=0; nTab<nTabCount && !bFound; nTab++)
                {
                    SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab));
                    DBG_ASSERT(pPage,"Page ?");
                    if (pPage)
                    {
                        SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS );
                        SdrObject* pObject = aIter.Next();
                        while (pObject && !bFound)
                        {
                            // name from InfoObject is PersistName
                            if ( pObject->ISA(SdrOle2Obj) &&
                                    static_cast<SdrOle2Obj*>(pObject)->GetPersistName() == aObjName )
                                bFound = TRUE;
                            pObject = aIter.Next();
                        }
                    }
                }
            }

            if (!bFound)
            {
                //TODO/LATER: hacks not supported anymore
                //DBG_ASSERT(pEle->GetRefCount()==2, "Loeschen von referenziertem Storage");
                GetEmbeddedObjectContainer().RemoveEmbeddedObject( aObjName );
            }
            else
                i++;
        }
}

<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_LINEARSOLVER_MinResLinearSolver_INL
#define SOFA_COMPONENT_LINEARSOLVER_MinResLinearSolver_INL

#include <sofa/component/linearsolver/MinResLinearSolver.h>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/component/linearsolver/FullMatrix.h>
#include <sofa/component/linearsolver/SparseMatrix.h>
#include <sofa/component/linearsolver/CompressedRowSparseMatrix.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/helper/system/thread/CTime.h>
#include <sofa/helper/AdvancedTimer.h>

#include <sofa/core/ObjectFactory.h>
#include <iostream>

namespace sofa
{

namespace component
{

namespace linearsolver
{
using core::VecId;
using namespace sofa::defaulttype;
using namespace sofa::core::behavior;
using namespace sofa::simulation;

/// Linear system solver using the conjugate gradient iterative algorithm
template<class TMatrix, class TVector>
MinResLinearSolver<TMatrix,TVector>::MinResLinearSolver()
    : f_maxIter( initData(&f_maxIter,(unsigned)25,"iterations","maximum number of iterations of the Conjugate Gradient solution") )
    , f_tolerance( initData(&f_tolerance,1e-5,"tolerance","desired precision of the Conjugate Gradient Solution (ratio of current residual norm over initial residual norm)") )
    , f_verbose( initData(&f_verbose,false,"verbose","Dump system state at each iteration") )
    , f_graph( initData(&f_graph,"graph","Graph of residuals at each iteration") )
{
    f_graph.setWidget("graph");
//    f_graph.setReadOnly(true);
}

template<class TMatrix, class TVector>
void MinResLinearSolver<TMatrix,TVector>::resetSystem()
{
    f_graph.beginEdit()->clear();
    f_graph.endEdit();

    Inherit::resetSystem();
}

template<class TMatrix, class TVector>
void MinResLinearSolver<TMatrix,TVector>::setSystemMBKMatrix(const sofa::core::MechanicalParams* mparams)
{
    Inherit::setSystemMBKMatrix(mparams);
}

/// Solve Ax=b
/// code issued (and modified) from tminres (https://code.google.com/p/tminres/)
// - Umberto Villa, Emory University - uvilla@emory.edu
// - Michael Saunders, Stanford University
// - Santiago Akle, Stanford University
template<class TMatrix, class TVector>
void MinResLinearSolver<TMatrix,TVector>::solve(Matrix& A, Vector& x, Vector& b)
{
    const double& tol = f_tolerance.getValue();
    const unsigned& max_iter = f_maxIter.getValue();

    double eps(std::numeric_limits<double>::epsilon());
    int istop(0);
    unsigned itn(0);
    double Anorm(0.0), Acond(0.0)/*, Arnorm(0.0)*/;
    double rnorm(0.0), ynorm(0.0);
    bool done(false);

    // Step 1
    /*
     * Set up y and v for the first Lanczos vector v1.
     * y = beta1 P' v1, where P = C^(-1).
     * v is really P'v1
     */

    const core::ExecParams* params = core::ExecParams::defaultInstance();
    typename Inherit::TempVectorContainer vtmp(this, params, A, x, b);
    Vector& r1 = *vtmp.createTempVector();
    Vector& y  = *vtmp.createTempVector();
    Vector& w  = *vtmp.createTempVector();
    Vector& w1 = *vtmp.createTempVector();
    Vector& w2 = *vtmp.createTempVector();
    Vector& r2 = *vtmp.createTempVector();
    Vector& v  = *vtmp.createTempVector();

    r1 = A * x;
//    r1 = b - r1;
    r1 *= -1;
    r1 += b;

    y = r1;

    double beta1(0.0);
    beta1 = r1.dot( y );

    // Test for an indefined preconditioner
    // If b = 0 exactly stop with x = x0.

    if(beta1 < 0.0)
    {
        istop = 9;
        done = true;
    }
    else
    {
        if(beta1 == 0.0)
        {
            done = true;
        }
        else
            beta1 = sqrt(beta1); // Normalize y to get v1 later
    }

    // TODO: port symmetry checks for A

    // STEP 2
    /* Initialize other quantities */
    double oldb(0.0), beta(beta1), dbar(0.0), epsln(0.0), oldeps(0.0);
    double qrnorm(beta1), phi(0.0), phibar(beta1), rhs1(beta1);
    double rhs2(0.0), tnorm2(0.0), ynorm2(0.0);
    double cs(-1.0), sn(0.0);
    double gmax(0.0), gmin(std::numeric_limits<double>::max( ));
    double alpha(0.0), gamma(0.0);
    double delta(0.0), gbar(0.0);
    double z(0.0);

//    ( w ) = (* w1 ) = ( w2 ) = 0.0;
    r2 = r1;

    /* Main Iteration */
    if(!done)
    {
        for(itn = 0; itn < max_iter; ++itn)
        {
            // STEP 3
            /*
            -----------------------------------------------------------------
            Obtain quantities for the next Lanczos vector vk+1, k = 1, 2,...
            The general iteration is similar to the case k = 1 with v0 = 0:

            p1      = Operator * v1  -  beta1 * v0,
            alpha1  = v1'p1,
            q2      = p2  -  alpha1 * v1,
            beta2^2 = q2'q2,
            v2      = (1/beta2) q2.

            Again, y = betak P vk,  where  P = C**(-1).
            .... more description needed.
            -----------------------------------------------------------------
             */
            double s(1./beta); //Normalize previous vector (in y)
            v  = y;
            v *= s;         // v = vk if P = I

            y = A * v;
            if(itn) y.peq( r1, -beta/oldb );

            alpha = v.dot( y );	// alphak
            y.peq( r2, -alpha/beta ); // y += -a/b * r2
            r1 = r2;
            r2 = y;
            y = r2;

            oldb = beta; //oldb = betak
            beta = r2.dot( y );

            if(beta < 0)
            {
                istop = 9;
                break;
            }

            beta = sqrt(beta);
            tnorm2 += alpha*alpha + oldb*oldb + beta*beta;

            if(itn == 0)	//Initialize a few things
            {
                if(beta/beta1 < 10.0*eps)
                    istop = 10;
            }

            // Apply previous rotation Q_{k-1} to get
            // [delta_k epsln_{k+1}] = [cs sn]  [dbar_k 0]
            // [gbar_k   dbar_{k+1}]   [sn -cs] [alpha_k beta_{k+1}].
            oldeps = epsln;
            delta  = cs*dbar + sn*alpha;
            gbar   = sn*dbar - cs*alpha;
            epsln  =           sn*beta;
            dbar   =         - cs*beta;
            double root(sqrt(gbar*gbar + dbar*dbar));
            //Arnorm = phibar * root; // ||Ar_{k-1}||

            // Compute next plane rotation Q_k
            gamma = sqrt(gbar*gbar + beta*beta); // gamma_k
            gamma = std::max(gamma, eps);
            cs = gbar/gamma;                     // c_k
            sn = beta/gamma;                     // s_k
            phi = cs*phibar;                     // phi_k
            phibar = sn*phibar;                  // phibar_{k+1}

            // Update x
            double denom(1./gamma);
            w1 = w2;
            w2 = w;

            // add(-oldeps, w1, -delta, w2, w);
            w = w1;
            w *= -oldeps;
            w.peq( w2, -delta );
//            add(denom, v, w, w);
            w *= denom;
            w.peq( v, denom );
//            add(x, phi, w, x);
            x.peq( w, phi );

            // go round again
            gmax    = std::max(gmax, gamma);
            gmin    = std::min(gmin, gamma);
            z       = rhs1/gamma;
            rhs1    = rhs2 - delta*z;
            rhs2    =      - epsln*z;

            // Estimate various norms

            Anorm = sqrt(tnorm2);
            ynorm2 = x.dot( x );
            ynorm = sqrt(ynorm2);
            double epsa(Anorm*eps);
            double epsx(epsa*ynorm);
//            double epsr(Anorm*ynorm*tol);
            double diag(gbar);
            if(0 == diag)
                diag = epsa;

            qrnorm = phibar;
            rnorm  = qrnorm;
            double test1(0.0), test2(0.0);
            test1  = rnorm/(Anorm*ynorm); // ||r||/(||A|| ||x||)
            test2  = root/ Anorm;         // ||A r_{k-1}|| / (||A|| ||r_{k-1}||)

            // Estimate cond(A)
            /*
             In this version we look at the diagonals of  R  in the
             factorization of the lower Hessenberg matrix,  Q * H = R,
             where H is the tridiagonal matrix from Lanczos with one
             extra row, beta(k+1) e_k^T.
             */
            Acond = gmax/gmin;

            //See if any of the stopping criteria is satisfied
            if(0 == istop)
            {
                double t1(1.0+test1), t2(1.0+test2); //This test work if tol < eps
                if(t2 <= 1.) istop = 2;
                if(t1 <= 1.) istop = 1;

                if(itn >= max_iter-1) istop = 6;
                if(Acond >= .1/eps) istop = 4;
                if(epsx >= beta1)   istop = 3;
                if(test2 <= tol  )  istop = 2;
                if(test1 <= tol)    istop = 1;
            }

            if(0 != istop)
                break;

        }

        vtmp.deleteTempVector(&r1);
        vtmp.deleteTempVector(&y);
        vtmp.deleteTempVector(&w);
        vtmp.deleteTempVector(&w1);
        vtmp.deleteTempVector(&w2);
        vtmp.deleteTempVector(&r2);
        vtmp.deleteTempVector(&v);
    }
}

} // namespace linearsolver

} // namespace component

} // namespace sofa

#endif // SOFA_COMPONENT_LINEARSOLVER_MinResLinearSolver_INL
<commit_msg>r9215/sofa : added convergence graph for MINRES<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_LINEARSOLVER_MinResLinearSolver_INL
#define SOFA_COMPONENT_LINEARSOLVER_MinResLinearSolver_INL

#include <sofa/component/linearsolver/MinResLinearSolver.h>
#include <sofa/core/visual/VisualParams.h>
#include <sofa/component/linearsolver/FullMatrix.h>
#include <sofa/component/linearsolver/SparseMatrix.h>
#include <sofa/component/linearsolver/CompressedRowSparseMatrix.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/helper/system/thread/CTime.h>
#include <sofa/helper/AdvancedTimer.h>

#include <sofa/core/ObjectFactory.h>
#include <iostream>

namespace sofa
{

namespace component
{

namespace linearsolver
{
using core::VecId;
using namespace sofa::defaulttype;
using namespace sofa::core::behavior;
using namespace sofa::simulation;

/// Linear system solver using the conjugate gradient iterative algorithm
template<class TMatrix, class TVector>
MinResLinearSolver<TMatrix,TVector>::MinResLinearSolver()
    : f_maxIter( initData(&f_maxIter,(unsigned)25,"iterations","maximum number of iterations of the Conjugate Gradient solution") )
    , f_tolerance( initData(&f_tolerance,1e-5,"tolerance","desired precision of the Conjugate Gradient Solution (ratio of current residual norm over initial residual norm)") )
    , f_verbose( initData(&f_verbose,false,"verbose","Dump system state at each iteration") )
    , f_graph( initData(&f_graph,"graph","Graph of residuals at each iteration") )
{
    f_graph.setWidget("graph");
//    f_graph.setReadOnly(true);
}

template<class TMatrix, class TVector>
void MinResLinearSolver<TMatrix,TVector>::resetSystem()
{
    f_graph.beginEdit()->clear();
    f_graph.endEdit();

    Inherit::resetSystem();
}

template<class TMatrix, class TVector>
void MinResLinearSolver<TMatrix,TVector>::setSystemMBKMatrix(const sofa::core::MechanicalParams* mparams)
{
    Inherit::setSystemMBKMatrix(mparams);
}

/// Solve Ax=b
/// code issued (and modified) from tminres (https://code.google.com/p/tminres/)
// - Umberto Villa, Emory University - uvilla@emory.edu
// - Michael Saunders, Stanford University
// - Santiago Akle, Stanford University
template<class TMatrix, class TVector>
void MinResLinearSolver<TMatrix,TVector>::solve(Matrix& A, Vector& x, Vector& b)
{
    const double& tol = f_tolerance.getValue();
    const unsigned& max_iter = f_maxIter.getValue();

    std::map < std::string, sofa::helper::vector<double> >& graph = *f_graph.beginEdit();
    sofa::helper::vector<double>& graph_error = graph[(this->isMultiGroup()) ? this->currentNode->getName()+std::string("-Error") : std::string("Error")];
    graph_error.clear();
    graph_error.push_back(1);

    double eps(std::numeric_limits<double>::epsilon());
    int istop(0);
    unsigned itn(0);
    double Anorm(0.0), Acond(0.0)/*, Arnorm(0.0)*/;
    double rnorm(0.0), ynorm(0.0);
    bool done(false);

    // Step 1
    /*
     * Set up y and v for the first Lanczos vector v1.
     * y = beta1 P' v1, where P = C^(-1).
     * v is really P'v1
     */

    const core::ExecParams* params = core::ExecParams::defaultInstance();
    typename Inherit::TempVectorContainer vtmp(this, params, A, x, b);
    Vector& r1 = *vtmp.createTempVector();
    Vector& y  = *vtmp.createTempVector();
    Vector& w  = *vtmp.createTempVector();
    Vector& w1 = *vtmp.createTempVector();
    Vector& w2 = *vtmp.createTempVector();
    Vector& r2 = *vtmp.createTempVector();
    Vector& v  = *vtmp.createTempVector();

    r1 = A * x;
//    r1 = b - r1;
    r1 *= -1;
    r1 += b;

    y = r1;

    double beta1(0.0);
    beta1 = r1.dot( y );

    // Test for an indefined preconditioner
    // If b = 0 exactly stop with x = x0.

    if(beta1 < 0.0)
    {
        istop = 9;
        done = true;
    }
    else
    {
        if(beta1 == 0.0)
        {
            done = true;
        }
        else
            beta1 = sqrt(beta1); // Normalize y to get v1 later
    }

    // TODO: port symmetry checks for A

    // STEP 2
    /* Initialize other quantities */
    double oldb(0.0), beta(beta1), dbar(0.0), epsln(0.0), oldeps(0.0);
    double qrnorm(beta1), phi(0.0), phibar(beta1), rhs1(beta1);
    double rhs2(0.0), tnorm2(0.0), ynorm2(0.0);
    double cs(-1.0), sn(0.0);
    double gmax(0.0), gmin(std::numeric_limits<double>::max( ));
    double alpha(0.0), gamma(0.0);
    double delta(0.0), gbar(0.0);
    double z(0.0);

//    ( w ) = (* w1 ) = ( w2 ) = 0.0;
    r2 = r1;

    /* Main Iteration */
    if(!done)
    {
        for(itn = 0; itn < max_iter; ++itn)
        {
            // STEP 3
            /*
            -----------------------------------------------------------------
            Obtain quantities for the next Lanczos vector vk+1, k = 1, 2,...
            The general iteration is similar to the case k = 1 with v0 = 0:

            p1      = Operator * v1  -  beta1 * v0,
            alpha1  = v1'p1,
            q2      = p2  -  alpha1 * v1,
            beta2^2 = q2'q2,
            v2      = (1/beta2) q2.

            Again, y = betak P vk,  where  P = C**(-1).
            .... more description needed.
            -----------------------------------------------------------------
             */
            double s(1./beta); //Normalize previous vector (in y)
            v  = y;
            v *= s;         // v = vk if P = I

            y = A * v;
            if(itn) y.peq( r1, -beta/oldb );

            alpha = v.dot( y );	// alphak
            y.peq( r2, -alpha/beta ); // y += -a/b * r2
            r1 = r2;
            r2 = y;
            y = r2;

            oldb = beta; //oldb = betak
            beta = r2.dot( y );

            if(beta < 0)
            {
                istop = 9;
                break;
            }

            beta = sqrt(beta);
            tnorm2 += alpha*alpha + oldb*oldb + beta*beta;

            if(itn == 0)	//Initialize a few things
            {
                if(beta/beta1 < 10.0*eps)
                    istop = 10;
            }

            // Apply previous rotation Q_{k-1} to get
            // [delta_k epsln_{k+1}] = [cs sn]  [dbar_k 0]
            // [gbar_k   dbar_{k+1}]   [sn -cs] [alpha_k beta_{k+1}].
            oldeps = epsln;
            delta  = cs*dbar + sn*alpha;
            gbar   = sn*dbar - cs*alpha;
            epsln  =           sn*beta;
            dbar   =         - cs*beta;
            double root(sqrt(gbar*gbar + dbar*dbar));
            //Arnorm = phibar * root; // ||Ar_{k-1}||

            // Compute next plane rotation Q_k
            gamma = sqrt(gbar*gbar + beta*beta); // gamma_k
            gamma = std::max(gamma, eps);
            cs = gbar/gamma;                     // c_k
            sn = beta/gamma;                     // s_k
            phi = cs*phibar;                     // phi_k
            phibar = sn*phibar;                  // phibar_{k+1}

            // Update x
            double denom(1./gamma);
            w1 = w2;
            w2 = w;

            // add(-oldeps, w1, -delta, w2, w);
            w = w1;
            w *= -oldeps;
            w.peq( w2, -delta );
//            add(denom, v, w, w);
            w *= denom;
            w.peq( v, denom );
//            add(x, phi, w, x);
            x.peq( w, phi );

            // go round again
            gmax    = std::max(gmax, gamma);
            gmin    = std::min(gmin, gamma);
            z       = rhs1/gamma;
            rhs1    = rhs2 - delta*z;
            rhs2    =      - epsln*z;

            // Estimate various norms

            Anorm = sqrt(tnorm2);
            ynorm2 = x.dot( x );
            ynorm = sqrt(ynorm2);
            double epsa(Anorm*eps);
            double epsx(epsa*ynorm);
//            double epsr(Anorm*ynorm*tol);
            double diag(gbar);
            if(0 == diag)
                diag = epsa;

            qrnorm = phibar;
            rnorm  = qrnorm;
            double test1(0.0), test2(0.0);
            test1  = rnorm/(Anorm*ynorm); // ||r||/(||A|| ||x||)
            test2  = root/ Anorm;         // ||A r_{k-1}|| / (||A|| ||r_{k-1}||)

            graph_error.push_back(test1);

            // Estimate cond(A)
            /*
             In this version we look at the diagonals of  R  in the
             factorization of the lower Hessenberg matrix,  Q * H = R,
             where H is the tridiagonal matrix from Lanczos with one
             extra row, beta(k+1) e_k^T.
             */
            Acond = gmax/gmin;

            //See if any of the stopping criteria is satisfied
            if(0 == istop)
            {
                double t1(1.0+test1), t2(1.0+test2); //This test work if tol < eps
                if(t2 <= 1.) istop = 2;
                if(t1 <= 1.) istop = 1;

                if(itn >= max_iter-1) istop = 6;
                if(Acond >= .1/eps) istop = 4;
                if(epsx >= beta1)   istop = 3;
                if(test2 <= tol  )  istop = 2;
                if(test1 <= tol)    istop = 1;
            }

            if(0 != istop)
                break;

        }

        vtmp.deleteTempVector(&r1);
        vtmp.deleteTempVector(&y);
        vtmp.deleteTempVector(&w);
        vtmp.deleteTempVector(&w1);
        vtmp.deleteTempVector(&w2);
        vtmp.deleteTempVector(&r2);
        vtmp.deleteTempVector(&v);
    }
}

} // namespace linearsolver

} // namespace component

} // namespace sofa

#endif // SOFA_COMPONENT_LINEARSOLVER_MinResLinearSolver_INL
<|endoftext|>


<commit_before>#include <Halide.h>
using namespace Halide;

Var x, y;

// Downsample with a 1 3 3 1 filter
Func downsample(Func f) {
    Func downx, downy;

    downx(x, y, _) = (f(2*x-1, y, _) + 3.0f * (f(2*x, y, _) + f(2*x+1, y, _)) + f(2*x+2, y, _)) / 8.0f;
    downy(x, y, _) = (downx(x, 2*y-1, _) + 3.0f * (downx(x, 2*y, _) + downx(x, 2*y+1, _)) + downx(x, 2*y+2, _)) / 8.0f;

    return downy;
}

// Upsample using bilinear interpolation
Func upsample(Func f) {
    Func upx, upy;

    upx(x, y, _) = 0.25f * f((x/2) - 1 + 2*(x % 2), y, _) + 0.75f * f(x/2, y, _);
    upy(x, y, _) = 0.25f * upx(x, (y/2) - 1 + 2*(y % 2), _) + 0.75f * upx(x, y/2, _);

    return upy;

}

int main(int argc, char **argv) {

    /* THE ALGORITHM */

    // Number of pyramid levels
    const int J = 8;

    // number of intensity levels
    Param<int> levels;
    // Parameters controlling the filter
    Param<float> alpha, beta;
    // Takes a 16-bit input
    ImageParam input(UInt(16), 3);

    // loop variables
    Var c, k;

    // Make the remapping function as a lookup table.
    Func remap;
    Expr fx = cast<float>(x) / 256.0f;
    remap(x) = alpha*fx*exp(-fx*fx/2.0f);

    // Convert to floating point
    Func floating;
    floating(x, y, c) = cast<float>(input(x, y, c)) / 65535.0f;

    // Set a boundary condition
    Func clamped;
    clamped(x, y, c) = floating(clamp(x, 0, input.width()-1), clamp(y, 0, input.height()-1), c);

    // Get the luminance channel
    Func gray;
    gray(x, y) = 0.299f * clamped(x, y, 0) + 0.587f * clamped(x, y, 1) + 0.114f * clamped(x, y, 2);

    // Make the processed Gaussian pyramid.
    Func gPyramid[J];
    // Do a lookup into a lut with 256 entires per intensity level
    Expr level = k * (1.0f / (levels - 1));
    Expr idx = gray(x, y)*cast<float>(levels-1)*256.0f;
    idx = clamp(cast<int>(idx), 0, (levels-1)*256);
    gPyramid[0](x, y, k) = beta*(gray(x, y) - level) + level + remap(idx - 256*k);
    for (int j = 1; j < J; j++) {
        gPyramid[j](x, y, k) = downsample(gPyramid[j-1])(x, y, k);
    }

    // Get its laplacian pyramid
    Func lPyramid[J];
    lPyramid[J-1](x, y, k) = gPyramid[J-1](x, y, k);
    for (int j = J-2; j >= 0; j--) {
        lPyramid[j](x, y, k) = gPyramid[j](x, y, k) - upsample(gPyramid[j+1])(x, y, k);
    }

    // Make the Gaussian pyramid of the input
    Func inGPyramid[J];
    inGPyramid[0](x, y) = gray(x, y);
    for (int j = 1; j < J; j++) {
        inGPyramid[j](x, y) = downsample(inGPyramid[j-1])(x, y);
    }

    // Make the laplacian pyramid of the output
    Func outLPyramid[J];
    for (int j = 0; j < J; j++) {
        // Split input pyramid value into integer and floating parts
        Expr level = inGPyramid[j](x, y) * cast<float>(levels-1);
        Expr li = clamp(cast<int>(level), 0, levels-2);
        Expr lf = level - cast<float>(li);
        // Linearly interpolate between the nearest processed pyramid levels
        outLPyramid[j](x, y) = (1.0f - lf) * lPyramid[j](x, y, li) + lf * lPyramid[j](x, y, li+1);
    }

    // Make the Gaussian pyramid of the output
    Func outGPyramid[J];
    outGPyramid[J-1](x, y) = outLPyramid[J-1](x, y);
    for (int j = J-2; j >= 0; j--) {
        outGPyramid[j](x, y) = upsample(outGPyramid[j+1])(x, y) + outLPyramid[j](x, y);
    }

    // Reintroduce color (Connelly: use eps to avoid scaling up noise w/ apollo3.png input)
    Func color;
    float eps = 0.01f;
    color(x, y, c) = outGPyramid[0](x, y) * (clamped(x, y, c)+eps) / (gray(x, y)+eps);

    Func output("local_laplacian");
    // Convert back to 16-bit
    output(x, y, c) = cast<uint16_t>(clamp(color(x, y, c), 0.0f, 1.0f) * 65535.0f);

    /* THE SCHEDULE */
    remap.compute_root();

    Target target = get_target_from_environment();
    if (target.has_gpu_feature()) {
        // gpu schedule
        output.compute_root().gpu_tile(x, y, 32, 16, GPU_Default);
        for (int j = 0; j < J; j++) {
            int blockw = 32, blockh = 16;
            if (j > 3) {
                blockw = 2;
                blockh = 2;
            }
            if (j > 0) inGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, GPU_Default);
            if (j > 0) gPyramid[j].compute_root().reorder(k, x, y).gpu_tile(x, y, blockw, blockh, GPU_Default);
            outGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, GPU_Default);
        }
    } else {
        // cpu schedule
        Var yi;
        output.parallel(y, 4).vectorize(x, 4);
        gray.compute_root().parallel(y, 4).vectorize(x, 4);
        for (int j = 0; j < 4; j++) {
            if (j > 0) inGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 4);
            if (j > 0) gPyramid[j].compute_root().parallel(y, 4).vectorize(x, 4);
            outGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 4);
        }
        for (int j = 4; j < J; j++) {
            inGPyramid[j].compute_root().parallel(y);
            gPyramid[j].compute_root().parallel(k);
            outGPyramid[j].compute_root().parallel(y);
        }
    }

    output.compile_to_file("local_laplacian", levels, alpha, beta, input, target);

    return 0;
}

<commit_msg>Reduce block size for local laplacian for lesser gpus<commit_after>#include <Halide.h>
using namespace Halide;

Var x, y;

// Downsample with a 1 3 3 1 filter
Func downsample(Func f) {
    Func downx, downy;

    downx(x, y, _) = (f(2*x-1, y, _) + 3.0f * (f(2*x, y, _) + f(2*x+1, y, _)) + f(2*x+2, y, _)) / 8.0f;
    downy(x, y, _) = (downx(x, 2*y-1, _) + 3.0f * (downx(x, 2*y, _) + downx(x, 2*y+1, _)) + downx(x, 2*y+2, _)) / 8.0f;

    return downy;
}

// Upsample using bilinear interpolation
Func upsample(Func f) {
    Func upx, upy;

    upx(x, y, _) = 0.25f * f((x/2) - 1 + 2*(x % 2), y, _) + 0.75f * f(x/2, y, _);
    upy(x, y, _) = 0.25f * upx(x, (y/2) - 1 + 2*(y % 2), _) + 0.75f * upx(x, y/2, _);

    return upy;

}

int main(int argc, char **argv) {

    /* THE ALGORITHM */

    // Number of pyramid levels
    const int J = 8;

    // number of intensity levels
    Param<int> levels;
    // Parameters controlling the filter
    Param<float> alpha, beta;
    // Takes a 16-bit input
    ImageParam input(UInt(16), 3);

    // loop variables
    Var c, k;

    // Make the remapping function as a lookup table.
    Func remap;
    Expr fx = cast<float>(x) / 256.0f;
    remap(x) = alpha*fx*exp(-fx*fx/2.0f);

    // Convert to floating point
    Func floating;
    floating(x, y, c) = cast<float>(input(x, y, c)) / 65535.0f;

    // Set a boundary condition
    Func clamped;
    clamped(x, y, c) = floating(clamp(x, 0, input.width()-1), clamp(y, 0, input.height()-1), c);

    // Get the luminance channel
    Func gray;
    gray(x, y) = 0.299f * clamped(x, y, 0) + 0.587f * clamped(x, y, 1) + 0.114f * clamped(x, y, 2);

    // Make the processed Gaussian pyramid.
    Func gPyramid[J];
    // Do a lookup into a lut with 256 entires per intensity level
    Expr level = k * (1.0f / (levels - 1));
    Expr idx = gray(x, y)*cast<float>(levels-1)*256.0f;
    idx = clamp(cast<int>(idx), 0, (levels-1)*256);
    gPyramid[0](x, y, k) = beta*(gray(x, y) - level) + level + remap(idx - 256*k);
    for (int j = 1; j < J; j++) {
        gPyramid[j](x, y, k) = downsample(gPyramid[j-1])(x, y, k);
    }

    // Get its laplacian pyramid
    Func lPyramid[J];
    lPyramid[J-1](x, y, k) = gPyramid[J-1](x, y, k);
    for (int j = J-2; j >= 0; j--) {
        lPyramid[j](x, y, k) = gPyramid[j](x, y, k) - upsample(gPyramid[j+1])(x, y, k);
    }

    // Make the Gaussian pyramid of the input
    Func inGPyramid[J];
    inGPyramid[0](x, y) = gray(x, y);
    for (int j = 1; j < J; j++) {
        inGPyramid[j](x, y) = downsample(inGPyramid[j-1])(x, y);
    }

    // Make the laplacian pyramid of the output
    Func outLPyramid[J];
    for (int j = 0; j < J; j++) {
        // Split input pyramid value into integer and floating parts
        Expr level = inGPyramid[j](x, y) * cast<float>(levels-1);
        Expr li = clamp(cast<int>(level), 0, levels-2);
        Expr lf = level - cast<float>(li);
        // Linearly interpolate between the nearest processed pyramid levels
        outLPyramid[j](x, y) = (1.0f - lf) * lPyramid[j](x, y, li) + lf * lPyramid[j](x, y, li+1);
    }

    // Make the Gaussian pyramid of the output
    Func outGPyramid[J];
    outGPyramid[J-1](x, y) = outLPyramid[J-1](x, y);
    for (int j = J-2; j >= 0; j--) {
        outGPyramid[j](x, y) = upsample(outGPyramid[j+1])(x, y) + outLPyramid[j](x, y);
    }

    // Reintroduce color (Connelly: use eps to avoid scaling up noise w/ apollo3.png input)
    Func color;
    float eps = 0.01f;
    color(x, y, c) = outGPyramid[0](x, y) * (clamped(x, y, c)+eps) / (gray(x, y)+eps);

    Func output("local_laplacian");
    // Convert back to 16-bit
    output(x, y, c) = cast<uint16_t>(clamp(color(x, y, c), 0.0f, 1.0f) * 65535.0f);

    /* THE SCHEDULE */
    remap.compute_root();

    Target target = get_target_from_environment();
    if (target.has_gpu_feature()) {
        // gpu schedule
        output.compute_root().gpu_tile(x, y, 16, 8, GPU_Default);
        for (int j = 0; j < J; j++) {
            int blockw = 16, blockh = 8;
            if (j > 3) {
                blockw = 2;
                blockh = 2;
            }
            if (j > 0) inGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, GPU_Default);
            if (j > 0) gPyramid[j].compute_root().reorder(k, x, y).gpu_tile(x, y, blockw, blockh, GPU_Default);
            outGPyramid[j].compute_root().gpu_tile(x, y, blockw, blockh, GPU_Default);
        }
    } else {
        // cpu schedule
        Var yi;
        output.parallel(y, 4).vectorize(x, 4);
        gray.compute_root().parallel(y, 4).vectorize(x, 4);
        for (int j = 0; j < 4; j++) {
            if (j > 0) inGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 4);
            if (j > 0) gPyramid[j].compute_root().parallel(y, 4).vectorize(x, 4);
            outGPyramid[j].compute_root().parallel(y, 4).vectorize(x, 4);
        }
        for (int j = 4; j < J; j++) {
            inGPyramid[j].compute_root().parallel(y);
            gPyramid[j].compute_root().parallel(k);
            outGPyramid[j].compute_root().parallel(y);
        }
    }

    output.compile_to_file("local_laplacian", levels, alpha, beta, input, target);

    return 0;
}

<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <pcl/point_types.h>
#include <pcl/impl/instantiate.hpp>
#include <pcl/apps/dominant_plane_segmentation.h>
#include <pcl/apps/impl/dominant_plane_segmentation.hpp>

// Instantiations of specific point types
PCL_INSTANTIATE(DominantPlaneSegmentation, PCL_XYZ_POINT_TYPES)
<commit_msg>Added PCL_ONLY_CORE_POINT_TYPES.<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2010, Willow Garage, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Willow Garage, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <pcl/point_types.h>
#include <pcl/impl/instantiate.hpp>
#include <pcl/apps/dominant_plane_segmentation.h>
#include <pcl/apps/impl/dominant_plane_segmentation.hpp>

#ifdef PCL_ONLY_CORE_POINT_TYPES
  PCL_INSTANTIATE(DominantPlaneSegmentation, (pcl::PointXYZ)(pcl::PointXYZI)(pcl::PointXYZRGBA)(pcl::PointXYZRGB))
#else
  PCL_INSTANTIATE(DominantPlaneSegmentation, PCL_XYZ_POINT_TYPES)
#endif
<|endoftext|>


<commit_before>#include "service_pool.h"
#include <sys/uio.h>
#include <sys/eventfd.h>
#include "sockets.h"
#include "loop.h"
#include "logging.h"
#include "redis_proxy.h"

namespace smart {

ServicePool& ServicePool::get_instance()
{
    static ServicePool pool;
    return pool;
}

ServProc::ServProc(int fd, MPMCQueue<Letter>& letters):
    LoopThread("service_processor"),
    _queue_read_io(new IO(fd, EV_READ, false)),
    _letters(&letters)
{
}

bool ServProc::prepare()
{
    _queue_read_io->on_read([this]() {
        eventfd_t num = 0;
        eventfd_read(_queue_read_io->fd(), &num);
        for (auto i = 0; i < num; ++i) {
            Letter letter;
            if (!_letters->pop(&letter)) {
                break;
            }

            SLOG(INFO) << "begin to parse:" << letter.second->content();
            shared_json request;
            shared_json response;
            if (!letter.second->content().empty()) {
                request = std::make_shared<json>(
                    json::parse(letter.second->content()));
            } else {
                request = std::make_shared<json>();
            }
            response = std::make_shared<json>();
            std::shared_ptr<Control> ctrl = std::make_shared<Control>(letter, response);

            SLOG(INFO) << "begin to call method: " << letter.second->get_service_name()
                       << " " << letter.second->get_method_name();
            ServicePool::get_instance()
                .find_service(letter.second->get_service_name())
                ->find_method(letter.second->get_method_name())(request, response, ctrl);
        }
    });

    return get_local_loop()->add_io(_queue_read_io);
}

void ServProc::process_end()
{
    get_local_loop()->remove_io(_queue_read_io);
}

Service::Method Service::_default_method =
    [](const shared_json&, shared_json& response, SControl&) {
        (*response)["status"] = "fail";
        (*response)["message"] = "method not found";
    };

bool ServicePool::run()
{
    _queue_write_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
    if (_queue_write_fd < 0) {
        SLOG(WARNING) << "get eventfd fail!";
        return false;
    }

    for(int i = 0; i < std::thread::hardware_concurrency(); ++i) {
        _proc_pool.emplace_back(new ServProc(_queue_write_fd, _letters));
        if (!_proc_pool.back()->run()) {
            return false;
        }
    }

    return true;
}

void ServicePool::stop()
{
    for (auto &proc : _proc_pool) {
        proc->stop();
    }
    rpc::close(_queue_write_fd);
}

void ServicePool::send(Letter&& letter)
{
    _letters.push(letter);
    eventfd_write(_queue_write_fd, 1);
}

}

<commit_msg>add try catch codes<commit_after>#include "service_pool.h"
#include <sys/uio.h>
#include <sys/eventfd.h>
#include "sockets.h"
#include "loop.h"
#include "logging.h"
#include "redis_proxy.h"

namespace smart {

ServicePool& ServicePool::get_instance()
{
    static ServicePool pool;
    return pool;
}

ServProc::ServProc(int fd, MPMCQueue<Letter>& letters):
    LoopThread("service_processor"),
    _queue_read_io(new IO(fd, EV_READ, false)),
    _letters(&letters)
{
}

bool ServProc::prepare()
{
    _queue_read_io->on_read([this]() {
        eventfd_t num = 0;
        eventfd_read(_queue_read_io->fd(), &num);
        for (auto i = 0; i < num; ++i) {
            Letter letter;
            if (!_letters->pop(&letter)) {
                break;
            }

            SLOG(INFO) << "begin to parse:" << letter.second->content();
            auto response = std::make_shared<json>();
            auto ctrl = std::make_shared<Control>(letter, response);
            try {
            auto request = std::make_shared<json>(
                        json::parse(letter.second->content()));

                SLOG(INFO) << "begin to call method: " << letter.second->get_service_name()
                           << " " << letter.second->get_method_name();
                ServicePool::get_instance()
                    .find_service(letter.second->get_service_name())
                ->find_method(letter.second->get_method_name())(request, response, ctrl);
            } catch (std::exception& ex) {
                LOG(WARNING) << "catch error:" << ex.what();
                (*response)["code"] = static_cast<int>(ErrCode::PARAM_ERROR);
                (*response)["message"] = ex.what();
            }
        }
    });

    return get_local_loop()->add_io(_queue_read_io);
}

void ServProc::process_end()
{
    get_local_loop()->remove_io(_queue_read_io);
}

Service::Method Service::_default_method =
    [](const shared_json&, shared_json& response, SControl&) {
        (*response)["code"] = static_cast<int>(ErrCode::PARAM_ERROR);
        (*response)["message"] = "method not found";
    };

bool ServicePool::run()
{
    _queue_write_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
    if (_queue_write_fd < 0) {
        SLOG(WARNING) << "get eventfd fail!";
        return false;
    }

    for(int i = 0; i < std::thread::hardware_concurrency(); ++i) {
        _proc_pool.emplace_back(new ServProc(_queue_write_fd, _letters));
        if (!_proc_pool.back()->run()) {
            return false;
        }
    }

    return true;
}

void ServicePool::stop()
{
    for (auto &proc : _proc_pool) {
        proc->stop();
    }
    rpc::close(_queue_write_fd);
}

void ServicePool::send(Letter&& letter)
{
    _letters.push(letter);
    eventfd_write(_queue_write_fd, 1);
}

}

<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2013 Aaron McCarthy <mccarthy.aaron@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
** 2015.4.4
** Adapted for use with QGroundControl
**
** Gus Grubba <mavlink@grubba.com>
**
****************************************************************************/

#include "QGCMapEngine.h"
#include "QGeoTiledMappingManagerEngineQGC.h"
#include "QGeoTileFetcherQGC.h"

#include <QtLocation/private/qgeocameracapabilities_p.h>
#include <QtLocation/private/qgeomaptype_p.h>
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include <QtLocation/private/qgeotiledmapdata_p.h>
#else
#include <QtLocation/private/qgeotiledmap_p.h>
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
#include <QtLocation/private/qgeofiletilecache_p.h>
#else
#include <QtLocation/private/qgeotilecache_p.h>
#endif
#endif

#include <QDir>
#include <QStandardPaths>

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
//-----------------------------------------------------------------------------
QGeoTiledMapQGC::QGeoTiledMapQGC(QGeoTiledMappingManagerEngine *engine, QObject *parent)
    : QGeoTiledMap(engine, parent)
{

}
#endif

#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
#define QGCGEOMAPTYPE(a,b,c,d,e,f)  QGeoMapType(a,b,c,d,e,f,QByteArray("QGroundControl"), QGeoCameraCapabilities())
#elif QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
#define QGCGEOMAPTYPE(a,b,c,d,e,f)  QGeoMapType(a,b,c,d,e,f,QByteArray("QGroundControl"))
#else
#define QGCGEOMAPTYPE(a,b,c,d,e,f)  QGeoMapType(a,b,c,d,e,f)
#endif

//-----------------------------------------------------------------------------
QGeoTiledMappingManagerEngineQGC::QGeoTiledMappingManagerEngineQGC(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)
:   QGeoTiledMappingManagerEngine()
{

    QGeoCameraCapabilities cameraCaps;
    cameraCaps.setMinimumZoomLevel(2.0);
    cameraCaps.setMaximumZoomLevel(MAX_MAP_ZOOM);
    cameraCaps.setSupportsBearing(true);
    setCameraCapabilities(cameraCaps);

    setTileSize(QSize(256, 256));

    /*
     * Google and Bing don't seem kosher at all. This was based on original code from OpenPilot and heavily modified to be used in QGC.
     */

    //-- IMPORTANT
    //   Changes here must reflect those in QGCMapEngine.cpp

    QList<QGeoMapType> mapTypes;

#ifndef QGC_NO_GOOGLE_MAPS
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Google Street Map",        "Google street map",            false,  false,  UrlFactory::GoogleMap);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Google Satellite Map",     "Google satellite map",         false,  false,  UrlFactory::GoogleSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Google Terrain Map",       "Google terrain map",           false,  false,  UrlFactory::GoogleTerrain);
#endif

    /* TODO:
     *  Proper google hybrid maps requires collecting two separate bitmaps and overlaying them.
     *
     * mapTypes << QGCGEOMAPTYPE(QGeoMapType::HybridMap,       "Google Hybrid Map",        "Google hybrid map",            false, false, UrlFactory::GoogleHybrid);
     *
     */

    // Bing
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Bing Street Map",          "Bing street map",                  false,  false,  UrlFactory::BingMap);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Bing Satellite Map",       "Bing satellite map",               false,  false,  UrlFactory::BingSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::HybridMap,         "Bing Hybrid Map",          "Bing hybrid map",                  false,  false,  UrlFactory::BingHybrid);

    // Statkart
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Statkart Terrain Map",     "Statkart Terrain Map",             false,  false,  UrlFactory::StatkartTopo);
    // Eniro
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Eniro Terrain Map",        "Eniro Terrain Map",                false,  false,  UrlFactory::EniroTopo);

    // Esri
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Esri Street Map",          "ArcGIS Online World Street Map",   true,   false,  UrlFactory::EsriWorldStreet);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Esri Satellite Map",       "ArcGIS Online World Imagery",      true,   false,  UrlFactory::EsriWorldSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Esri Terrain Map",         "World Terrain Base",               false,  false,  UrlFactory::EsriTerrain);

    /* See: https://wiki.openstreetmap.org/wiki/Tile_usage_policy
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Open Street Map",          "Open Street map",              false, false, UrlFactory::OpenStreetMap);
    */

    // MapQuest
    /*
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "MapQuest Street Map",      "MapQuest street map",          false,  false,  UrlFactory::MapQuestMap);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "MapQuest Satellite Map",   "MapQuest satellite map",       false,  false,  UrlFactory::MapQuestSat);
    */

    /*
     * These are OK as you need your own token for accessing it. Out-of-the box, QGC does not even offer these unless you enter a proper Mapbox token.
     */

    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Mapbox Street Map",        "Mapbox Street Map",            false,  false,  UrlFactory::MapboxStreets);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Mapbox Satellite Map",     "Mapbox Satellite Map",         false,  false,  UrlFactory::MapboxSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox High Contrast Map", "Mapbox High Contrast Map",     false,  false,  UrlFactory::MapboxHighContrast);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Light Map",         "Mapbox Light Map",             false,  false,  UrlFactory::MapboxLight);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Dark Map",          "Mapbox Dark Map",              false,  false,  UrlFactory::MapboxDark);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::HybridMap,         "Mapbox Hybrid Map",        "Mapbox Hybrid Map",            false,  false,  UrlFactory::MapboxHybrid);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Wheat Paste Map",   "Mapbox Wheat Paste Map",       false,  false,  UrlFactory::MapboxWheatPaste);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Mapbox Streets Basic Map", "Mapbox Streets Basic Map",     false,  false,  UrlFactory::MapboxStreetsBasic);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Comic Map",         "Mapbox Comic Map",             false,  false,  UrlFactory::MapboxComic);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Outdoors Map",      "Mapbox Outdoors Map",          false,  false,  UrlFactory::MapboxOutdoors);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CycleMap,          "Mapbox Run, Byke and Hike Map",   "Mapbox Run, Byke and Hike Map",     false,  false,  UrlFactory::MapboxRunBikeHike);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Pencil Map",        "Mapbox Pencil Map",            false,  false,  UrlFactory::MapboxPencil);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Pirates Map",       "Mapbox Pirates Map",           false,  false,  UrlFactory::MapboxPirates);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Emerald Map",       "Mapbox Emerald Map",           false,  false,  UrlFactory::MapboxEmerald);

    setSupportedMapTypes(mapTypes);

    //-- Users (QML code) can define a different user agent
    if (parameters.contains(QStringLiteral("useragent"))) {
        getQGCMapEngine()->setUserAgent(parameters.value(QStringLiteral("useragent")).toString().toLatin1());
    }

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
    _setCache(parameters);
#endif

    setTileFetcher(new QGeoTileFetcherQGC(this));

    *error = QGeoServiceProvider::NoError;
    errorString->clear();
}

//-----------------------------------------------------------------------------
QGeoTiledMappingManagerEngineQGC::~QGeoTiledMappingManagerEngineQGC()
{
}

#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)

//-----------------------------------------------------------------------------
QGeoMapData *QGeoTiledMappingManagerEngineQGC::createMapData()
{
    return new QGeoTiledMapData(this, 0);
}

#else

//-----------------------------------------------------------------------------
QGeoMap*
QGeoTiledMappingManagerEngineQGC::createMap()
{
    return new QGeoTiledMapQGC(this);
}

#endif

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
//-----------------------------------------------------------------------------
void
QGeoTiledMappingManagerEngineQGC::_setCache(const QVariantMap &parameters)
{
    QString cacheDir;
    if (parameters.contains(QStringLiteral("mapping.cache.directory")))
        cacheDir = parameters.value(QStringLiteral("mapping.cache.directory")).toString();
    else {
        cacheDir = getQGCMapEngine()->getCachePath();
        if(!QFileInfo(cacheDir).exists()) {
            if(!QDir::root().mkpath(cacheDir)) {
                qWarning() << "Could not create mapping disk cache directory: " << cacheDir;
                cacheDir = QDir::homePath() + QLatin1String("/.qgcmapscache/");
            }
        }
    }
    if(!QFileInfo(cacheDir).exists()) {
        if(!QDir::root().mkpath(cacheDir)) {
            qWarning() << "Could not create mapping disk cache directory: " << cacheDir;
            cacheDir.clear();
        }
    }
    //-- Memory Cache
    uint32_t memLimit = 0;
    if (parameters.contains(QStringLiteral("mapping.cache.memory.size"))) {
      bool ok = false;
      memLimit = parameters.value(QStringLiteral("mapping.cache.memory.size")).toString().toUInt(&ok);
      if (!ok)
          memLimit = 0;
    }
    if(!memLimit)
    {
        //-- Value saved in MB
        memLimit = getQGCMapEngine()->getMaxMemCache() * (1024 * 1024);
    }
    //-- It won't work with less than 1M of memory cache
    if(memLimit < 1024 * 1024)
        memLimit = 1024 * 1024;
    //-- On the other hand, Qt uses signed 32-bit integers. Limit to 1G to round it down (you don't need more than that).
    if(memLimit > 1024 * 1024 * 1024)
        memLimit = 1024 * 1024 * 1024;
    //-- Disable Qt's disk cache (sort of)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
    QAbstractGeoTileCache *pTileCache = new QGeoFileTileCache(cacheDir);
    setTileCache(pTileCache);
#else
    QGeoTileCache* pTileCache = createTileCacheWithDir(cacheDir);
#endif
    if(pTileCache)
    {
        //-- We're basically telling it to use 100k of disk for cache. It doesn't like
        //   values smaller than that and I could not find a way to make it NOT cache.
        //   We handle our own disk caching elsewhere.
        pTileCache->setMaxDiskUsage(1024 * 100);
        pTileCache->setMaxMemoryUsage(memLimit);
    }
}
#endif
<commit_msg>QGeoTiledMappingManagerEngineQGC: Use cameraCaps in QGeoMapType<commit_after>/****************************************************************************
**
** Copyright (C) 2013 Aaron McCarthy <mccarthy.aaron@gmail.com>
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.  For licensing terms and
** conditions see http://qt.digia.com/licensing.  For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights.  These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
** 2015.4.4
** Adapted for use with QGroundControl
**
** Gus Grubba <mavlink@grubba.com>
**
****************************************************************************/

#include "QGCMapEngine.h"
#include "QGeoTiledMappingManagerEngineQGC.h"
#include "QGeoTileFetcherQGC.h"

#include <QtLocation/private/qgeocameracapabilities_p.h>
#include <QtLocation/private/qgeomaptype_p.h>
#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
#include <QtLocation/private/qgeotiledmapdata_p.h>
#else
#include <QtLocation/private/qgeotiledmap_p.h>
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
#include <QtLocation/private/qgeofiletilecache_p.h>
#else
#include <QtLocation/private/qgeotilecache_p.h>
#endif
#endif

#include <QDir>
#include <QStandardPaths>

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
//-----------------------------------------------------------------------------
QGeoTiledMapQGC::QGeoTiledMapQGC(QGeoTiledMappingManagerEngine *engine, QObject *parent)
    : QGeoTiledMap(engine, parent)
{

}
#endif

//-----------------------------------------------------------------------------
QGeoTiledMappingManagerEngineQGC::QGeoTiledMappingManagerEngineQGC(const QVariantMap &parameters, QGeoServiceProvider::Error *error, QString *errorString)
:   QGeoTiledMappingManagerEngine()
{

    QGeoCameraCapabilities cameraCaps;
    cameraCaps.setMinimumZoomLevel(2.0);
    cameraCaps.setMaximumZoomLevel(MAX_MAP_ZOOM);
    cameraCaps.setSupportsBearing(true);
    setCameraCapabilities(cameraCaps);

    setTileSize(QSize(256, 256));

    // In Qt 5.10 QGeoMapType need QGeoCameraCapabilities as argument
    // E.g: https://github.com/qt/qtlocation/blob/2b230b0a10d898979e9d5193f4da2e408b397fe3/src/plugins/geoservices/osm/qgeotiledmappingmanagerengineosm.cpp#L167
    #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
    #define QGCGEOMAPTYPE(a,b,c,d,e,f)  QGeoMapType(a,b,c,d,e,f,QByteArray("QGroundControl"), cameraCaps)
    #elif QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
    #define QGCGEOMAPTYPE(a,b,c,d,e,f)  QGeoMapType(a,b,c,d,e,f,QByteArray("QGroundControl"))
    #else
    #define QGCGEOMAPTYPE(a,b,c,d,e,f)  QGeoMapType(a,b,c,d,e,f)
    #endif

    /*
     * Google and Bing don't seem kosher at all. This was based on original code from OpenPilot and heavily modified to be used in QGC.
     */

    //-- IMPORTANT
    //   Changes here must reflect those in QGCMapEngine.cpp

    QList<QGeoMapType> mapTypes;

#ifndef QGC_NO_GOOGLE_MAPS
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Google Street Map",        "Google street map",            false,  false,  UrlFactory::GoogleMap);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Google Satellite Map",     "Google satellite map",         false,  false,  UrlFactory::GoogleSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Google Terrain Map",       "Google terrain map",           false,  false,  UrlFactory::GoogleTerrain);
#endif

    /* TODO:
     *  Proper google hybrid maps requires collecting two separate bitmaps and overlaying them.
     *
     * mapTypes << QGCGEOMAPTYPE(QGeoMapType::HybridMap,       "Google Hybrid Map",        "Google hybrid map",            false, false, UrlFactory::GoogleHybrid);
     *
     */

    // Bing
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Bing Street Map",          "Bing street map",                  false,  false,  UrlFactory::BingMap);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Bing Satellite Map",       "Bing satellite map",               false,  false,  UrlFactory::BingSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::HybridMap,         "Bing Hybrid Map",          "Bing hybrid map",                  false,  false,  UrlFactory::BingHybrid);

    // Statkart
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Statkart Terrain Map",     "Statkart Terrain Map",             false,  false,  UrlFactory::StatkartTopo);
    // Eniro
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Eniro Terrain Map",        "Eniro Terrain Map",                false,  false,  UrlFactory::EniroTopo);

    // Esri
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Esri Street Map",          "ArcGIS Online World Street Map",   true,   false,  UrlFactory::EsriWorldStreet);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Esri Satellite Map",       "ArcGIS Online World Imagery",      true,   false,  UrlFactory::EsriWorldSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::TerrainMap,        "Esri Terrain Map",         "World Terrain Base",               false,  false,  UrlFactory::EsriTerrain);

    /* See: https://wiki.openstreetmap.org/wiki/Tile_usage_policy
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Open Street Map",          "Open Street map",              false, false, UrlFactory::OpenStreetMap);
    */

    // MapQuest
    /*
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "MapQuest Street Map",      "MapQuest street map",          false,  false,  UrlFactory::MapQuestMap);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "MapQuest Satellite Map",   "MapQuest satellite map",       false,  false,  UrlFactory::MapQuestSat);
    */

    /*
     * These are OK as you need your own token for accessing it. Out-of-the box, QGC does not even offer these unless you enter a proper Mapbox token.
     */

    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Mapbox Street Map",        "Mapbox Street Map",            false,  false,  UrlFactory::MapboxStreets);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::SatelliteMapDay,   "Mapbox Satellite Map",     "Mapbox Satellite Map",         false,  false,  UrlFactory::MapboxSatellite);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox High Contrast Map", "Mapbox High Contrast Map",     false,  false,  UrlFactory::MapboxHighContrast);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Light Map",         "Mapbox Light Map",             false,  false,  UrlFactory::MapboxLight);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Dark Map",          "Mapbox Dark Map",              false,  false,  UrlFactory::MapboxDark);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::HybridMap,         "Mapbox Hybrid Map",        "Mapbox Hybrid Map",            false,  false,  UrlFactory::MapboxHybrid);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Wheat Paste Map",   "Mapbox Wheat Paste Map",       false,  false,  UrlFactory::MapboxWheatPaste);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::StreetMap,         "Mapbox Streets Basic Map", "Mapbox Streets Basic Map",     false,  false,  UrlFactory::MapboxStreetsBasic);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Comic Map",         "Mapbox Comic Map",             false,  false,  UrlFactory::MapboxComic);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Outdoors Map",      "Mapbox Outdoors Map",          false,  false,  UrlFactory::MapboxOutdoors);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CycleMap,          "Mapbox Run, Byke and Hike Map",   "Mapbox Run, Byke and Hike Map",     false,  false,  UrlFactory::MapboxRunBikeHike);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Pencil Map",        "Mapbox Pencil Map",            false,  false,  UrlFactory::MapboxPencil);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Pirates Map",       "Mapbox Pirates Map",           false,  false,  UrlFactory::MapboxPirates);
    mapTypes << QGCGEOMAPTYPE(QGeoMapType::CustomMap,         "Mapbox Emerald Map",       "Mapbox Emerald Map",           false,  false,  UrlFactory::MapboxEmerald);

    setSupportedMapTypes(mapTypes);

    //-- Users (QML code) can define a different user agent
    if (parameters.contains(QStringLiteral("useragent"))) {
        getQGCMapEngine()->setUserAgent(parameters.value(QStringLiteral("useragent")).toString().toLatin1());
    }

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
    _setCache(parameters);
#endif

    setTileFetcher(new QGeoTileFetcherQGC(this));

    *error = QGeoServiceProvider::NoError;
    errorString->clear();
}

//-----------------------------------------------------------------------------
QGeoTiledMappingManagerEngineQGC::~QGeoTiledMappingManagerEngineQGC()
{
}

#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)

//-----------------------------------------------------------------------------
QGeoMapData *QGeoTiledMappingManagerEngineQGC::createMapData()
{
    return new QGeoTiledMapData(this, 0);
}

#else

//-----------------------------------------------------------------------------
QGeoMap*
QGeoTiledMappingManagerEngineQGC::createMap()
{
    return new QGeoTiledMapQGC(this);
}

#endif

#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
//-----------------------------------------------------------------------------
void
QGeoTiledMappingManagerEngineQGC::_setCache(const QVariantMap &parameters)
{
    QString cacheDir;
    if (parameters.contains(QStringLiteral("mapping.cache.directory")))
        cacheDir = parameters.value(QStringLiteral("mapping.cache.directory")).toString();
    else {
        cacheDir = getQGCMapEngine()->getCachePath();
        if(!QFileInfo(cacheDir).exists()) {
            if(!QDir::root().mkpath(cacheDir)) {
                qWarning() << "Could not create mapping disk cache directory: " << cacheDir;
                cacheDir = QDir::homePath() + QLatin1String("/.qgcmapscache/");
            }
        }
    }
    if(!QFileInfo(cacheDir).exists()) {
        if(!QDir::root().mkpath(cacheDir)) {
            qWarning() << "Could not create mapping disk cache directory: " << cacheDir;
            cacheDir.clear();
        }
    }
    //-- Memory Cache
    uint32_t memLimit = 0;
    if (parameters.contains(QStringLiteral("mapping.cache.memory.size"))) {
      bool ok = false;
      memLimit = parameters.value(QStringLiteral("mapping.cache.memory.size")).toString().toUInt(&ok);
      if (!ok)
          memLimit = 0;
    }
    if(!memLimit)
    {
        //-- Value saved in MB
        memLimit = getQGCMapEngine()->getMaxMemCache() * (1024 * 1024);
    }
    //-- It won't work with less than 1M of memory cache
    if(memLimit < 1024 * 1024)
        memLimit = 1024 * 1024;
    //-- On the other hand, Qt uses signed 32-bit integers. Limit to 1G to round it down (you don't need more than that).
    if(memLimit > 1024 * 1024 * 1024)
        memLimit = 1024 * 1024 * 1024;
    //-- Disable Qt's disk cache (sort of)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
    QAbstractGeoTileCache *pTileCache = new QGeoFileTileCache(cacheDir);
    setTileCache(pTileCache);
#else
    QGeoTileCache* pTileCache = createTileCacheWithDir(cacheDir);
#endif
    if(pTileCache)
    {
        //-- We're basically telling it to use 100k of disk for cache. It doesn't like
        //   values smaller than that and I could not find a way to make it NOT cache.
        //   We handle our own disk caching elsewhere.
        pTileCache->setMaxDiskUsage(1024 * 100);
        pTileCache->setMaxMemoryUsage(memLimit);
    }
}
#endif
<|endoftext|>