<commit_before>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>

// basic_string(const basic_string& str, const Allocator& alloc);

#include <string>
#include <cassert>

#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"

template <class T>
struct alloc_imp {
    bool active;

    alloc_imp() : active(true) {}

    T* allocate(std::size_t n)
    {
        if (active)
            return static_cast<T*>(std::malloc(n * sizeof(T)));
        else
            throw std::bad_alloc();
    }

    void deallocate(T* p, std::size_t) { std::free(p); }
    void activate  ()                  { active = true; }
    void deactivate()                  { active = false; }
};

template <class T>
struct poca_alloc {
    typedef T value_type;
    typedef std::true_type propagate_on_container_copy_assignment;

    alloc_imp<T> *imp;

    poca_alloc(alloc_imp<T> *ximp) : imp (ximp) {}

    template <class U>
    poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {}

    T*   allocate  (std::size_t n)       { return imp->allocate(n);}
    void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); }
};

template <typename T, typename U>
bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
{
    return lhs.imp == rhs.imp;
}

template <typename T, typename U>
bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
{
    return lhs.imp != rhs.imp;
}

template <class S>
void
test(S s1, const typename S::allocator_type& a)
{
    S s2(s1, a);
    LIBCPP_ASSERT(s2.__invariants());
    assert(s2 == s1);
    assert(s2.capacity() >= s2.size());
    assert(s2.get_allocator() == a);
}

#ifndef TEST_HAS_NO_EXCEPTIONS
template <class S>
void test_assign(S &s1, const S& s2)
{
	try { s1 = s2; }
	catch ( std::bad_alloc &) { return; }
	assert(false);
}
#endif

int main()
{
    {
    typedef test_allocator<char> A;
    typedef std::basic_string<char, std::char_traits<char>, A> S;
    test(S(), A(3));
    test(S("1"), A(5));
    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
    }
#if TEST_STD_VER >= 11
    {
    typedef min_allocator<char> A;
    typedef std::basic_string<char, std::char_traits<char>, A> S;
    test(S(), A());
    test(S("1"), A());
    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
    }

#ifndef TEST_HAS_NO_EXCEPTIONS
    {
    typedef poca_alloc<char> A;
    typedef std::basic_string<char, std::char_traits<char>, A> S;
	const char * p1 = "This is my first string";
	const char * p2 = "This is my second string";

    alloc_imp<char> imp1;
    alloc_imp<char> imp2;
	S s1(p1, A(&imp1));
	S s2(p2, A(&imp2));

	assert(s1 == p1);
	assert(s2 == p2);

	imp2.deactivate();
	test_assign(s1, s2);
	assert(s1 == p1);
	assert(s2 == p2);
    }
#endif
#endif
}
<commit_msg>Fix up some no-exception compile failures<commit_after>//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// <string>

// basic_string(const basic_string& str, const Allocator& alloc);

#include <string>
#include <cassert>

#include "test_macros.h"
#include "test_allocator.h"
#include "min_allocator.h"

#ifndef TEST_HAS_NO_EXCEPTIONS
template <class T>
struct alloc_imp {
    bool active;

    alloc_imp() : active(true) {}

    T* allocate(std::size_t n)
    {
        if (active)
            return static_cast<T*>(std::malloc(n * sizeof(T)));
        else
            throw std::bad_alloc();
    }

    void deallocate(T* p, std::size_t) { std::free(p); }
    void activate  ()                  { active = true; }
    void deactivate()                  { active = false; }
};

template <class T>
struct poca_alloc {
    typedef T value_type;
    typedef std::true_type propagate_on_container_copy_assignment;

    alloc_imp<T> *imp;

    poca_alloc(alloc_imp<T> *imp_) : imp (imp_) {}

    template <class U>
    poca_alloc(const poca_alloc<U>& other) : imp(other.imp) {}

    T*   allocate  (std::size_t n)       { return imp->allocate(n);}
    void deallocate(T* p, std::size_t n) { imp->deallocate(p, n); }
};

template <typename T, typename U>
bool operator==(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
{
    return lhs.imp == rhs.imp;
}

template <typename T, typename U>
bool operator!=(const poca_alloc<T>& lhs, const poca_alloc<U>& rhs)
{
    return lhs.imp != rhs.imp;
}

template <class S>
void test_assign(S &s1, const S& s2)
{
	try { s1 = s2; }
	catch ( std::bad_alloc &) { return; }
	assert(false);
}
#endif

template <class S>
void
test(S s1, const typename S::allocator_type& a)
{
    S s2(s1, a);
    LIBCPP_ASSERT(s2.__invariants());
    assert(s2 == s1);
    assert(s2.capacity() >= s2.size());
    assert(s2.get_allocator() == a);
}

int main()
{
    {
    typedef test_allocator<char> A;
    typedef std::basic_string<char, std::char_traits<char>, A> S;
    test(S(), A(3));
    test(S("1"), A(5));
    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A(7));
    }
#if TEST_STD_VER >= 11
    {
    typedef min_allocator<char> A;
    typedef std::basic_string<char, std::char_traits<char>, A> S;
    test(S(), A());
    test(S("1"), A());
    test(S("1234567890123456789012345678901234567890123456789012345678901234567890"), A());
    }

#ifndef TEST_HAS_NO_EXCEPTIONS
    {
    typedef poca_alloc<char> A;
    typedef std::basic_string<char, std::char_traits<char>, A> S;
	const char * p1 = "This is my first string";
	const char * p2 = "This is my second string";

    alloc_imp<char> imp1;
    alloc_imp<char> imp2;
	S s1(p1, A(&imp1));
	S s2(p2, A(&imp2));

	assert(s1 == p1);
	assert(s2 == p2);

	imp2.deactivate();
	test_assign(s1, s2);
	assert(s1 == p1);
	assert(s2 == p2);
    }
#endif
#endif
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sddll.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: rt $ $Date: 2006-05-02 15:03:04 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _EEITEM_HXX //autogen
#include <svx/eeitem.hxx>
#endif

#include <svx/editeng.hxx>

#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
#include <svtools/moduleoptions.hxx>
#endif
#ifndef _FM_FMOBJFAC_HXX
#include <svx/fmobjfac.hxx>
#endif
#ifndef _SVX_SIIMPORT_HXX
#include <svx/siimport.hxx>
#endif
#ifndef _SVDFIELD_HXX
#include <svx/svdfield.hxx>
#endif
#ifndef _OBJFAC3D_HXX
#include <svx/objfac3d.hxx>
#endif

#pragma hdrstop

#include "sddll.hxx"
#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif
#ifndef SD_GRAPHIC_DOC_SHELL_HXX
#include "GraphicDocShell.hxx"
#endif
#include "sdresid.hxx"
#include "sdobjfac.hxx"
#include "cfgids.hxx"
#include "strmname.h"
#include "SdShapeTypes.hxx"

#include <svx/SvxShapeTypes.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/fcontnr.hxx>
#include <tools/urlobj.hxx>
#include <svx/impgrf.hxx>
#include <svtools/FilterConfigItem.hxx>

#ifndef _COM_SUN_STAR_UTIL_XARCHIVER_HPP_
#include <com/sun/star/util/XArchiver.hpp>
#endif

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star;

/*************************************************************************
|*
|* Init
|*
\************************************************************************/

void SdDLL::Init()
{
    if ( SD_MOD() )
        return;

    SfxObjectFactory* pDrawFact = NULL;
    SfxObjectFactory* pImpressFact = NULL;

    if (SvtModuleOptions().IsImpress())
        pImpressFact = &::sd::DrawDocShell::Factory();

    if (SvtModuleOptions().IsDraw())
        pDrawFact = &::sd::GraphicDocShell::Factory();

    // the SdModule must be created
     SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);

     // #i46427#
     // The SfxModule::SfxModule stops when the first given factory
     // is 0, so we must not give a 0 as first factory
     if( pImpressFact )
     {
        (*ppShlPtr) = new SdModule( pImpressFact, pDrawFact );
     }
     else
     {
        (*ppShlPtr) = new SdModule( pDrawFact, pImpressFact );
     }

    if (SvtModuleOptions().IsImpress())
    {
        // Register the Impress shape types in order to make the shapes accessible.
        ::accessibility::RegisterImpressShapeTypes ();
        ::sd::DrawDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) );
    }

    if (SvtModuleOptions().IsDraw())
    {
        ::sd::GraphicDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) );
    }

    // register your view-factories here
    RegisterFactorys();

    // register your shell-interfaces here
    RegisterInterfaces();

    // register your controllers here
    RegisterControllers();

    // SvDraw-Felder registrieren
    SdrRegisterFieldClasses();

    // 3D-Objekt-Factory eintragen
    E3dObjFactory();

    // ::com::sun::star::form::component::Form-Objekt-Factory eintragen
    FmFormObjFactory();

    // factory for dummy import of old si-controls in 3.1 documents
//BFS02    SiImportFactory();

    // Objekt-Factory eintragen
    SdrObjFactory::InsertMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));
}

/*************************************************************************
|*
|* Exit
|*
\************************************************************************/

void SdDLL::Exit()
{
    // called directly befor unloading the DLL
    // do whatever you want, Sd-DLL is accessible

    // Objekt-Factory austragen
    SdrObjFactory::RemoveMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));

    // the SdModule must be destroyed
    SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);
    delete (*ppShlPtr);
    (*ppShlPtr) = NULL;
}

/*
ULONG SdDLL::DetectFilter(SfxMedium& rMedium, const SfxFilter** ppFilter,
                          SfxFilterFlags nMust, SfxFilterFlags nDont)
{
    ULONG nReturn = ERRCODE_ABORT;  // Erkennung fehlgeschlagen, Filter ungueltig
    BOOL bStorage = FALSE;

    if( *ppFilter && (*ppFilter)->GetFilterFlags() & SFX_FILTER_PACKED )
    {
        uno::Reference< lang::XMultiServiceFactory > xSMgr( ::comphelper::getProcessServiceFactory() );
        uno::Reference< util::XArchiver > xPacker( xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.util.Archiver" ) ), uno::UNO_QUERY );
        if( xPacker.is() )
        {
            // extract extra data
            OUString aPath( rMedium.GetOrigURL() );
            OUString aExtraData( xPacker->getExtraData( aPath ) );
            const OUString aSig1= OUString::createFromAscii( "private:" );
            String aTmp;
            aTmp += sal_Unicode( '?' );
            aTmp += String::CreateFromAscii("simpress");
            const OUString aSig2( aTmp );
            INT32 nIndex1 = aExtraData.indexOf( aSig1 );
            INT32 nIndex2 = aExtraData.indexOf( aSig2 );
            if( nIndex1 == 0 && nIndex2 != -1 )
                return ERRCODE_NONE;
        }
    }
    else if (rMedium.GetError() == SVSTREAM_OK)
    {
        if ( rMedium.IsStorage() )
        {
            bStorage = TRUE;
            SotStorageRef xStorage = rMedium.GetStorage();
            if ( !xStorage.Is() )
                return ULONG_MAX;

            if( SvtModuleOptions().IsImpress() )
            {
                // Erkennung ueber contained streams (PowerPoint 97-Filter)
                String aStreamName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PowerPoint Document" ) );
                if ( xStorage->IsContained( aStreamName ) && xStorage->IsStream( aStreamName ) )
                {
                    String aFileName(rMedium.GetName());
                    aFileName.ToUpperAscii();

                    if( aFileName.SearchAscii( ".POT" ) == STRING_NOTFOUND )
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97);
                    else
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97Template );

                    return ERRCODE_NONE;
                }
            }

            const SfxFilter* pFilter = *ppFilter;
            if ( *ppFilter )
            {
                if ( (*ppFilter)->GetFormat() == xStorage->GetFormat() )
                    pFilter = *ppFilter;
            }

             if( !pFilter && SvtModuleOptions().IsImpress() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("simpress") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if( !pFilter && SvtModuleOptions().IsDraw() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("sdraw") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if ( pFilter &&
                ( pFilter->GetFilterFlags() & nMust ) == nMust &&
                ( pFilter->GetFilterFlags() & nDont ) == 0 )
            {
                *ppFilter = pFilter;
                nReturn = ERRCODE_NONE;
            }
            else
            {
                *ppFilter = NULL;
                nReturn = ERRCODE_NONE;
            }
        }

        String aFileName( rMedium.GetName() );
        aFileName.ToUpperAscii();

        if ( nReturn == ERRCODE_ABORT )
        {
            if( bStorage )         // aber keine Clipboard-Id #55337#
            {
                *ppFilter = NULL;
            }
            else
            {
                // Vektorgraphik?
                SvStream* pStm = rMedium.GetInStream();

                if( !pStm )
                    nReturn = ERRCODE_IO_GENERAL;
                else
                {
                    pStm->Seek( STREAM_SEEK_TO_BEGIN );

                    const String        aFileName( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
                    GraphicDescriptor   aDesc( *pStm, &aFileName );
                    GraphicFilter*      pGrfFilter = GetGrfFilter();

                    if( !aDesc.Detect( FALSE ) )
                    {
                        if( SvtModuleOptions().IsImpress() )
                        {
                            *ppFilter = NULL;
                            nReturn = ERRCODE_ABORT;
                            INetURLObject aURL( aFileName );
                            if( aURL.getExtension().equalsIgnoreAsciiCaseAscii( "cgm" ) )
                            {
                                sal_uInt8 n8;
                                pStm->Seek( STREAM_SEEK_TO_BEGIN );
                                *pStm >> n8;
                                if ( ( n8 & 0xf0 ) == 0 )       // we are supporting binary cgm format only, so
                                {                               // this is a small test to exclude cgm text
                                    const String aName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "CGM - Computer Graphics Metafile" ) );
                                    SfxFilterMatcher aMatch( String::CreateFromAscii("simpress") );
                                    *ppFilter = aMatch.GetFilter4FilterName( aName );
                                    nReturn = ERRCODE_NONE;
                                }
                            }
                        }
                    }
                    else
                    {
                        if( SvtModuleOptions().IsDraw() )
                        {
                            String aShortName( aDesc.GetImportFormatShortName( aDesc.GetFileFormat() ) );
                            const String aName( pGrfFilter->GetImportFormatTypeName( pGrfFilter->GetImportFormatNumberForShortName( aShortName ) ) );

                            if ( *ppFilter && aShortName.EqualsIgnoreCaseAscii( "PCD" ) )    // there is a multiple pcd selection possible
                            {
                                sal_Int32 nBase = 2;    // default Base0
                                String aFilterTypeName( (*ppFilter)->GetRealTypeName() );
                                if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base4" ) == COMPARE_EQUAL )
                                    nBase = 1;
                                else if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base16" ) == COMPARE_EQUAL )
                                    nBase = 0;
                                String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
                                FilterConfigItem aFilterConfigItem( aFilterConfigPath );
                                aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
                            }

                            SfxFilterMatcher aMatch( String::CreateFromAscii("draw") );
                            *ppFilter = aMatch.GetFilter4FilterName( aName );
                            nReturn = ERRCODE_NONE;
                        }
                        else
                        {
                            nReturn = ERRCODE_ABORT;
                            *ppFilter = NULL;
                        }
                    }
                }
            }
        }
    }
    else
    {
        nReturn = rMedium.GetError();
    }

    return nReturn;
} */
<commit_msg>INTEGRATION: CWS rt16 (1.13.80); FILE MERGED 2006/08/08 12:17:07 rt 1.13.80.1: #i68214# Obsolete svx headers removed<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sddll.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: ihi $ $Date: 2006-08-29 14:19:08 $
 *
 *  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
 *
 ************************************************************************/

#ifndef _EEITEM_HXX //autogen
#include <svx/eeitem.hxx>
#endif

#include <svx/editeng.hxx>

#ifndef _SVDOBJ_HXX //autogen
#include <svx/svdobj.hxx>
#endif
#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX
#include <svtools/moduleoptions.hxx>
#endif
#ifndef _FM_FMOBJFAC_HXX
#include <svx/fmobjfac.hxx>
#endif
#ifndef _SVDFIELD_HXX
#include <svx/svdfield.hxx>
#endif
#ifndef _OBJFAC3D_HXX
#include <svx/objfac3d.hxx>
#endif

#pragma hdrstop

#include "sddll.hxx"
#ifndef SD_DRAW_DOC_SHELL_HXX
#include "DrawDocShell.hxx"
#endif
#ifndef SD_GRAPHIC_DOC_SHELL_HXX
#include "GraphicDocShell.hxx"
#endif
#include "sdresid.hxx"
#include "sdobjfac.hxx"
#include "cfgids.hxx"
#include "strmname.h"
#include "SdShapeTypes.hxx"

#include <svx/SvxShapeTypes.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/fcontnr.hxx>
#include <tools/urlobj.hxx>
#include <svx/impgrf.hxx>
#include <svtools/FilterConfigItem.hxx>

#ifndef _COM_SUN_STAR_UTIL_XARCHIVER_HPP_
#include <com/sun/star/util/XArchiver.hpp>
#endif

#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
#endif

using namespace ::rtl;
using namespace ::com::sun::star;

/*************************************************************************
|*
|* Init
|*
\************************************************************************/

void SdDLL::Init()
{
    if ( SD_MOD() )
        return;

    SfxObjectFactory* pDrawFact = NULL;
    SfxObjectFactory* pImpressFact = NULL;

    if (SvtModuleOptions().IsImpress())
        pImpressFact = &::sd::DrawDocShell::Factory();

    if (SvtModuleOptions().IsDraw())
        pDrawFact = &::sd::GraphicDocShell::Factory();

    // the SdModule must be created
     SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);

     // #i46427#
     // The SfxModule::SfxModule stops when the first given factory
     // is 0, so we must not give a 0 as first factory
     if( pImpressFact )
     {
        (*ppShlPtr) = new SdModule( pImpressFact, pDrawFact );
     }
     else
     {
        (*ppShlPtr) = new SdModule( pDrawFact, pImpressFact );
     }

    if (SvtModuleOptions().IsImpress())
    {
        // Register the Impress shape types in order to make the shapes accessible.
        ::accessibility::RegisterImpressShapeTypes ();
        ::sd::DrawDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) );
    }

    if (SvtModuleOptions().IsDraw())
    {
        ::sd::GraphicDocShell::Factory().SetDocumentServiceName( String( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) );
    }

    // register your view-factories here
    RegisterFactorys();

    // register your shell-interfaces here
    RegisterInterfaces();

    // register your controllers here
    RegisterControllers();

    // SvDraw-Felder registrieren
    SdrRegisterFieldClasses();

    // 3D-Objekt-Factory eintragen
    E3dObjFactory();

    // ::com::sun::star::form::component::Form-Objekt-Factory eintragen
    FmFormObjFactory();

    // factory for dummy import of old si-controls in 3.1 documents
//BFS02    SiImportFactory();

    // Objekt-Factory eintragen
    SdrObjFactory::InsertMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));
}

/*************************************************************************
|*
|* Exit
|*
\************************************************************************/

void SdDLL::Exit()
{
    // called directly befor unloading the DLL
    // do whatever you want, Sd-DLL is accessible

    // Objekt-Factory austragen
    SdrObjFactory::RemoveMakeUserDataHdl(LINK(&aSdObjectFactory, SdObjectFactory, MakeUserData));

    // the SdModule must be destroyed
    SdModule** ppShlPtr = (SdModule**) GetAppData(SHL_DRAW);
    delete (*ppShlPtr);
    (*ppShlPtr) = NULL;
}

/*
ULONG SdDLL::DetectFilter(SfxMedium& rMedium, const SfxFilter** ppFilter,
                          SfxFilterFlags nMust, SfxFilterFlags nDont)
{
    ULONG nReturn = ERRCODE_ABORT;  // Erkennung fehlgeschlagen, Filter ungueltig
    BOOL bStorage = FALSE;

    if( *ppFilter && (*ppFilter)->GetFilterFlags() & SFX_FILTER_PACKED )
    {
        uno::Reference< lang::XMultiServiceFactory > xSMgr( ::comphelper::getProcessServiceFactory() );
        uno::Reference< util::XArchiver > xPacker( xSMgr->createInstance( OUString::createFromAscii( "com.sun.star.util.Archiver" ) ), uno::UNO_QUERY );
        if( xPacker.is() )
        {
            // extract extra data
            OUString aPath( rMedium.GetOrigURL() );
            OUString aExtraData( xPacker->getExtraData( aPath ) );
            const OUString aSig1= OUString::createFromAscii( "private:" );
            String aTmp;
            aTmp += sal_Unicode( '?' );
            aTmp += String::CreateFromAscii("simpress");
            const OUString aSig2( aTmp );
            INT32 nIndex1 = aExtraData.indexOf( aSig1 );
            INT32 nIndex2 = aExtraData.indexOf( aSig2 );
            if( nIndex1 == 0 && nIndex2 != -1 )
                return ERRCODE_NONE;
        }
    }
    else if (rMedium.GetError() == SVSTREAM_OK)
    {
        if ( rMedium.IsStorage() )
        {
            bStorage = TRUE;
            SotStorageRef xStorage = rMedium.GetStorage();
            if ( !xStorage.Is() )
                return ULONG_MAX;

            if( SvtModuleOptions().IsImpress() )
            {
                // Erkennung ueber contained streams (PowerPoint 97-Filter)
                String aStreamName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "PowerPoint Document" ) );
                if ( xStorage->IsContained( aStreamName ) && xStorage->IsStream( aStreamName ) )
                {
                    String aFileName(rMedium.GetName());
                    aFileName.ToUpperAscii();

                    if( aFileName.SearchAscii( ".POT" ) == STRING_NOTFOUND )
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97);
                    else
                        *ppFilter = SfxFilter::GetFilterByName( pFilterPowerPoint97Template );

                    return ERRCODE_NONE;
                }
            }

            const SfxFilter* pFilter = *ppFilter;
            if ( *ppFilter )
            {
                if ( (*ppFilter)->GetFormat() == xStorage->GetFormat() )
                    pFilter = *ppFilter;
            }

             if( !pFilter && SvtModuleOptions().IsImpress() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("simpress") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if( !pFilter && SvtModuleOptions().IsDraw() )
            {
                SfxFilterMatcher aMatcher( String::CreateFromAscii("sdraw") );
                pFilter = aMatcher.GetFilter4ClipBoardId( xStorage->GetFormat() );
                if ( pFilter )
                    *ppFilter = pFilter;
            }

            if ( pFilter &&
                ( pFilter->GetFilterFlags() & nMust ) == nMust &&
                ( pFilter->GetFilterFlags() & nDont ) == 0 )
            {
                *ppFilter = pFilter;
                nReturn = ERRCODE_NONE;
            }
            else
            {
                *ppFilter = NULL;
                nReturn = ERRCODE_NONE;
            }
        }

        String aFileName( rMedium.GetName() );
        aFileName.ToUpperAscii();

        if ( nReturn == ERRCODE_ABORT )
        {
            if( bStorage )         // aber keine Clipboard-Id #55337#
            {
                *ppFilter = NULL;
            }
            else
            {
                // Vektorgraphik?
                SvStream* pStm = rMedium.GetInStream();

                if( !pStm )
                    nReturn = ERRCODE_IO_GENERAL;
                else
                {
                    pStm->Seek( STREAM_SEEK_TO_BEGIN );

                    const String        aFileName( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
                    GraphicDescriptor   aDesc( *pStm, &aFileName );
                    GraphicFilter*      pGrfFilter = GetGrfFilter();

                    if( !aDesc.Detect( FALSE ) )
                    {
                        if( SvtModuleOptions().IsImpress() )
                        {
                            *ppFilter = NULL;
                            nReturn = ERRCODE_ABORT;
                            INetURLObject aURL( aFileName );
                            if( aURL.getExtension().equalsIgnoreAsciiCaseAscii( "cgm" ) )
                            {
                                sal_uInt8 n8;
                                pStm->Seek( STREAM_SEEK_TO_BEGIN );
                                *pStm >> n8;
                                if ( ( n8 & 0xf0 ) == 0 )       // we are supporting binary cgm format only, so
                                {                               // this is a small test to exclude cgm text
                                    const String aName = UniString::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "CGM - Computer Graphics Metafile" ) );
                                    SfxFilterMatcher aMatch( String::CreateFromAscii("simpress") );
                                    *ppFilter = aMatch.GetFilter4FilterName( aName );
                                    nReturn = ERRCODE_NONE;
                                }
                            }
                        }
                    }
                    else
                    {
                        if( SvtModuleOptions().IsDraw() )
                        {
                            String aShortName( aDesc.GetImportFormatShortName( aDesc.GetFileFormat() ) );
                            const String aName( pGrfFilter->GetImportFormatTypeName( pGrfFilter->GetImportFormatNumberForShortName( aShortName ) ) );

                            if ( *ppFilter && aShortName.EqualsIgnoreCaseAscii( "PCD" ) )    // there is a multiple pcd selection possible
                            {
                                sal_Int32 nBase = 2;    // default Base0
                                String aFilterTypeName( (*ppFilter)->GetRealTypeName() );
                                if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base4" ) == COMPARE_EQUAL )
                                    nBase = 1;
                                else if ( aFilterTypeName.CompareToAscii( "pcd_Photo_CD_Base16" ) == COMPARE_EQUAL )
                                    nBase = 0;
                                String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) );
                                FilterConfigItem aFilterConfigItem( aFilterConfigPath );
                                aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase );
                            }

                            SfxFilterMatcher aMatch( String::CreateFromAscii("draw") );
                            *ppFilter = aMatch.GetFilter4FilterName( aName );
                            nReturn = ERRCODE_NONE;
                        }
                        else
                        {
                            nReturn = ERRCODE_ABORT;
                            *ppFilter = NULL;
                        }
                    }
                }
            }
        }
    }
    else
    {
        nReturn = rMedium.GetError();
    }

    return nReturn;
} */
<|endoftext|>


<commit_before>/*=========================================================================
 *
 *  Copyright Leiden University Medical Center, Erasmus University Medical
 *  Center and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "selxSuperElastixFilter.h"
#include "selxAnyFileReader.h"
#include "selxAnyFileWriter.h"
#include "selxLogger.h"
#include "selxGitInfo.h"

#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <stdexcept>

template< class T >
std::ostream &
operator<<( std::ostream & os, const std::vector< T > & v )
{
  std::copy( v.begin(), v.end(), std::ostream_iterator< T >( os, " " ) );
  return os;
}

namespace selx
{
  // helper function to parse command line arguments for log level
  std::istream& operator>>(std::istream& in, selx::LogLevel& loglevel)
  {
    std::string token;
    in >> token;
    if (token == "off")
      loglevel = selx::LogLevel::OFF;
    else if (token == "critical")
      loglevel = selx::LogLevel::CRT;
    else if (token == "error")
      loglevel = selx::LogLevel::ERR;
    else if (token == "warning")
      loglevel = selx::LogLevel::WRN;
    else if (token == "info")
      loglevel = selx::LogLevel::INF;
    else if (token == "debug")
      loglevel = selx::LogLevel::DBG;
    else if (token == "trace")
      loglevel = selx::LogLevel::TRC;
    else
      in.setstate(std::ios_base::failbit);
    return in;
  }
}

int
main( int ac, char * av[] )
{

  selx::Logger::Pointer logger = selx::Logger::New();

  typedef std::vector< std::string > VectorOfStringsType;
  typedef std::vector< boost::filesystem::path > VectorOfPathsType;

  boost::filesystem::path logPath;
  // default log level
  selx::LogLevel logLevel = selx::LogLevel::WRN;

  boost::filesystem::path            configurationPath;
  VectorOfPathsType                   configurationPaths;

  VectorOfStringsType inputPairs;
  VectorOfStringsType outputPairs;

  boost::program_options::variables_map vm;

  try
  {
    boost::program_options::options_description desc("Allowed options");
    desc.add_options()
      ( "help", "produce help message" )
      ( "revision-sha", "produce git revision SHA-1 hash of SuperElastix source" )
      ("conf", boost::program_options::value< VectorOfPathsType >(&configurationPaths)->required()->multitoken(), "Configuration file: single or multiple Blueprints [.xml|.json]")
      ("in", boost::program_options::value< VectorOfStringsType >(&inputPairs)->multitoken(), "Input data: images, labels, meshes, etc. Usage arg: <name>=<path> (or multiple pairs)")
      ("out", boost::program_options::value< VectorOfStringsType >(&outputPairs)->multitoken(), "Output data: images, labels, meshes, etc. Usage arg: <name>=<path> (or multiple pairs)")
      ("graphout", boost::program_options::value< boost::filesystem::path >(), "Output Graphviz dot file")
      ("logfile", boost::program_options::value< boost::filesystem::path >(&logPath), "Log output file")
      ("loglevel", boost::program_options::value< selx::LogLevel >(&logLevel), "Log level [off|critical|error|warning|info|debug|trace]")
      ;

    boost::program_options::store(boost::program_options::parse_command_line(ac, av, desc), vm);

    if( vm.count( "help" ) )
    {
      std::cout
        << "SuperElastix GIT Revision SHA-1: " << selx::GitInfo::GetRevisionSha() << '\n'
        << desc << std::endl;
      return 0;
    }
    if (vm.count("revision-sha"))
    {
      std::cout << selx::GitInfo::GetRevisionSha() << std::endl;
      return 0;
    }
    boost::program_options::notify(vm);
  }
  catch (std::exception& e)
  {
    std::cerr << "Error: " << e.what() << "\n";
    std::cerr << "See 'SuperElastix --help' for help" << "\n";
    return 1;
  }
  catch (...)
  {
    std::cerr << "Unknown error!" << "\n";
    return 1;
  }

  try
  {
    // optionally, stream to log file
    std::ofstream outfile;
    if ( vm.count("logfile") )
    {
      outfile =  std::ofstream(logPath.c_str());
      logger->AddStream("logfile", outfile);
    }

    logger->AddStream("cout", std::cout);
    logger->SetLogLevel(logLevel);

    // instantiate a SuperElastixFilter that is loaded with default components
    selx::SuperElastixFilter::Pointer superElastixFilter = selx::SuperElastixFilter::New();

    superElastixFilter->SetLogger(logger);

    // create empty blueprint
    selx::Blueprint::Pointer blueprint = selx::Blueprint::New();
    blueprint->SetLogger(logger);
    for (const auto & configurationPath : configurationPaths)
    {
      blueprint->MergeFromFile(configurationPath.string());
    }

    if( vm.count( "graphout" ) )
    {
      blueprint->Write(vm["graphout"].as< boost::filesystem::path >().string());
    }

    // The Blueprint needs to be set to superElastixFilter before GetInputFileReader and GetOutputFileWriter should be called.
    superElastixFilter->SetBlueprint(blueprint);

    // Store the readers so that they will not be destroyed before the pipeline is executed.
    std::vector< selx::AnyFileReader::Pointer > fileReaders;
    // Store the writers for the update call
    std::vector< selx::AnyFileWriter::Pointer > fileWriters;

    if( vm.count( "in" ) )
    {
      logger->Log( selx::LogLevel::INF, "Preparing input data ... ");
      for( const auto & inputPair : inputPairs )
      {
        VectorOfStringsType nameAndPath;
        boost::split( nameAndPath, inputPair, boost::is_any_of( "=" ) );  // NameAndPath == { "name","path" }
        const std::string & name = nameAndPath[ 0 ];
        const std::string & path = nameAndPath[ 1 ];

        // since we do not know which reader type we should instantiate for input "name",
        // we ask SuperElastix for a reader that matches the type of the source component "name"
        logger->Log( selx::LogLevel::INF, "Preparing input '" + name + "': " + path + " ..." );
        selx::AnyFileReader::Pointer reader = superElastixFilter->GetInputFileReader( name );
        reader->SetFileName( path );
        superElastixFilter->SetInput( name, reader->GetOutput() );
        fileReaders.push_back( reader );
        logger->Log( selx::LogLevel::INF, "Preparing input '" + name + "': " + path + " ... Done" );
      }
      logger->Log( selx::LogLevel::INF, "Preparing input data ... Done");
    }
    else
    {
      logger->Log( selx::LogLevel::INF, "No input data specified.");
    }

    if( vm.count( "out" ) )
    {
      logger->Log( selx::LogLevel::INF, "Preparing output data ... ");
      for( const auto & outputPair : outputPairs )
      {
        VectorOfStringsType nameAndPath;
        boost::split( nameAndPath, outputPair, boost::is_any_of( "=" ) );  // NameAndPath == { "name","path" }
        const std::string & name = nameAndPath[ 0 ];
        const std::string & path = nameAndPath[ 1 ];

        // since we do not know which writer type we should instantiate for output "name",
        // we ask SuperElastix for a writer that matches the type of the sink component "name"
        logger->Log( selx::LogLevel::INF, "Preparing output '" + name + "': " + path + " ..." );
        selx::AnyFileWriter::Pointer writer = superElastixFilter->GetOutputFileWriter( name );
        writer->SetFileName( path );
        writer->SetInput( superElastixFilter->GetOutput( name ) );
        fileWriters.push_back( writer );
        logger->Log( selx::LogLevel::INF, "Preparing output '" + name + "': " + path + " ... Done" );
      }
    }
    else
    {
      logger->Log( selx::LogLevel::INF, "No output data specified.");
    }

    superElastixFilter->Update();

    /* Execute SuperElastix by updating the writers */
    logger->Log( selx::LogLevel::INF, "Executing ...");
    for( auto & writer : fileWriters )
    {
      writer->Update();
    }
    logger->Log(selx:: LogLevel::INF, "Executing ... Done");
  }
  catch( std::exception & e )
  {
    logger->Log( selx::LogLevel::CRT, "Executing ... Error");
    logger->Log( selx::LogLevel::CRT, e.what());
    std::cerr << e.what();
    return 1;
  }
  catch( ... )
  {
    logger->Log( selx::LogLevel::CRT, "Executing ... Error");
    logger->Log( selx::LogLevel::CRT, "Exception of unknown type!");
    std::cerr << "Exception of unknown type!";
    return 1;
  }

  return 0;
}
<commit_msg>BUG: Remove extra call to update<commit_after>/*=========================================================================
 *
 *  Copyright Leiden University Medical Center, Erasmus University Medical
 *  Center and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

#include "selxSuperElastixFilter.h"
#include "selxAnyFileReader.h"
#include "selxAnyFileWriter.h"
#include "selxLogger.h"
#include "selxGitInfo.h"

#include <boost/algorithm/string.hpp>
#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include <iostream>
#include <algorithm>
#include <iterator>
#include <string>
#include <stdexcept>

template< class T >
std::ostream &
operator<<( std::ostream & os, const std::vector< T > & v )
{
  std::copy( v.begin(), v.end(), std::ostream_iterator< T >( os, " " ) );
  return os;
}

namespace selx
{
  // helper function to parse command line arguments for log level
  std::istream& operator>>(std::istream& in, selx::LogLevel& loglevel)
  {
    std::string token;
    in >> token;
    if (token == "off")
      loglevel = selx::LogLevel::OFF;
    else if (token == "critical")
      loglevel = selx::LogLevel::CRT;
    else if (token == "error")
      loglevel = selx::LogLevel::ERR;
    else if (token == "warning")
      loglevel = selx::LogLevel::WRN;
    else if (token == "info")
      loglevel = selx::LogLevel::INF;
    else if (token == "debug")
      loglevel = selx::LogLevel::DBG;
    else if (token == "trace")
      loglevel = selx::LogLevel::TRC;
    else
      in.setstate(std::ios_base::failbit);
    return in;
  }
}

int
main( int ac, char * av[] )
{

  selx::Logger::Pointer logger = selx::Logger::New();

  typedef std::vector< std::string > VectorOfStringsType;
  typedef std::vector< boost::filesystem::path > VectorOfPathsType;

  boost::filesystem::path logPath;
  // default log level
  selx::LogLevel logLevel = selx::LogLevel::WRN;

  boost::filesystem::path            configurationPath;
  VectorOfPathsType                   configurationPaths;

  VectorOfStringsType inputPairs;
  VectorOfStringsType outputPairs;

  boost::program_options::variables_map vm;

  try
  {
    boost::program_options::options_description desc("Allowed options");
    desc.add_options()
      ( "help", "produce help message" )
      ( "revision-sha", "produce git revision SHA-1 hash of SuperElastix source" )
      ("conf", boost::program_options::value< VectorOfPathsType >(&configurationPaths)->required()->multitoken(), "Configuration file: single or multiple Blueprints [.xml|.json]")
      ("in", boost::program_options::value< VectorOfStringsType >(&inputPairs)->multitoken(), "Input data: images, labels, meshes, etc. Usage arg: <name>=<path> (or multiple pairs)")
      ("out", boost::program_options::value< VectorOfStringsType >(&outputPairs)->multitoken(), "Output data: images, labels, meshes, etc. Usage arg: <name>=<path> (or multiple pairs)")
      ("graphout", boost::program_options::value< boost::filesystem::path >(), "Output Graphviz dot file")
      ("logfile", boost::program_options::value< boost::filesystem::path >(&logPath), "Log output file")
      ("loglevel", boost::program_options::value< selx::LogLevel >(&logLevel), "Log level [off|critical|error|warning|info|debug|trace]")
      ;

    boost::program_options::store(boost::program_options::parse_command_line(ac, av, desc), vm);

    if( vm.count( "help" ) )
    {
      std::cout
        << "SuperElastix GIT Revision SHA-1: " << selx::GitInfo::GetRevisionSha() << '\n'
        << desc << std::endl;
      return 0;
    }
    if (vm.count("revision-sha"))
    {
      std::cout << selx::GitInfo::GetRevisionSha() << std::endl;
      return 0;
    }
    boost::program_options::notify(vm);
  }
  catch (std::exception& e)
  {
    std::cerr << "Error: " << e.what() << "\n";
    std::cerr << "See 'SuperElastix --help' for help" << "\n";
    return 1;
  }
  catch (...)
  {
    std::cerr << "Unknown error!" << "\n";
    return 1;
  }

  try
  {
    // optionally, stream to log file
    std::ofstream outfile;
    if ( vm.count("logfile") )
    {
      outfile =  std::ofstream(logPath.c_str());
      logger->AddStream("logfile", outfile);
    }

    logger->AddStream("cout", std::cout);
    logger->SetLogLevel(logLevel);

    // instantiate a SuperElastixFilter that is loaded with default components
    selx::SuperElastixFilter::Pointer superElastixFilter = selx::SuperElastixFilter::New();

    superElastixFilter->SetLogger(logger);

    // create empty blueprint
    selx::Blueprint::Pointer blueprint = selx::Blueprint::New();
    blueprint->SetLogger(logger);
    for (const auto & configurationPath : configurationPaths)
    {
      blueprint->MergeFromFile(configurationPath.string());
    }

    if( vm.count( "graphout" ) )
    {
      blueprint->Write(vm["graphout"].as< boost::filesystem::path >().string());
    }

    // The Blueprint needs to be set to superElastixFilter before GetInputFileReader and GetOutputFileWriter should be called.
    superElastixFilter->SetBlueprint(blueprint);

    // Store the readers so that they will not be destroyed before the pipeline is executed.
    std::vector< selx::AnyFileReader::Pointer > fileReaders;
    // Store the writers for the update call
    std::vector< selx::AnyFileWriter::Pointer > fileWriters;

    if( vm.count( "in" ) )
    {
      logger->Log( selx::LogLevel::INF, "Preparing input data ... ");
      for( const auto & inputPair : inputPairs )
      {
        VectorOfStringsType nameAndPath;
        boost::split( nameAndPath, inputPair, boost::is_any_of( "=" ) );  // NameAndPath == { "name","path" }
        const std::string & name = nameAndPath[ 0 ];
        const std::string & path = nameAndPath[ 1 ];

        // since we do not know which reader type we should instantiate for input "name",
        // we ask SuperElastix for a reader that matches the type of the source component "name"
        logger->Log( selx::LogLevel::INF, "Preparing input '" + name + "': " + path + " ..." );
        selx::AnyFileReader::Pointer reader = superElastixFilter->GetInputFileReader( name );
        reader->SetFileName( path );
        superElastixFilter->SetInput( name, reader->GetOutput() );
        fileReaders.push_back( reader );
        logger->Log( selx::LogLevel::INF, "Preparing input '" + name + "': " + path + " ... Done" );
      }
      logger->Log( selx::LogLevel::INF, "Preparing input data ... Done");
    }
    else
    {
      logger->Log( selx::LogLevel::INF, "No input data specified.");
    }

    if( vm.count( "out" ) )
    {
      logger->Log( selx::LogLevel::INF, "Preparing output data ... ");
      for( const auto & outputPair : outputPairs )
      {
        VectorOfStringsType nameAndPath;
        boost::split( nameAndPath, outputPair, boost::is_any_of( "=" ) );  // NameAndPath == { "name","path" }
        const std::string & name = nameAndPath[ 0 ];
        const std::string & path = nameAndPath[ 1 ];

        // since we do not know which writer type we should instantiate for output "name",
        // we ask SuperElastix for a writer that matches the type of the sink component "name"
        logger->Log( selx::LogLevel::INF, "Preparing output '" + name + "': " + path + " ..." );
        selx::AnyFileWriter::Pointer writer = superElastixFilter->GetOutputFileWriter( name );
        writer->SetFileName( path );
        writer->SetInput( superElastixFilter->GetOutput( name ) );
        fileWriters.push_back( writer );
        logger->Log( selx::LogLevel::INF, "Preparing output '" + name + "': " + path + " ... Done" );
      }
    }
    else
    {
      logger->Log( selx::LogLevel::INF, "No output data specified.");
    }

    /* Execute SuperElastix by updating the writers */
    logger->Log( selx::LogLevel::INF, "Executing ...");
    for( auto & writer : fileWriters )
    {
      writer->Update();
    }
    logger->Log(selx:: LogLevel::INF, "Executing ... Done");
  }
  catch( std::exception & e )
  {
    logger->Log( selx::LogLevel::CRT, "Executing ... Error");
    logger->Log( selx::LogLevel::CRT, e.what());
    std::cerr << e.what();
    return 1;
  }
  catch( ... )
  {
    logger->Log( selx::LogLevel::CRT, "Executing ... Error");
    logger->Log( selx::LogLevel::CRT, "Exception of unknown type!");
    std::cerr << "Exception of unknown type!";
    return 1;
  }

  return 0;
}
<|endoftext|>


<commit_before>#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "sensor_msgs/LaserScan.h"
#include <nav_msgs/Odometry.h>
#include "std_msgs/String.h"

#include <cstdlib> // Needed for rand()
#include <ctime> // Needed to seed random number generator with a time value

float prevclosestRange = 0;
double linear_x;
double angular_z;

//pose of the robot
double px;
double py;
double theta;
double prevpx;
double prevpy;
bool isRotate;

int checkcount=0;

class RandomWalk {
		public:
		// Construst a new RandomWalk object and hook up this ROS node
		// to the simulated robot's velocity control and laser topics
		RandomWalk(ros::NodeHandle& nh) :
		fsm(FSM_MOVE_FORWARD),
		rotateStartTime(ros::Time::now()),
		rotateDuration(0.f) {
		// Initialize random time generator
		srand(time(NULL));
		// Advertise a new publisher for the simulated robot's velocity command topic
		// (the second argument indicates that if multiple command messages are in
		// the queue to be sent, only the last command will be sent)
		ros::NodeHandle n;
		commandPub = nh.advertise<geometry_msgs::Twist>("robot_2/cmd_vel",1000);
		truckPosPub = nh.advertise<std_msgs::String>("truck_position",1000);
		// Subscribe to the simulated robot's laser scan topic and tell ROS to call
		// this->commandCallback() whenever a new message is published on that topic
		laserSub = nh.subscribe<sensor_msgs::LaserScan>("robot_2/base_scan", 1000, &RandomWalk::commandCallback, this);
		StageOdo_sub = nh.subscribe<nav_msgs::Odometry>("robot_2/odom",1000, &RandomWalk::StageOdom_callback,this);
		//ros::Subscriber StageOdo_sub = n.subscribe<nav_msgs::Odometry>("robot_0/odom",1000, StageOdom_callback);

	};

	void StageOdom_callback(nav_msgs::Odometry msg)
	{
		//This is the call back function to process odometry messages coming from Stage.

		px = -3 + msg.pose.pose.position.x;
		py = -3 + msg.pose.pose.position.y;
		//printf("%f",px);

		// If the current position is the same the previous position, then the robot is stuck and needs to move around
		if ((px == prevpx) && (py == prevpy)) {
			//msg.pose.pose.position.x = 5;
			//ROS_INFO("Prevpx: %f",prevpx);

			// Note the negative linear_x
			//linear_x=-0.2;
			//angular_z=1;

			//theta=10;
			//px = 5;
			//py= 5;
			//printf("Robot stuck");
			if (!isRotate) {
				ROS_INFO("Truck stuck");
				double r2 = (double)rand()/((double)RAND_MAX/(M_PI/2));
				double m2 = (double)rand()/((double)RAND_MAX/0.5);
				//ROS_INFO("r2" << r2);
				move(-m2, r2);

			}
		} else {
			// One the robot becomes unstuck, then it moves around again normally
			//linear_x = 0.2;
			//angular_z = 0.2;
			//ROS_INFO("Robot unstuck");
			//checkcount=0;
		}
		ROS_INFO("Truck -- Current x position is: %f", px);
		ROS_INFO("Truck -- Current y position is: %f", py);
		prevpx = px;
		prevpy = py;
	};

	// Send a velocity command
	void move(double linearVelMPS, double angularVelRadPS) {
		geometry_msgs::Twist msg; // The default constructor will set all commands to 0
		msg.linear.x = linearVelMPS;
		msg.angular.z = angularVelRadPS;
		commandPub.publish(msg);
	};

	// Process the incoming laser scan message
	void commandCallback(const sensor_msgs::LaserScan::ConstPtr& msg) {
		if (fsm == FSM_MOVE_FORWARD) {
			// Compute the average range value between MIN_SCAN_ANGLE and MAX_SCAN_ANGLE
			//
			// NOTE: ideally, the following loop should have additional checks to ensure
			// that indices are not out of bounds, by computing:
			//
			//- currAngle = msg->angle_min + msg->angle_increment*currIndex
			//
			// and then ensuring that currAngle <= msg->angle_max
			unsigned int minIndex = ceil((MIN_SCAN_ANGLE_RAD - msg->angle_min) / msg->angle_increment);
			unsigned int maxIndex = ceil((MAX_SCAN_ANGLE_RAD - msg->angle_min) / msg->angle_increment);
			float closestRange = msg->ranges[minIndex];

			for (unsigned int currIndex = minIndex + 1; currIndex < maxIndex; currIndex++) {
				if (msg->ranges[currIndex] < closestRange) {
					closestRange = msg->ranges[currIndex];
				}
			}
			//if (closestRange == prevclosestRange) {
			//	ROS_INFO_STREAM("STUCK");
			//	move(-FORWARD_SPEED_MPS, ROTATE_SPEED_RADPS);
			//	//move(0, ROTATE_SPEED_RADPS);
			//} else {

				//ROS_INFO_STREAM("Range: " << closestRange);
				prevclosestRange = closestRange;
				if (closestRange < PROXIMITY_RANGE_M) {
					fsm=FSM_ROTATE;
					rotateStartTime=ros::Time::now();
					float r2 = (float)rand()/((float)RAND_MAX/100);
					rotateDuration=ros::Duration(rand() % 2);
					//fsm= FSM_MOVE_FORWARD;
				}
			//}

		}
	};
	// Main FSM loop for ensuring that ROS messages are
	// processed in a timely manner, and also for sending
	// velocity controls to the simulated robot based on the FSM state
	void spin() {
		ros::Rate rate(10); // Specify the FSM loop rate in Hz
		while (ros::ok()) { // Keep spinning loop until user presses Ctrl+C
			std_msgs::String msg;
			std::stringstream ss;
			ss << "Truck -- px:" << px << " py:" << py << " theta:" << theta << " isRotate:" << isRotate;
    			msg.data = ss.str();

    			//ROS_INFO("%s", msg.data.c_str());

			if (fsm == FSM_MOVE_FORWARD) {
				//ROS_INFO_STREAM("Start forward");
				move(FORWARD_SPEED_MPS, 0);
				checkcount++;
				if (checkcount > 3) {
					isRotate=false;
				}
			}
			if (fsm == FSM_ROTATE) {
				//ROS_INFO_STREAM("Start rotate");
				move(0, ROTATE_SPEED_RADPS);
				rotateEndTime=ros::Time::now();
				isRotate=true;
				//ROS_INFO_STREAM("Time: " << rotateEndTime);

				if ((rotateEndTime - rotateStartTime) > rotateDuration) {
					fsm=FSM_MOVE_FORWARD;
					//ROS_INFO_STREAM("End rotate");
					checkcount=0;
				}
			}

		truckPosPub.publish(msg);

		ros::spinOnce(); // Need to call this function often to allow ROS to process incoming messages
		rate.sleep(); // Sleep for the rest of the cycle, to enforce the FSM loop rate
		}
	};
	enum FSM {FSM_MOVE_FORWARD, FSM_ROTATE};
	// Tunable parameters
	// TODO: tune parameters as you see fit
	const static double MIN_SCAN_ANGLE_RAD = -10.0/180*M_PI;
	const static double MAX_SCAN_ANGLE_RAD = +10.0/180*M_PI;
	const static float PROXIMITY_RANGE_M = 4; // Should be smaller than sensor_msgs::LaserScan::range_max
	const static double FORWARD_SPEED_MPS = 2;
	const static double ROTATE_SPEED_RADPS = M_PI/2;

	protected:
	ros::Publisher commandPub; // Publisher to the simulated robot's velocity command topic
	ros::Publisher truckPosPub;
	ros::Subscriber laserSub; // Subscriber to the simulated robot's laser scan topic
	enum FSM fsm; // Finite state machine for the random walk algorithm
	ros::Time rotateStartTime; // Start time of the rotation
	ros::Time rotateEndTime;
	ros::Duration rotateDuration; // Duration of the rotation
	ros::Subscriber StageOdo_sub;

};
int main(int argc, char **argv) {
	ros::init(argc, argv, "Trust"); // Initiate new ROS node named "Truck"
	ROS_INFO("This node is: Truck");
	ros::NodeHandle n;
	prevpx = 0;
	prevpx= 0;
	RandomWalk walker(n); // Create new random walk object
	walker.spin(); // Execute FSM loop
	return 0;
};

<commit_msg>Revert "Fixing Truck. Work in progress, saving changes with commit"<commit_after>#include "ros/ros.h"
#include "geometry_msgs/Twist.h"
#include "sensor_msgs/LaserScan.h"
#include <nav_msgs/Odometry.h>
#include "std_msgs/String.h"

#include <cstdlib> // Needed for rand()
#include <ctime> // Needed to seed random number generator with a time value

float prevclosestRange = 0;
double linear_x;
double angular_z;

//pose of the robot
double px;
double py;
double theta;
double prevpx;
double prevpy;
bool isRotate;

int checkcount=0;

class RandomWalk {
		public:
		// Construst a new RandomWalk object and hook up this ROS node
		// to the simulated robot's velocity control and laser topics
		RandomWalk(ros::NodeHandle& nh) :
		fsm(FSM_MOVE_FORWARD),
		rotateStartTime(ros::Time::now()),
		rotateDuration(0.f) {
		// Initialize random time generator
		srand(time(NULL));
		// Advertise a new publisher for the simulated robot's velocity command topic
		// (the second argument indicates that if multiple command messages are in
		// the queue to be sent, only the last command will be sent)
		ros::NodeHandle n;
		commandPub = nh.advertise<geometry_msgs::Twist>("robot_2/cmd_vel",1000);
		truckPosPub = nh.advertise<std_msgs::String>("truck_position",1000);
		// Subscribe to the simulated robot's laser scan topic and tell ROS to call
		// this->commandCallback() whenever a new message is published on that topic
		laserSub = nh.subscribe<sensor_msgs::LaserScan>("robot_2/base_scan", 1000, &RandomWalk::commandCallback, this);
		StageOdo_sub = nh.subscribe<nav_msgs::Odometry>("robot_2/odom",1000, &RandomWalk::StageOdom_callback,this);
		//ros::Subscriber StageOdo_sub = n.subscribe<nav_msgs::Odometry>("robot_0/odom",1000, StageOdom_callback);

	};

	void StageOdom_callback(nav_msgs::Odometry msg)
	{
		//This is the call back function to process odometry messages coming from Stage.

		px = -3 + msg.pose.pose.position.x;
		py = -3 + msg.pose.pose.position.y;
		//printf("%f",px);

		// If the current position is the same the previous position, then the robot is stuck and needs to move around
		if ((px == prevpx) && (py == prevpy)) {
			//msg.pose.pose.position.x = 5;
			//ROS_INFO("Prevpx: %f",prevpx);

			// Note the negative linear_x
			//linear_x=-0.2;
			//angular_z=1;

			//theta=10;
			//px = 5;
			//py= 5;
			//printf("Robot stuck");
			if (!isRotate) {
				ROS_INFO("Truck stuck");
				double r2 = (double)rand()/((double)RAND_MAX/(M_PI/2));
				double m2 = (double)rand()/((double)RAND_MAX/0.5);
				//ROS_INFO("r2" << r2);
				move(-m2, r2);

			}
		} else {
			// One the robot becomes unstuck, then it moves around again normally
			//linear_x = 0.2;
			//angular_z = 0.2;
			//ROS_INFO("Robot unstuck");
			//checkcount=0;
		}
		ROS_INFO("Truck -- Current x position is: %f", px);
		ROS_INFO("Truck -- Current y position is: %f", py);
		prevpx = px;
		prevpy = py;
	};

	// Send a velocity command
	void move(double linearVelMPS, double angularVelRadPS) {
		geometry_msgs::Twist msg; // The default constructor will set all commands to 0
		msg.linear.x = linearVelMPS;
		msg.angular.z = angularVelRadPS;
		commandPub.publish(msg);
	};

	// Process the incoming laser scan message
	void commandCallback(const sensor_msgs::LaserScan::ConstPtr& msg) {
		if (fsm == FSM_MOVE_FORWARD) {
			// Compute the average range value between MIN_SCAN_ANGLE and MAX_SCAN_ANGLE
			//
			// NOTE: ideally, the following loop should have additional checks to ensure
			// that indices are not out of bounds, by computing:
			//
			//- currAngle = msg->angle_min + msg->angle_increment*currIndex
			//
			// and then ensuring that currAngle <= msg->angle_max
			unsigned int minIndex = ceil((MIN_SCAN_ANGLE_RAD - msg->angle_min) / msg->angle_increment);
			unsigned int maxIndex = ceil((MAX_SCAN_ANGLE_RAD - msg->angle_min) / msg->angle_increment);
			float closestRange = msg->ranges[minIndex];

			for (unsigned int currIndex = minIndex + 1; currIndex < maxIndex; currIndex++) {
				if (msg->ranges[currIndex] < closestRange) {
					closestRange = msg->ranges[currIndex];
				}
			}
			//if (closestRange == prevclosestRange) {
			//	ROS_INFO_STREAM("STUCK");
			//	move(-FORWARD_SPEED_MPS, ROTATE_SPEED_RADPS);
			//	//move(0, ROTATE_SPEED_RADPS);
			//} else {

				//ROS_INFO_STREAM("Range: " << closestRange);
				prevclosestRange = closestRange;
				if (closestRange < PROXIMITY_RANGE_M) {
					fsm=FSM_ROTATE;
					rotateStartTime=ros::Time::now();
					float r2 = (float)rand()/((float)RAND_MAX/100);
					rotateDuration=ros::Duration(rand() % 2);
					//fsm= FSM_MOVE_FORWARD;
				}
			//}

		}
	};
	// Main FSM loop for ensuring that ROS messages are
	// processed in a timely manner, and also for sending
	// velocity controls to the simulated robot based on the FSM state
	void spin() {
		ros::Rate rate(10); // Specify the FSM loop rate in Hz
		while (ros::ok()) { // Keep spinning loop until user presses Ctrl+C
			std_msgs::String msg;
			std::stringstream ss;
			ss << "Truck -- px:" << px << " py:" << py << " theta:" << theta << " isRotate:" << isRotate;
    			msg.data = ss.str();

    			//ROS_INFO("%s", msg.data.c_str());

			if (fsm == FSM_MOVE_FORWARD) {
				//ROS_INFO_STREAM("Start forward");
				move(FORWARD_SPEED_MPS, 0);
				checkcount++;
				if (checkcount > 3) {
					isRotate=false;
				}
			}
			if (fsm == FSM_ROTATE) {
				//ROS_INFO_STREAM("Start rotate");
				move(0, ROTATE_SPEED_RADPS);
				rotateEndTime=ros::Time::now();
				isRotate=true;
				//ROS_INFO_STREAM("Time: " << rotateEndTime);

				if ((rotateEndTime - rotateStartTime) > rotateDuration) {
					fsm=FSM_MOVE_FORWARD;
					//ROS_INFO_STREAM("End rotate");
					checkcount=0;
				}
			}

		truckPosPub.publish(msg);

		ros::spinOnce(); // Need to call this function often to allow ROS to process incoming messages
		rate.sleep(); // Sleep for the rest of the cycle, to enforce the FSM loop rate
		}
	};
	enum FSM {FSM_MOVE_FORWARD, FSM_ROTATE};
	// Tunable parameters
	// TODO: tune parameters as you see fit
	const static double MIN_SCAN_ANGLE_RAD = -10.0/180*M_PI;
	const static double MAX_SCAN_ANGLE_RAD = +10.0/180*M_PI;
	const static float PROXIMITY_RANGE_M = 1; // Should be smaller than sensor_msgs::LaserScan::range_max
	const static double FORWARD_SPEED_MPS = 2;
	const static double ROTATE_SPEED_RADPS = M_PI/2;

	protected:
	ros::Publisher commandPub; // Publisher to the simulated robot's velocity command topic
	ros::Publisher truckPosPub;
	ros::Subscriber laserSub; // Subscriber to the simulated robot's laser scan topic
	enum FSM fsm; // Finite state machine for the random walk algorithm
	ros::Time rotateStartTime; // Start time of the rotation
	ros::Time rotateEndTime;
	ros::Duration rotateDuration; // Duration of the rotation
	ros::Subscriber StageOdo_sub;

};
int main(int argc, char **argv) {
	ros::init(argc, argv, "Trust"); // Initiate new ROS node named "Truck"
	ROS_INFO("This node is: Truck");
	ros::NodeHandle n;
	prevpx = 0;
	prevpx= 0;
	RandomWalk walker(n); // Create new random walk object
	walker.spin(); // Execute FSM loop
	return 0;
};

<|endoftext|>


<commit_before>//Copyright (c) 2021 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <gtest/gtest.h>

#include "../../src/BeadingStrategy/CenterDeviationBeadingStrategy.h" //Code under test.

namespace cura
{

/*!
 * Tests calling the constructor of the CenterDeviationBeadingStrategy and
 * whether it sets members correctly.
 */
TEST(CenterDeviationBeadingStrategy, Construction)
{
    CenterDeviationBeadingStrategy strategy(400, 0.6, 0.5, 0.5); //Pretty standard settings.
    EXPECT_EQ(strategy.getSplitMiddleThreshold(), 200) << "Since the transition threshold was 50%, the minimum line width should be 0.5 times the preferred width.";
    strategy = CenterDeviationBeadingStrategy(400, 0.6, 0, 0);
    EXPECT_EQ(strategy.getSplitMiddleThreshold(), 0) << "Since the transition threshold was 0%, the minimum line width should be 0.";
    strategy = CenterDeviationBeadingStrategy(0, 0.6, 0.5, 0.5);
    EXPECT_EQ(strategy.getSplitMiddleThreshold(), 0) << "Since the line width was 0%, the minimum line width should also be 0.";
    strategy = CenterDeviationBeadingStrategy(400, 0.6, 1, 1);
    EXPECT_EQ(strategy.getSplitMiddleThreshold(), 400) << "Since the transition threshold was 100%, the minimum line width equals the preferred width.";
}

/*!
 * Tests getting the optimal thickness with Center Deviation.
 *
 * This should simply be a multiplication of the line width, when using Center
 * Deviation. It doesn't adjust the line widths by itself.
 */
TEST(CenterDeviationBeadingStrategy, GetOptimalThickness)
{
    constexpr coord_t line_width = 400;
    CenterDeviationBeadingStrategy strategy(line_width, 0.6, 0.5, 0.5);
    EXPECT_EQ(strategy.getOptimalThickness(0), 0) << "With 0 beads, you'll fill 0 space.";
    EXPECT_EQ(strategy.getOptimalThickness(1), line_width) << "With 1 bead, optimally you'll want to print that bead at the optimal line width.";
    EXPECT_EQ(strategy.getOptimalThickness(4), 4 * line_width) << "With 4 beads, optimally fill 4 line widths.";
}

/*!
 * Test getting the width at which we need to transition to a greater number of
 * lines.
 */
TEST(CenterDeviationBeadingStrategy, GetTransitionThickness)
{
    constexpr coord_t line_width = 400;

    //Transition ratio 25%.
    CenterDeviationBeadingStrategy strategy(line_width, 0.6, 0.25, 0.25);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0.25 * line_width) << "The transition from 0 beads to 1 happens at 25% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 1.25 * line_width) << "The transition from 1 bead to 2 happens at 125% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(4), 4.25 * line_width) << "The transition from 4 beads to 5 happens at 4 + 25% line width.";

    //Transition ratio 50%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0.5, 0.5);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0.5 * line_width) << "The transition from 0 beads to 1 happens at 50% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 1.5 * line_width) << "The transition from 1 bead to 2 happens at 150% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(5), 5.5 * line_width) << "The transition from 5 beads to 6 happens at 5 + 50% line width.";

    //Transition ratio 95%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0.95, 0.95);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0.95 * line_width) << "The transition from 0 beads to 1 happens at 95% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 1.95 * line_width) << "The transition from 1 bead to 2 happens at 195% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(3), 3.95 * line_width) << "The transition from 3 beads to 4 happens at 3 + 95% line width.";

    //Transition ratio 100%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 1, 1);
    EXPECT_EQ(strategy.getTransitionThickness(0), line_width) << "Only transition to have a line if it fits completely.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 2 * line_width) << "Only transition to have two lines if they both fit completely.";
    EXPECT_EQ(strategy.getTransitionThickness(2), 3 * line_width) << "Only transition to have three lines if they all fit completely.";

    //Transition ratio 0%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0, 0);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0) << "Always transition to 1 line. The minimum line width is 0 after all.";
    EXPECT_EQ(strategy.getTransitionThickness(1), line_width) << "If 1 line fits completely, immediately transition to 2 lines.";
    EXPECT_EQ(strategy.getTransitionThickness(6), 6 * line_width) << "If 6 lines fit completely, immediately transition to 7 lines.";
}

/*!
 * Test getting the optimal bead count for a given shape width.
 */
TEST(CenterDeviationBeadingStrategy, GetOptimalBeadCount)
{
    constexpr coord_t line_width = 400;

    //Transition ratio 25%.
    CenterDeviationBeadingStrategy strategy(line_width, 0.6, 0.25, 0.25);
    //Anything below 25% line width should then produce 0 lines.
    for(coord_t width = 0; width < 0.25 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 0) << "Width is below the transition thickness from 0 to 1 line, so it should produce 0 lines.";
    }
    EXPECT_LE(strategy.getOptimalBeadCount(0.25 * line_width), 1) << "At exactly the transition thickness, either 0 or 1 line is acceptable.";
    for(coord_t width = 0.25 * line_width + 1; width < 1.25 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 1) << "Width is above the transition thickness from 0 to 1 line but below 1 to 2 lines, so it should produce 1 line.";
    }
    EXPECT_TRUE(strategy.getOptimalBeadCount(1.25 * line_width) == 1 || strategy.getOptimalBeadCount(1.25 * line_width) == 2) << "At exactly 125% line width, either 1 or 2 lines is acceptable.";
    for(coord_t width = 1.25 * line_width + 1; width < 2.25 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 2) << "Width is above the transition thickness from 1 to 2 lines but below 2 to 3 lines, so it should produce 2 lines.";
    }

    //Transition ratio 80%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0.8, 0.8);
    //Anything below 80% line width should then produce 0 lines.
    for(coord_t width = 0; width < 0.8 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 0) << "Width is below the transition thickness from 0 to 1 line, so it should produce 0 lines.";
    }
    EXPECT_LE(strategy.getOptimalBeadCount(0.8 * line_width), 1) << "At exactly the transition thickness, either 0 or 1 line is acceptable.";
    for(coord_t width = 0.8 * line_width + 1; width < 1.8 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 1) << "Width is above the transition thickness from 0 to 1 line but below 1 to 2 lines, so it should produce 1 line.";
    }
    EXPECT_TRUE(strategy.getOptimalBeadCount(1.8 * line_width) == 1 || strategy.getOptimalBeadCount(1.8 * line_width) == 2) << "At exactly 180% line width, either 1 or 2 lines is acceptable.";
    for(coord_t width = 1.8 * line_width + 1; width < 2.8 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 2) << "Width is above the transition thickness from 1 to 2 lines but below 2 to 3 lines, so it should produce 2 lines.";
    }
}

/*!
 * Tests whether the line compactness setting does what it is supposed to do,
 * producing fewer, wider lines when the setting is high than when the setting
 * is low.
 *
 * This is a test for requirements. The exact outcome of a function is not
 * tested, but properties of the outcome is tested.
 */
TEST(CenterDeviationBeadingStrategy, LineCompactnessMonotonic)
{
    constexpr coord_t line_width = 400;
    constexpr coord_t widths[] = {0, 1, 99, 101, 150, 200, 299, 300, 301, 399, 400, 401, 410, 450, 500, 660, 770, 880, 910, 1000, 1200}; //Bunch of widths to test with.
    constexpr float compactnesses[] = {0, 0.1, 0.2, 0.24, 0.25, 0.26, 0.3, 0.5, 0.7, 0.75, 0.99, 1}; //Bunch of line compactness factors to test with.
    constexpr size_t num_compactnesses = sizeof(compactnesses) / sizeof(float);

    for(coord_t width : widths)
    {
        for(size_t low_index = 0; low_index < num_compactnesses; ++low_index)
        {
            const float low_compactness = compactnesses[low_index];
            for(size_t high_index = low_index; high_index < num_compactnesses; ++high_index)
            {
                const float high_compactness = compactnesses[high_index];

                EXPECT_GE(
                        CenterDeviationBeadingStrategy(line_width, 0.6, low_compactness, low_compactness).getOptimalBeadCount(width),
                        CenterDeviationBeadingStrategy(line_width, 0.6, high_compactness, high_compactness).getOptimalBeadCount(width)
                ) << "When the compactness is low, the number of beads should always be greater or equal to when the compactness is high.";
            }
        }
    }
}

}<commit_msg>'Fix' test 'Construction of Center-Deviation Strategy'.<commit_after>//Copyright (c) 2021 Ultimaker B.V.
//CuraEngine is released under the terms of the AGPLv3 or higher.

#include <gtest/gtest.h>

#include "../../src/BeadingStrategy/CenterDeviationBeadingStrategy.h" //Code under test.

namespace cura
{

/*!
 * Tests calling the constructor of the CenterDeviationBeadingStrategy and
 * whether it sets members correctly.
 */
TEST(CenterDeviationBeadingStrategy, Construction)
{
    CenterDeviationBeadingStrategy strategy(400, 0.6, 0.5, 0.75);
    EXPECT_EQ(strategy.getSplitMiddleThreshold(), 0.5) << "Split-middle threshold should be the one it's constructed with.";
    EXPECT_EQ(strategy.getAddMiddleThreshold(), 0.75) << "Add-middle threshold should be the one it's constructed with.";
}

/*!
 * Tests getting the optimal thickness with Center Deviation.
 *
 * This should simply be a multiplication of the line width, when using Center
 * Deviation. It doesn't adjust the line widths by itself.
 */
TEST(CenterDeviationBeadingStrategy, GetOptimalThickness)
{
    constexpr coord_t line_width = 400;
    CenterDeviationBeadingStrategy strategy(line_width, 0.6, 0.5, 0.5);
    EXPECT_EQ(strategy.getOptimalThickness(0), 0) << "With 0 beads, you'll fill 0 space.";
    EXPECT_EQ(strategy.getOptimalThickness(1), line_width) << "With 1 bead, optimally you'll want to print that bead at the optimal line width.";
    EXPECT_EQ(strategy.getOptimalThickness(4), 4 * line_width) << "With 4 beads, optimally fill 4 line widths.";
}

/*!
 * Test getting the width at which we need to transition to a greater number of
 * lines.
 */
TEST(CenterDeviationBeadingStrategy, GetTransitionThickness)
{
    constexpr coord_t line_width = 400;

    //Transition ratio 25%.
    CenterDeviationBeadingStrategy strategy(line_width, 0.6, 0.25, 0.25);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0.25 * line_width) << "The transition from 0 beads to 1 happens at 25% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 1.25 * line_width) << "The transition from 1 bead to 2 happens at 125% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(4), 4.25 * line_width) << "The transition from 4 beads to 5 happens at 4 + 25% line width.";

    //Transition ratio 50%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0.5, 0.5);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0.5 * line_width) << "The transition from 0 beads to 1 happens at 50% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 1.5 * line_width) << "The transition from 1 bead to 2 happens at 150% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(5), 5.5 * line_width) << "The transition from 5 beads to 6 happens at 5 + 50% line width.";

    //Transition ratio 95%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0.95, 0.95);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0.95 * line_width) << "The transition from 0 beads to 1 happens at 95% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 1.95 * line_width) << "The transition from 1 bead to 2 happens at 195% line width.";
    EXPECT_EQ(strategy.getTransitionThickness(3), 3.95 * line_width) << "The transition from 3 beads to 4 happens at 3 + 95% line width.";

    //Transition ratio 100%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 1, 1);
    EXPECT_EQ(strategy.getTransitionThickness(0), line_width) << "Only transition to have a line if it fits completely.";
    EXPECT_EQ(strategy.getTransitionThickness(1), 2 * line_width) << "Only transition to have two lines if they both fit completely.";
    EXPECT_EQ(strategy.getTransitionThickness(2), 3 * line_width) << "Only transition to have three lines if they all fit completely.";

    //Transition ratio 0%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0, 0);
    EXPECT_EQ(strategy.getTransitionThickness(0), 0) << "Always transition to 1 line. The minimum line width is 0 after all.";
    EXPECT_EQ(strategy.getTransitionThickness(1), line_width) << "If 1 line fits completely, immediately transition to 2 lines.";
    EXPECT_EQ(strategy.getTransitionThickness(6), 6 * line_width) << "If 6 lines fit completely, immediately transition to 7 lines.";
}

/*!
 * Test getting the optimal bead count for a given shape width.
 */
TEST(CenterDeviationBeadingStrategy, GetOptimalBeadCount)
{
    constexpr coord_t line_width = 400;

    //Transition ratio 25%.
    CenterDeviationBeadingStrategy strategy(line_width, 0.6, 0.25, 0.25);
    //Anything below 25% line width should then produce 0 lines.
    for(coord_t width = 0; width < 0.25 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 0) << "Width is below the transition thickness from 0 to 1 line, so it should produce 0 lines.";
    }
    EXPECT_LE(strategy.getOptimalBeadCount(0.25 * line_width), 1) << "At exactly the transition thickness, either 0 or 1 line is acceptable.";
    for(coord_t width = 0.25 * line_width + 1; width < 1.25 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 1) << "Width is above the transition thickness from 0 to 1 line but below 1 to 2 lines, so it should produce 1 line.";
    }
    EXPECT_TRUE(strategy.getOptimalBeadCount(1.25 * line_width) == 1 || strategy.getOptimalBeadCount(1.25 * line_width) == 2) << "At exactly 125% line width, either 1 or 2 lines is acceptable.";
    for(coord_t width = 1.25 * line_width + 1; width < 2.25 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 2) << "Width is above the transition thickness from 1 to 2 lines but below 2 to 3 lines, so it should produce 2 lines.";
    }

    //Transition ratio 80%.
    strategy = CenterDeviationBeadingStrategy(line_width, 0.6, 0.8, 0.8);
    //Anything below 80% line width should then produce 0 lines.
    for(coord_t width = 0; width < 0.8 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 0) << "Width is below the transition thickness from 0 to 1 line, so it should produce 0 lines.";
    }
    EXPECT_LE(strategy.getOptimalBeadCount(0.8 * line_width), 1) << "At exactly the transition thickness, either 0 or 1 line is acceptable.";
    for(coord_t width = 0.8 * line_width + 1; width < 1.8 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 1) << "Width is above the transition thickness from 0 to 1 line but below 1 to 2 lines, so it should produce 1 line.";
    }
    EXPECT_TRUE(strategy.getOptimalBeadCount(1.8 * line_width) == 1 || strategy.getOptimalBeadCount(1.8 * line_width) == 2) << "At exactly 180% line width, either 1 or 2 lines is acceptable.";
    for(coord_t width = 1.8 * line_width + 1; width < 2.8 * line_width; width += 10)
    {
        EXPECT_EQ(strategy.getOptimalBeadCount(width), 2) << "Width is above the transition thickness from 1 to 2 lines but below 2 to 3 lines, so it should produce 2 lines.";
    }
}

/*!
 * Tests whether the line compactness setting does what it is supposed to do,
 * producing fewer, wider lines when the setting is high than when the setting
 * is low.
 *
 * This is a test for requirements. The exact outcome of a function is not
 * tested, but properties of the outcome is tested.
 */
TEST(CenterDeviationBeadingStrategy, LineCompactnessMonotonic)
{
    constexpr coord_t line_width = 400;
    constexpr coord_t widths[] = {0, 1, 99, 101, 150, 200, 299, 300, 301, 399, 400, 401, 410, 450, 500, 660, 770, 880, 910, 1000, 1200}; //Bunch of widths to test with.
    constexpr float compactnesses[] = {0, 0.1, 0.2, 0.24, 0.25, 0.26, 0.3, 0.5, 0.7, 0.75, 0.99, 1}; //Bunch of line compactness factors to test with.
    constexpr size_t num_compactnesses = sizeof(compactnesses) / sizeof(float);

    for(coord_t width : widths)
    {
        for(size_t low_index = 0; low_index < num_compactnesses; ++low_index)
        {
            const float low_compactness = compactnesses[low_index];
            for(size_t high_index = low_index; high_index < num_compactnesses; ++high_index)
            {
                const float high_compactness = compactnesses[high_index];

                EXPECT_GE(
                        CenterDeviationBeadingStrategy(line_width, 0.6, low_compactness, low_compactness).getOptimalBeadCount(width),
                        CenterDeviationBeadingStrategy(line_width, 0.6, high_compactness, high_compactness).getOptimalBeadCount(width)
                ) << "When the compactness is low, the number of beads should always be greater or equal to when the compactness is high.";
            }
        }
    }
}

}<|endoftext|>