<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cairo_canvascustomsprite.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 03:18:22 $
 *
 *  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_canvas.hxx"

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <rtl/logfile.hxx>
#include <rtl/math.hxx>

#include <canvas/canvastools.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/point/b2dpoint.hxx>

#include "cairo_canvascustomsprite.hxx"
#include "cairo_spritecanvas.hxx"

using namespace ::cairo;
using namespace ::com::sun::star;

namespace cairocanvas
{
    CanvasCustomSprite::CanvasCustomSprite( const ::com::sun::star::geometry::RealSize2D&   rSpriteSize,
                                            const SpriteCanvasRef&                          rRefDevice ) :
        mpSpriteCanvas( rRefDevice ),
        maSize( ::canvas::tools::roundUp( rSpriteSize.Width ),
                ::canvas::tools::roundUp( rSpriteSize.Height ) )
    {
        ENSURE_AND_THROW( rRefDevice.get(),
                          "CanvasCustomSprite::CanvasCustomSprite(): Invalid sprite canvas" );

        //mpBufferSurface = mpSpriteCanvas->getSurface( aSize, CAIRO_CONTENT_COLOR );
        mpBufferSurface = mpSpriteCanvas->getSurface( maSize );

        maCanvasHelper.init( maSize, *rRefDevice.get() );
        maCanvasHelper.setSurface( mpBufferSurface, true, this );

        maSpriteHelper.init( rSpriteSize,
                             rRefDevice );
        maSpriteHelper.setSurface( mpBufferSurface );
    }

    ::cairo::Surface* CanvasCustomSprite::changeSurface( bool bHasAlpha, bool bCopyContent )
    {
        if( !bHasAlpha && !bCopyContent )
        {
            OSL_TRACE("replacing sprite background surface");

            if( mpBufferSurface )
                mpBufferSurface->Unref();
            mpBufferSurface = mpSpriteCanvas->getSurface( maSize, CAIRO_CONTENT_COLOR );

            maSpriteHelper.setSurface( mpBufferSurface );

            return mpBufferSurface;
        }

        return NULL;
    }

    void SAL_CALL CanvasCustomSprite::disposing()
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        mpSpriteCanvas.clear();

        if( mpBufferSurface )
        {
            mpBufferSurface->Unref();
            mpBufferSurface = NULL;
        }

        // forward to parent
        CanvasCustomSpriteBaseT::disposing();
    }

    void CanvasCustomSprite::redraw( Cairo* pCairo,
                                     bool bBufferedUpdate ) const
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        redraw( pCairo, maSpriteHelper.getPosPixel(), bBufferedUpdate );
    }

    void CanvasCustomSprite::redraw( Cairo* pCairo,
                                     const ::basegfx::B2DPoint& rOrigOutputPos,
                                     bool bBufferedUpdate ) const
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        maSpriteHelper.redraw( pCairo,
                               rOrigOutputPos,
                               mbSurfaceDirty,
                               bBufferedUpdate );

        mbSurfaceDirty = false;
    }

    bool CanvasCustomSprite::repaint( Surface* pSurface,
                      const rendering::ViewState&   viewState,
                      const rendering::RenderState& renderState )
    {
    return maCanvasHelper.repaint( pSurface, viewState, renderState );
    }

#define IMPLEMENTATION_NAME "CairoCanvas.CanvasCustomSprite"
#define SERVICE_NAME "com.sun.star.rendering.CanvasCustomSprite"

    ::rtl::OUString SAL_CALL CanvasCustomSprite::getImplementationName() throw( uno::RuntimeException )
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

    sal_Bool SAL_CALL CanvasCustomSprite::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException )
    {
        return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
    }

    uno::Sequence< ::rtl::OUString > SAL_CALL CanvasCustomSprite::getSupportedServiceNames()  throw( uno::RuntimeException )
    {
        uno::Sequence< ::rtl::OUString > aRet(1);
        aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );

        return aRet;
    }
}
<commit_msg>INTEGRATION: CWS cairofixes02 (1.2.20); FILE MERGED 2006/10/09 16:30:25 radekdoulik 1.2.20.2: RESYNC: (1.2-1.3); FILE MERGED 2006/06/30 14:04:58 radekdoulik 1.2.20.1: #i65683# fixes problem of text bounds, visible in text animations, where the top of text was clipped out<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: cairo_canvascustomsprite.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2006-11-01 14:45: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
 *
 ************************************************************************/

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

#include <canvas/debug.hxx>
#include <canvas/verbosetrace.hxx>

#include <rtl/logfile.hxx>
#include <rtl/math.hxx>

#include <canvas/canvastools.hxx>

#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/point/b2dpoint.hxx>

#include "cairo_canvascustomsprite.hxx"
#include "cairo_spritecanvas.hxx"

using namespace ::cairo;
using namespace ::com::sun::star;

namespace cairocanvas
{
    CanvasCustomSprite::CanvasCustomSprite( const ::com::sun::star::geometry::RealSize2D&   rSpriteSize,
                                            const SpriteCanvasRef&                          rRefDevice ) :
        mpSpriteCanvas( rRefDevice ),
        maSize( ::canvas::tools::roundUp( rSpriteSize.Width ),
                ::canvas::tools::roundUp( rSpriteSize.Height ) )
    {
        ENSURE_AND_THROW( rRefDevice.get(),
                          "CanvasCustomSprite::CanvasCustomSprite(): Invalid sprite canvas" );

        OSL_TRACE("sprite size: %d, %d",
                  ::canvas::tools::roundUp( rSpriteSize.Width ),
                  ::canvas::tools::roundUp( rSpriteSize.Height ));

        //mpBufferSurface = mpSpriteCanvas->getSurface( aSize, CAIRO_CONTENT_COLOR );
        mpBufferSurface = mpSpriteCanvas->getSurface( maSize );

        maCanvasHelper.init( maSize, *rRefDevice.get() );
        maCanvasHelper.setSurface( mpBufferSurface, true, this );

        maSpriteHelper.init( rSpriteSize,
                             rRefDevice );
        maSpriteHelper.setSurface( mpBufferSurface );
    }

    ::cairo::Surface* CanvasCustomSprite::changeSurface( bool bHasAlpha, bool bCopyContent )
    {
        if( !bHasAlpha && !bCopyContent )
        {
            OSL_TRACE("replacing sprite background surface");

            if( mpBufferSurface )
                mpBufferSurface->Unref();
            mpBufferSurface = mpSpriteCanvas->getSurface( maSize, CAIRO_CONTENT_COLOR );

            maSpriteHelper.setSurface( mpBufferSurface );

            return mpBufferSurface;
        }

        return NULL;
    }

    void SAL_CALL CanvasCustomSprite::disposing()
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        mpSpriteCanvas.clear();

        if( mpBufferSurface )
        {
            mpBufferSurface->Unref();
            mpBufferSurface = NULL;
        }

        // forward to parent
        CanvasCustomSpriteBaseT::disposing();
    }

    void CanvasCustomSprite::redraw( Cairo* pCairo,
                                     bool bBufferedUpdate ) const
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        redraw( pCairo, maSpriteHelper.getPosPixel(), bBufferedUpdate );
    }

    void CanvasCustomSprite::redraw( Cairo* pCairo,
                                     const ::basegfx::B2DPoint& rOrigOutputPos,
                                     bool bBufferedUpdate ) const
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        maSpriteHelper.redraw( pCairo,
                               rOrigOutputPos,
                               mbSurfaceDirty,
                               bBufferedUpdate );

        mbSurfaceDirty = false;
    }

    bool CanvasCustomSprite::repaint( Surface* pSurface,
                      const rendering::ViewState&   viewState,
                      const rendering::RenderState& renderState )
    {
    return maCanvasHelper.repaint( pSurface, viewState, renderState );
    }

#define IMPLEMENTATION_NAME "CairoCanvas.CanvasCustomSprite"
#define SERVICE_NAME "com.sun.star.rendering.CanvasCustomSprite"

    ::rtl::OUString SAL_CALL CanvasCustomSprite::getImplementationName() throw( uno::RuntimeException )
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( IMPLEMENTATION_NAME ) );
    }

    sal_Bool SAL_CALL CanvasCustomSprite::supportsService( const ::rtl::OUString& ServiceName ) throw( uno::RuntimeException )
    {
        return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ) );
    }

    uno::Sequence< ::rtl::OUString > SAL_CALL CanvasCustomSprite::getSupportedServiceNames()  throw( uno::RuntimeException )
    {
        uno::Sequence< ::rtl::OUString > aRet(1);
        aRet[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );

        return aRet;
    }
}
<|endoftext|>


<commit_before>// TortoiseSVN - a Windows shell extension for easy version control

// Copyright (C) 2003-2006 - Stefan Kueng

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program 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 General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#include "stdafx.h"
#include "ResModule.h"

#include <string>
#include <vector>
#include "shlwapi.h"
#pragma comment(lib, "shlwapi.lib")

typedef std::basic_string<wchar_t> wstring;
#ifdef UNICODE
#	define stdstring wstring
#else
#	define stdstring std::string
#endif

int _tmain(int argc, _TCHAR* argv[])
{
	bool bShowHelp = true;
	bool bQuiet = false;
	bool bNoUpdate = false;
	bool bRTL = false;
   bool bShowDefault = false;
	//parse the command line
	std::vector<stdstring> arguments;
	std::vector<stdstring> switches;
	for (int i=1; i<argc; ++i)
	{
		if ((argv[i][0] == '-')||(argv[i][0] == '/'))
		{
			stdstring str = stdstring(&argv[i][1]);
			switches.push_back(str);
		}
		else
		{
			stdstring str = stdstring(&argv[i][0]);
			arguments.push_back(str);
		}
	}

	for (std::vector<stdstring>::iterator I = switches.begin(); I != switches.end(); ++I)
	{
		if (_tcscmp(I->c_str(), _T("?"))==0)
			bShowHelp = true;
		if (_tcscmp(I->c_str(), _T("help"))==0)
			bShowHelp = true;
		if (_tcscmp(I->c_str(), _T("quiet"))==0)
			bQuiet = true;
		if (_tcscmp(I->c_str(), _T("noupdate"))==0)
			bNoUpdate = true;
		if (_tcscmp(I->c_str(), _T("rtl"))==0)
			bRTL = true;
      if (_tcscmp(I->c_str(), _T("showdefault"))==0)
			bShowDefault = true;
	}
	std::vector<stdstring>::iterator arg = arguments.begin();

	if (arg != arguments.end())
	{
		if (_tcscmp(arg->c_str(), _T("extract"))==0)
		{
			stdstring sDllFile;
			stdstring sPoFile;
			++arg;

			std::vector<std::wstring> filelist = arguments;
			filelist.erase(filelist.begin());
			sPoFile = stdstring((--filelist.end())->c_str());
			filelist.erase(--filelist.end());

			CResModule module;
			module.SetQuiet(bQuiet);
			if (!module.ExtractResources(filelist, sPoFile.c_str(), bNoUpdate))
				return -1;
			bShowHelp = false;
		}
		else if (_tcscmp(arg->c_str(), _T("apply"))==0)
		{
			stdstring sSrcDllFile;
			stdstring sDstDllFile;
			stdstring sPoFile;
			WORD wLang = 0;
			++arg;
			if (!PathFileExists(arg->c_str()))
			{
				_ftprintf(stderr, _T("the resource dll <%s> does not exist!\n"), arg->c_str());
				return -1;
			}
			sSrcDllFile = stdstring(arg->c_str());
			++arg;
			sDstDllFile = stdstring(arg->c_str());
			++arg;
			if (!PathFileExists(arg->c_str()))
			{
				_ftprintf(stderr, _T("the po-file <%s> does not exist!\n"), arg->c_str());
				return -1;
			}
			sPoFile = stdstring(arg->c_str());
			++arg;
			if (arg != arguments.end())
			{
				wLang = (WORD)_ttoi(arg->c_str());
			}
			CResModule module;
			module.SetQuiet(bQuiet);
			module.SetLanguage(wLang);
			module.SetRTL(bRTL);
         module.SetShowDefault(bShowDefault);
			if (!module.CreateTranslatedResources(sSrcDllFile.c_str(), sDstDllFile.c_str(), sPoFile.c_str()))
				return -1;
			bShowHelp = false;
		}
	}

	if (bShowHelp)
	{
		_ftprintf(stdout, _T("usage:\n"));
		_ftprintf(stdout, _T("\n"));
		_ftprintf(stdout, _T("ResText extract <resource.dll> [<resource.dll> ...] <po-file> [-quiet] [-noupdate]\n"));
		_ftprintf(stdout, _T("Extracts all strings from the resource dll and writes them to the po-file\n"));
		_ftprintf(stdout, _T("-quiet: don't print progress messages\n"));
		_ftprintf(stdout, _T("-noupdate: overwrite the po-file\n"));
		_ftprintf(stdout, _T("\n"));
		_ftprintf(stdout, _T("ResText apply <src resource.dll> <dst resource.dll> <po-file> [langID] [-quiet][-rtl] [-showdefault]\n"));
		_ftprintf(stdout, _T("Replaces all strings in the dst resource.dll with the po-file translations\n"));
		_ftprintf(stdout, _T("-quiet: don't print progress messages\n"));
		_ftprintf(stdout, _T("-rtl  : change the controls to RTL reading\n"));
      _ftprintf(stdout, _T("-showdefault  : print untranslated values to stderr\n"));
		_ftprintf(stdout, _T("\n"));
	}

	return 0;
}

<commit_msg>Very minor Nit<commit_after>// TortoiseSVN - a Windows shell extension for easy version control

// Copyright (C) 2003-2006 - Stefan Kueng

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.

// This program 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 General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#include "stdafx.h"
#include "ResModule.h"

#include <string>
#include <vector>
#include "shlwapi.h"
#pragma comment(lib, "shlwapi.lib")

typedef std::basic_string<wchar_t> wstring;
#ifdef UNICODE
#	define stdstring wstring
#else
#	define stdstring std::string
#endif

int _tmain(int argc, _TCHAR* argv[])
{
	bool bShowHelp = true;
	bool bQuiet = false;
	bool bNoUpdate = false;
	bool bRTL = false;
   bool bShowDefault = false;
	//parse the command line
	std::vector<stdstring> arguments;
	std::vector<stdstring> switches;
	for (int i=1; i<argc; ++i)
	{
		if ((argv[i][0] == '-')||(argv[i][0] == '/'))
		{
			stdstring str = stdstring(&argv[i][1]);
			switches.push_back(str);
		}
		else
		{
			stdstring str = stdstring(&argv[i][0]);
			arguments.push_back(str);
		}
	}

	for (std::vector<stdstring>::iterator I = switches.begin(); I != switches.end(); ++I)
	{
		if (_tcscmp(I->c_str(), _T("?"))==0)
			bShowHelp = true;
		if (_tcscmp(I->c_str(), _T("help"))==0)
			bShowHelp = true;
		if (_tcscmp(I->c_str(), _T("quiet"))==0)
			bQuiet = true;
		if (_tcscmp(I->c_str(), _T("noupdate"))==0)
			bNoUpdate = true;
		if (_tcscmp(I->c_str(), _T("rtl"))==0)
			bRTL = true;
      if (_tcscmp(I->c_str(), _T("showdefault"))==0)
			bShowDefault = true;
	}
	std::vector<stdstring>::iterator arg = arguments.begin();

	if (arg != arguments.end())
	{
		if (_tcscmp(arg->c_str(), _T("extract"))==0)
		{
			stdstring sDllFile;
			stdstring sPoFile;
			++arg;

			std::vector<std::wstring> filelist = arguments;
			filelist.erase(filelist.begin());
			sPoFile = stdstring((--filelist.end())->c_str());
			filelist.erase(--filelist.end());

			CResModule module;
			module.SetQuiet(bQuiet);
			if (!module.ExtractResources(filelist, sPoFile.c_str(), bNoUpdate))
				return -1;
			bShowHelp = false;
		}
		else if (_tcscmp(arg->c_str(), _T("apply"))==0)
		{
			stdstring sSrcDllFile;
			stdstring sDstDllFile;
			stdstring sPoFile;
			WORD wLang = 0;
			++arg;
			if (!PathFileExists(arg->c_str()))
			{
				_ftprintf(stderr, _T("the resource dll <%s> does not exist!\n"), arg->c_str());
				return -1;
			}
			sSrcDllFile = stdstring(arg->c_str());
			++arg;
			sDstDllFile = stdstring(arg->c_str());
			++arg;
			if (!PathFileExists(arg->c_str()))
			{
				_ftprintf(stderr, _T("the po-file <%s> does not exist!\n"), arg->c_str());
				return -1;
			}
			sPoFile = stdstring(arg->c_str());
			++arg;
			if (arg != arguments.end())
			{
				wLang = (WORD)_ttoi(arg->c_str());
			}
			CResModule module;
			module.SetQuiet(bQuiet);
			module.SetLanguage(wLang);
			module.SetRTL(bRTL);
         module.SetShowDefault(bShowDefault);
			if (!module.CreateTranslatedResources(sSrcDllFile.c_str(), sDstDllFile.c_str(), sPoFile.c_str()))
				return -1;
			bShowHelp = false;
		}
	}

	if (bShowHelp)
	{
		_ftprintf(stdout, _T("usage:\n"));
		_ftprintf(stdout, _T("\n"));
		_ftprintf(stdout, _T("ResText extract <resource.dll> [<resource.dll> ...] <po-file> [-quiet] [-noupdate]\n"));
		_ftprintf(stdout, _T("Extracts all strings from the resource dll and writes them to the po-file\n"));
		_ftprintf(stdout, _T("-quiet: don't print progress messages\n"));
		_ftprintf(stdout, _T("-noupdate: overwrite the po-file\n"));
		_ftprintf(stdout, _T("\n"));
		_ftprintf(stdout, _T("ResText apply <src resource.dll> <dst resource.dll> <po-file> [langID] [-quiet][-rtl] [-showdefault]\n"));
		_ftprintf(stdout, _T("Replaces all strings in the dst resource.dll with the po-file translations\n"));
		_ftprintf(stdout, _T("-quiet: don't print progress messages\n"));
		_ftprintf(stdout, _T("-rtl  : change the controls to RTL reading\n"));
		_ftprintf(stdout, _T("-showdefault  : print untranslated values to stderr\n"));
		_ftprintf(stdout, _T("\n"));
	}

	return 0;
}

<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_GRID_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRID_PROVIDER_CUBE_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include <config.h>
#endif // ifdef HAVE_CMAKE_CONFIG

#if HAVE_DUNE_GRID

#include <sstream>
#include <type_traits>
#include <boost/assign/list_of.hpp>

#include <dune/common/parametertree.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/static_assert.hh>

#include <dune/grid/utility/structuredgridfactory.hh>
#include <dune/grid/yaspgrid.hh>
#ifdef HAVE_ALUGRID
  #include <dune/grid/alugrid.hh>
#endif
#include <dune/grid/sgrid.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/color.hh>

#include "interface.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace Provider {

template< typename GridType >
struct ElementVariant;

/**
 *  \brief  Creates a grid of a cube in various dimensions.
 *
 *          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
 *          dimensions. Tested with
 *

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c SGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,
 *
 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and
 *
 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

 *  \tparam GridImp
 *          Type of the underlying grid.
 *  \tparam variant
 *          Type of the codim 0 elements:
 *

\c 1: cubes
 *
2: simplices

 **/
template< typename GridImp, int variant = ElementVariant<GridImp>::id>
class GenericCube
  : public Interface< GridImp >
{
public:
  //! Type of the provided grid.
  typedef GridImp GridType;

  typedef Interface< GridType > BaseType;

  typedef GenericCube< GridType, variant > ThisType;

private:
  typedef typename GridType::LeafGridView GridViewType;

public:
  static const unsigned int dim = BaseType::dim;

  //! Type of the grids coordinates.
  typedef typename GridType::ctype ctype;
  typedef Dune::FieldVector< ctype, dim > CoordinateType;

  //! Unique identifier: \c stuff.grid.provider.cube
  static const std::string id()
  {
    return BaseType::id() + ".cube";
  }

  /**
   *  \brief      Creates a cube.
   *  \param[in]  _lowerLeft
   *              A double that is used as a lower left corner in each dimension.
   *  \param[in]  _upperRight
   *              A double that is used as a upper right corner in each dimension.
   *  \param[in]  numElements (optional)
   *              number of elements.
   **/
  GenericCube(const double _lowerLeft = 0.0, const double _upperRight = 1.0, const unsigned int numElements = 1u)
    : lowerLeft_(_lowerLeft)
    , upperRight_(_upperRight)
  {
    Dune::array< unsigned int, dim > tmpNumElements;
    std::fill(tmpNumElements.begin(), tmpNumElements.end(), numElements);
    buildGrid(tmpNumElements);
  }

  /**
   *  \brief      Creates a cube.
   *  \param[in]  _lowerLeft
   *              A vector that is used as a lower left corner.
   *  \param[in]  _upperRight
   *              A vector that is used as a upper right corner.
   *  \param[in]  numElements (optional)
   *              number of elements.
   **/
  GenericCube(const CoordinateType& _lowerLeft, const CoordinateType& _upperRight, const unsigned int numElements = 1u)
    : lowerLeft_(_lowerLeft)
    , upperRight_(_upperRight)
  {
    Dune::array< unsigned int, dim > tmpNumElements;
    std::fill(tmpNumElements.begin(), tmpNumElements.end(), numElements);
    buildGrid(tmpNumElements);
  }

  /**
    \brief      Creates a cube. This signature allows to prescribe anisotopic refinement
    \param[in]  _lowerLeft
                A double that is used as a lower left corner in each dimension.
    \param[in]  _upperRight
                A double that is used as a upper right corner in each dimension.
    \param[in]  numElements
                number of elements in each dimension.
                can contain 0 to dim elements (missing dimension are initialized to 1)
    \tparam ContainerType some sequence type that functions with std::begin/end
    **/
  template< class ContainerType  >
  GenericCube(const CoordinateType& _lowerLeft, const CoordinateType& _upperRight,
              const ContainerType numElements
                = boost::assign::list_of< typename ContainerType::value_type>().repeat(dim,
                                                                                typename ContainerType::value_type(1u)))
    : lowerLeft_(_lowerLeft),
      upperRight_(_upperRight)
  {
    Dune::array< unsigned int, dim > tmpNumElements;
    static_assert(std::is_unsigned< typename ContainerType::value_type >::value
                  && std::is_integral< typename ContainerType::value_type >::value,
                  "only unsigned integral number of elements per dimension allowed");
    //base init in case input is shorter
    std::fill(tmpNumElements.begin(), tmpNumElements.end(), 1u);
    std::copy(numElements.begin(), numElements.end(), tmpNumElements.begin());
    buildGrid(tmpNumElements);
  }

  static Dune::ParameterTree createSampleDescription(const std::string subName = "")
  {
    Dune::ParameterTree description;
    description["lowerLeft"] = "[0.0; 0.0; 0.0]";
    description["upperRight"] = "[1.0; 1.0; 1.0]";
    description["numElements"] = "[2; 2; 2]";
    if (subName.empty())
      return description;
    else {
      Dune::Stuff::Common::ExtendedParameterTree extendedDescription;
      extendedDescription.add(description, subName);
      return extendedDescription;
    }
  }

  /**
   *  \brief      Creates a cube.
   *  \param[in]  paramTree
   *              A Dune::ParameterTree containing
   *

 the following keys directly or
   *
 a subtree named Cube::id, containing the following keys. If a subtree is present, it is always selected. Also it is solely selceted, so that all keys in the supertree are ignored.

   *              The actual keys are:
   *

 \c lowerLeft: \a double or a vector that is used as lower left corners.
   *
 \c upperRight: \a double or a vector that is used as upper right corners.
   *
 \c numElements: \a int or vector to denote the number of elements.
   *

   **/
  static ThisType* createFromDescription(const Dune::ParameterTree& paramTree, const std::string subName = id())
  {
    // get correct paramTree
    Dune::Stuff::Common::ExtendedParameterTree extendedParamTree;
    if (paramTree.hasSub(subName))
      extendedParamTree = paramTree.sub(subName);
    else
      extendedParamTree = paramTree;
    // get lower left
    std::vector< ctype > lowerLefts;
    if (extendedParamTree.hasVector("lowerLeft")) {
      lowerLefts = extendedParamTree.getVector("lowerLeft", ctype(0), dim);
      assert(lowerLefts.size() >= dim && "Given vector too short!");
    } else if (extendedParamTree.hasKey("lowerLeft")) {
        const ctype lowerLeft = extendedParamTree.get("lowerLeft", ctype(0));
        lowerLefts = std::vector< ctype >(dim, lowerLeft);
    } else {
      std::cout << "\n" << Dune::Stuff::Common::colorString("WARNING in " + id() + ":")
                << " neither vector nor key 'lowerLeft' given, defaulting to 0.0!" << std::flush;
      lowerLefts = std::vector< ctype >(dim, ctype(0));
    }
    // get upper right
    std::vector< ctype > upperRights;
    if (extendedParamTree.hasVector("upperRight")) {
      upperRights = extendedParamTree.getVector("upperRight", ctype(1), dim);
      assert(upperRights.size() >= dim && "Given vector too short!");
    } else if (extendedParamTree.hasKey("upperRight")) {
        const ctype upperRight = extendedParamTree.get("upperRight", ctype(1));
        upperRights = std::vector< ctype >(dim, upperRight);
    } else {
      std::cout << "\n" << Dune::Stuff::Common::colorString("WARNING in " + id() + ":")
                << " neither vector nor key 'upperRight' given, defaulting to 1.0!" << std::flush;
      upperRights = std::vector< ctype >(dim, ctype(1));
    }
    // get number of elements
    std::vector< unsigned int > tmpNumElements;
    if (extendedParamTree.hasVector("numElements")) {
      tmpNumElements = extendedParamTree.getVector("numElements", 1u, dim);
      assert(tmpNumElements.size() >= dim && "Given vector too short!");
    } else if (extendedParamTree.hasKey("numElements")) {
        const unsigned int numElement = extendedParamTree.get("numElements", 1u);
        tmpNumElements = std::vector< unsigned int >(dim, numElement);
    } else {
      std::cout << "\n" << Dune::Stuff::Common::colorString("WARNING in " + id() + ":")
                << " neither vector nor key 'numElements' given, defaulting to 1!" << std::flush;
      tmpNumElements = std::vector< unsigned int >(dim, 1u);
    }
    // check and save
    CoordinateType lowerLeft;
    CoordinateType upperRight;
    Dune::array< unsigned int, dim > numElements;
    for (unsigned int d = 0; d < dim; ++d) {
      assert(lowerLefts[d] < upperRights[d]
             && "Given 'upperRight' hast to be elementwise larger than given 'lowerLeft'!");
      lowerLeft[d] = lowerLefts[d];
      upperRight[d] = upperRights[d];
      assert(tmpNumElements[d] > 0 && "Given 'numElements' has to be elementwise positive!");
      numElements[d] = tmpNumElements[d];
    }
    return new ThisType(lowerLeft, upperRight, numElements);
  } // static ThisType createFromParamTree(const Dune::ParameterTree& paramTree, const std::string subName = id())

  //! access to shared ptr
  virtual Dune::shared_ptr< GridType > grid()
  {
    return grid_;
  }

  virtual const Dune::shared_ptr< const GridType > grid() const
  {
    return grid_;
  }

  const CoordinateType& lowerLeft() const
  {
    return lowerLeft_;
  }

  const CoordinateType& upperRight() const
  {
    return upperRight_;
  }

private:
  void buildGrid(const Dune::array< unsigned int, dim >& numElements)
  {
    dune_static_assert(variant >= 1 && variant <= 2, "only variant 1 and 2 are valid");
    switch (variant) {
      case 1:
        grid_ = Dune::StructuredGridFactory< GridType >::createCubeGrid(lowerLeft_, upperRight_, numElements);
        break;
      case 2:
    default:
        grid_ = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lowerLeft_, upperRight_, numElements);
        break;
    }
  } // void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight)

  CoordinateType lowerLeft_;
  CoordinateType upperRight_;
  Dune::shared_ptr< GridType > grid_;
}; // class GenericCube

template< typename GridType >
struct ElementVariant {
  static const int id = 2;
};

template< int dim >
struct ElementVariant< Dune::YaspGrid< dim > > {
  static const int id = 1;
};

template< int dim >
struct ElementVariant< Dune::SGrid< dim, dim > > {
  static const int id = 1;
};

#if HAVE_ALUGRID
template< int dim >
struct ElementVariant< Dune::ALUCubeGrid< dim, dim > > {
  static const int id = 1;
};
#endif // HAVE_ALUGRID

} // namespace Provider
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // HAVE_DUNE_GRID

#endif // DUNE_STUFF_GRID_PROVIDER_CUBE_HH
<commit_msg>[grid.provider.cube] renamed GenericCube -> Cube<commit_after>#ifndef DUNE_STUFF_GRID_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRID_PROVIDER_CUBE_HH

#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include <config.h>
#endif // ifdef HAVE_CMAKE_CONFIG

#if HAVE_DUNE_GRID

#include <sstream>
#include <type_traits>
#include <boost/assign/list_of.hpp>

#include <dune/common/parametertree.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>
#include <dune/common/static_assert.hh>

#include <dune/grid/utility/structuredgridfactory.hh>
#include <dune/grid/yaspgrid.hh>
#ifdef HAVE_ALUGRID
  #include <dune/grid/alugrid.hh>
#endif
#include <dune/grid/sgrid.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/color.hh>

#include "interface.hh"

namespace Dune {
namespace Stuff {
namespace Grid {
namespace Provider {

template< typename GridType >
struct ElementVariant;

/**
 *  \brief  Creates a grid of a cube in various dimensions.
 *
 *          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
 *          dimensions. Tested with
 *

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c SGRID, \c variant 1, dim = 1, 2, 3,
 *
 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,
 *
 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and
 *
 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

 *  \tparam GridImp
 *          Type of the underlying grid.
 *  \tparam variant
 *          Type of the codim 0 elements:
 *

\c 1: cubes
 *
2: simplices

 **/
template< typename GridImp, int variant = ElementVariant<GridImp>::id>
class Cube
  : public Interface< GridImp >
{
public:
  //! Type of the provided grid.
  typedef GridImp GridType;

  typedef Interface< GridType > BaseType;

  typedef Cube< GridType, variant > ThisType;

private:
  typedef typename GridType::LeafGridView GridViewType;

public:
  static const unsigned int dim = BaseType::dim;

  //! Type of the grids coordinates.
  typedef typename GridType::ctype ctype;
  typedef Dune::FieldVector< ctype, dim > CoordinateType;

  //! Unique identifier: \c stuff.grid.provider.cube
  static const std::string id()
  {
    return BaseType::id() + ".cube";
  }

  /**
   *  \brief      Creates a cube.
   *  \param[in]  _lowerLeft
   *              A double that is used as a lower left corner in each dimension.
   *  \param[in]  _upperRight
   *              A double that is used as a upper right corner in each dimension.
   *  \param[in]  numElements (optional)
   *              number of elements.
   **/
  Cube(const double _lowerLeft = 0.0, const double _upperRight = 1.0, const unsigned int numElements = 1u)
    : lowerLeft_(_lowerLeft)
    , upperRight_(_upperRight)
  {
    Dune::array< unsigned int, dim > tmpNumElements;
    std::fill(tmpNumElements.begin(), tmpNumElements.end(), numElements);
    buildGrid(tmpNumElements);
  }

  /**
   *  \brief      Creates a cube.
   *  \param[in]  _lowerLeft
   *              A vector that is used as a lower left corner.
   *  \param[in]  _upperRight
   *              A vector that is used as a upper right corner.
   *  \param[in]  numElements (optional)
   *              number of elements.
   **/
  Cube(const CoordinateType& _lowerLeft, const CoordinateType& _upperRight, const unsigned int numElements = 1u)
    : lowerLeft_(_lowerLeft)
    , upperRight_(_upperRight)
  {
    Dune::array< unsigned int, dim > tmpNumElements;
    std::fill(tmpNumElements.begin(), tmpNumElements.end(), numElements);
    buildGrid(tmpNumElements);
  }

  /**
    \brief      Creates a cube. This signature allows to prescribe anisotopic refinement
    \param[in]  _lowerLeft
                A double that is used as a lower left corner in each dimension.
    \param[in]  _upperRight
                A double that is used as a upper right corner in each dimension.
    \param[in]  numElements
                number of elements in each dimension.
                can contain 0 to dim elements (missing dimension are initialized to 1)
    \tparam ContainerType some sequence type that functions with std::begin/end
    **/
  template< class ContainerType  >
  Cube(const CoordinateType& _lowerLeft, const CoordinateType& _upperRight,
              const ContainerType numElements
                = boost::assign::list_of< typename ContainerType::value_type>().repeat(dim,
                                                                                typename ContainerType::value_type(1u)))
    : lowerLeft_(_lowerLeft),
      upperRight_(_upperRight)
  {
    Dune::array< unsigned int, dim > tmpNumElements;
    static_assert(std::is_unsigned< typename ContainerType::value_type >::value
                  && std::is_integral< typename ContainerType::value_type >::value,
                  "only unsigned integral number of elements per dimension allowed");
    //base init in case input is shorter
    std::fill(tmpNumElements.begin(), tmpNumElements.end(), 1u);
    std::copy(numElements.begin(), numElements.end(), tmpNumElements.begin());
    buildGrid(tmpNumElements);
  }

  static Dune::ParameterTree createSampleDescription(const std::string subName = "")
  {
    Dune::ParameterTree description;
    description["lowerLeft"] = "[0.0; 0.0; 0.0]";
    description["upperRight"] = "[1.0; 1.0; 1.0]";
    description["numElements"] = "[2; 2; 2]";
    if (subName.empty())
      return description;
    else {
      Dune::Stuff::Common::ExtendedParameterTree extendedDescription;
      extendedDescription.add(description, subName);
      return extendedDescription;
    }
  }

  /**
   *  \brief      Creates a cube.
   *  \param[in]  paramTree
   *              A Dune::ParameterTree containing
   *

 the following keys directly or
   *
 a subtree named Cube::id, containing the following keys. If a subtree is present, it is always selected. Also it is solely selceted, so that all keys in the supertree are ignored.

   *              The actual keys are:
   *

 \c lowerLeft: \a double or a vector that is used as lower left corners.
   *
 \c upperRight: \a double or a vector that is used as upper right corners.
   *
 \c numElements: \a int or vector to denote the number of elements.
   *

   **/
  static ThisType* createFromDescription(const Dune::ParameterTree& paramTree, const std::string subName = id())
  {
    // get correct paramTree
    Dune::Stuff::Common::ExtendedParameterTree extendedParamTree;
    if (paramTree.hasSub(subName))
      extendedParamTree = paramTree.sub(subName);
    else
      extendedParamTree = paramTree;
    // get lower left
    std::vector< ctype > lowerLefts;
    if (extendedParamTree.hasVector("lowerLeft")) {
      lowerLefts = extendedParamTree.getVector("lowerLeft", ctype(0), dim);
      assert(lowerLefts.size() >= dim && "Given vector too short!");
    } else if (extendedParamTree.hasKey("lowerLeft")) {
        const ctype lowerLeft = extendedParamTree.get("lowerLeft", ctype(0));
        lowerLefts = std::vector< ctype >(dim, lowerLeft);
    } else {
      std::cout << "\n" << Dune::Stuff::Common::colorString("WARNING in " + id() + ":")
                << " neither vector nor key 'lowerLeft' given, defaulting to 0.0!" << std::flush;
      lowerLefts = std::vector< ctype >(dim, ctype(0));
    }
    // get upper right
    std::vector< ctype > upperRights;
    if (extendedParamTree.hasVector("upperRight")) {
      upperRights = extendedParamTree.getVector("upperRight", ctype(1), dim);
      assert(upperRights.size() >= dim && "Given vector too short!");
    } else if (extendedParamTree.hasKey("upperRight")) {
        const ctype upperRight = extendedParamTree.get("upperRight", ctype(1));
        upperRights = std::vector< ctype >(dim, upperRight);
    } else {
      std::cout << "\n" << Dune::Stuff::Common::colorString("WARNING in " + id() + ":")
                << " neither vector nor key 'upperRight' given, defaulting to 1.0!" << std::flush;
      upperRights = std::vector< ctype >(dim, ctype(1));
    }
    // get number of elements
    std::vector< unsigned int > tmpNumElements;
    if (extendedParamTree.hasVector("numElements")) {
      tmpNumElements = extendedParamTree.getVector("numElements", 1u, dim);
      assert(tmpNumElements.size() >= dim && "Given vector too short!");
    } else if (extendedParamTree.hasKey("numElements")) {
        const unsigned int numElement = extendedParamTree.get("numElements", 1u);
        tmpNumElements = std::vector< unsigned int >(dim, numElement);
    } else {
      std::cout << "\n" << Dune::Stuff::Common::colorString("WARNING in " + id() + ":")
                << " neither vector nor key 'numElements' given, defaulting to 1!" << std::flush;
      tmpNumElements = std::vector< unsigned int >(dim, 1u);
    }
    // check and save
    CoordinateType lowerLeft;
    CoordinateType upperRight;
    Dune::array< unsigned int, dim > numElements;
    for (unsigned int d = 0; d < dim; ++d) {
      assert(lowerLefts[d] < upperRights[d]
             && "Given 'upperRight' hast to be elementwise larger than given 'lowerLeft'!");
      lowerLeft[d] = lowerLefts[d];
      upperRight[d] = upperRights[d];
      assert(tmpNumElements[d] > 0 && "Given 'numElements' has to be elementwise positive!");
      numElements[d] = tmpNumElements[d];
    }
    return new ThisType(lowerLeft, upperRight, numElements);
  } // static ThisType createFromParamTree(const Dune::ParameterTree& paramTree, const std::string subName = id())

  //! access to shared ptr
  virtual Dune::shared_ptr< GridType > grid()
  {
    return grid_;
  }

  virtual const Dune::shared_ptr< const GridType > grid() const
  {
    return grid_;
  }

  const CoordinateType& lowerLeft() const
  {
    return lowerLeft_;
  }

  const CoordinateType& upperRight() const
  {
    return upperRight_;
  }

private:
  void buildGrid(const Dune::array< unsigned int, dim >& numElements)
  {
    dune_static_assert(variant >= 1 && variant <= 2, "only variant 1 and 2 are valid");
    switch (variant) {
      case 1:
        grid_ = Dune::StructuredGridFactory< GridType >::createCubeGrid(lowerLeft_, upperRight_, numElements);
        break;
      case 2:
    default:
        grid_ = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lowerLeft_, upperRight_, numElements);
        break;
    }
  } // void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight)

  CoordinateType lowerLeft_;
  CoordinateType upperRight_;
  Dune::shared_ptr< GridType > grid_;
}; // class Cube

template< typename GridType >
struct ElementVariant {
  static const int id = 2;
};

template< int dim >
struct ElementVariant< Dune::YaspGrid< dim > > {
  static const int id = 1;
};

template< int dim >
struct ElementVariant< Dune::SGrid< dim, dim > > {
  static const int id = 1;
};

#if HAVE_ALUGRID
template< int dim >
struct ElementVariant< Dune::ALUCubeGrid< dim, dim > > {
  static const int id = 1;
};
#endif // HAVE_ALUGRID

} // namespace Provider
} // namespace Grid
} // namespace Stuff
} // namespace Dune

#endif // HAVE_DUNE_GRID

#endif // DUNE_STUFF_GRID_PROVIDER_CUBE_HH
<|endoftext|>


<commit_before>#ifndef INCLUDE_UNITTESTS_MIXED_DECIMATER_HH
#define INCLUDE_UNITTESTS_MIXED_DECIMATER_HH

#include <gtest/gtest.h>
#include <Unittests/unittests_common.hh>
#include <OpenMesh/Tools/Decimater/MixedDecimaterT.hh>
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>
#include <OpenMesh/Tools/Decimater/ModNormalFlippingT.hh>

class OpenMeshMixedDecimater : public OpenMeshBase {

    protected:

        // This function is called before each test is run
        virtual void SetUp() {

            // Do some initial stuff with the member data here...
        }

        // This function is called after all tests are through
        virtual void TearDown() {

            // Do some final stuff with the member data here...
        }

    // Member already defined in OpenMeshBase
    //Mesh mesh_;
};

/*
 * ====================================================================
 * Define tests below
 * ====================================================================
 */

/*
 */
TEST_F(OpenMeshMixedDecimater, DecimateMesh80PercentMc) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::MixedDecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
  typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to(5000,0.8f);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshMixedDecimater, DecimateMeshToFaceVerticesLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::MixedDecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
  typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(5000, 8000, 0.7f);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshMixedDecimater, DecimateMeshToFaceFaceLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::MixedDecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
  typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(4500, 9996, 0.7f);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

#endif // INCLUDE GUARD
<commit_msg>Fixed some conversions in unittests<commit_after>#ifndef INCLUDE_UNITTESTS_MIXED_DECIMATER_HH
#define INCLUDE_UNITTESTS_MIXED_DECIMATER_HH

#include <gtest/gtest.h>
#include <Unittests/unittests_common.hh>
#include <OpenMesh/Tools/Decimater/MixedDecimaterT.hh>
#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>
#include <OpenMesh/Tools/Decimater/ModNormalFlippingT.hh>

class OpenMeshMixedDecimater : public OpenMeshBase {

    protected:

        // This function is called before each test is run
        virtual void SetUp() {

            // Do some initial stuff with the member data here...
        }

        // This function is called after all tests are through
        virtual void TearDown() {

            // Do some final stuff with the member data here...
        }

    // Member already defined in OpenMeshBase
    //Mesh mesh_;
};

/*
 * ====================================================================
 * Define tests below
 * ====================================================================
 */

/*
 */
TEST_F(OpenMeshMixedDecimater, DecimateMesh80PercentMc) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::MixedDecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
  typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to(5000,0.8f);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshMixedDecimater, DecimateMeshToFaceVerticesLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::MixedDecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
  typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(5000, 8000, 0.7f);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

TEST_F(OpenMeshMixedDecimater, DecimateMeshToFaceFaceLimit) {

  bool ok = OpenMesh::IO::read_mesh(mesh_, "cube1.off");

  ASSERT_TRUE(ok);

  typedef OpenMesh::Decimater::MixedDecimaterT< Mesh >  Decimater;
  typedef OpenMesh::Decimater::ModQuadricT< Mesh >::Handle HModQuadric;
  typedef OpenMesh::Decimater::ModNormalFlippingT< Mesh >::Handle HModNormal;

  Decimater decimaterDBG(mesh_);
  HModQuadric hModQuadricDBG;
  decimaterDBG.add( hModQuadricDBG );
  decimaterDBG.initialize();
  size_t removedVertices = 0;
  removedVertices = decimaterDBG.decimate_to_faces(4500, 9996, 0.7f);
                    decimaterDBG.mesh().garbage_collection();

  EXPECT_EQ(2526u, removedVertices) << "The number of remove vertices is not correct!";
  EXPECT_EQ(5000u, mesh_.n_vertices()) << "The number of vertices after decimation is not correct!";
  EXPECT_EQ(14994u, mesh_.n_edges()) << "The number of edges after decimation is not correct!";
  EXPECT_EQ(9996u, mesh_.n_faces()) << "The number of faces after decimation is not correct!";
}

#endif // INCLUDE GUARD
<|endoftext|>


<commit_before>#include "engine.hpp"

#include <ctime>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <vector>
#include <utility>

#include "uv.h"

#include "scripting.hpp"
#include "types.hpp"
#include "utils.hpp"

using std::string;
using std::flush;
using std::cout;
using std::endl;
using std::vector;
using std::pair;
using std::make_pair;

namespace fr {

/// The library for the current render.
static Library* lib = nullptr;

/// The maximum number of uninteresting stats intervals before we declare the
/// rendering complete.
static uint32_t max_intervals = 0;

/// The maximum number of jobs "in flight" at any given time.
static uint32_t max_jobs = 0;

/// The number of jobs currently available for running on libuv's thread pool.
static uint32_t active_jobs = 0;

/// The timer for reporting stats during rendering.
static uv_timer_t stats_timer;

/// The scene file we're rendering.
static string scene;

/// Render stats for this worker.
static RenderStats stats;

/// Timers for measuring total time.
static time_t load_start;
static time_t load_stop;
static time_t build_start;
static time_t build_stop;
static time_t render_start;
static time_t render_stop;

uint32_t SyncMesh(Mesh* mesh);
void ScheduleJob();
void StopRender();

void OnStatsTimeout(uv_timer_t* timer, int status);
void OnWork(uv_work_t* req);
void AfterWork(uv_work_t* req);

void EngineInit(const string& config_file, const string& scene_file,
 uint32_t intervals, uint32_t jobs) {
    lib = new Library;

    scene = scene_file;
    max_intervals = intervals;
    max_jobs = jobs;

    // Randomize the world.
    srand(time(0));

    // Parse the config file.
    ConfigScript config_script;
    TOUTLN("Loading config from " << config_file << ".");
    if (!config_script.Parse(config_file, lib)) {
        TERRLN("Can't continue with bad config.");
        exit(EXIT_FAILURE);
    }
    TOUTLN("Config loaded.");

    load_start = time(nullptr);

    // Parse the scene.
    SceneScript scene_script(SyncMesh);
    TOUTLN("Loading scene from " << scene << ".");
    if (!scene_script.Parse(scene, lib)) {
        TERRLN("Can't continue with bad scene.");
        exit(EXIT_FAILURE);
    }

    load_stop = time(nullptr);

    TOUT("Building BVH" << flush);
    build_start = time(nullptr);

    // Build triangle BVHs for each mesh.
    vector<pair<uint32_t, BoundingBox>> mesh_bounds;
    lib->ForEachMesh([&mesh_bounds](uint32_t id, Mesh* mesh) {
        mesh->bvh = new BVH(mesh);
        mesh_bounds.emplace_back(make_pair(id, mesh->bvh->Extents()));
        cout << "." << flush;
    });

    // Build the mesh BVH from the mesh extents.
    BVH* mbvh = new BVH(mesh_bounds);
    lib->StoreMBVH(mbvh);
    cout << "." << endl;

    build_stop = time(nullptr);
    TOUTLN("Local BVH ready.");

    // Set the camera range.
    Config* config = lib->LookupConfig();
    assert(config != nullptr);
    Camera* camera = lib->LookupCamera();
    assert(camera != nullptr);
    camera->SetRange(0, config->width);

    // Start the stats timer.
    int result = 0;
    result = uv_timer_init(uv_default_loop(), &stats_timer);
    CheckUVResult(result, "timer_init");
    result = uv_timer_start(&stats_timer, OnStatsTimeout, 1000, 1000);
    CheckUVResult(result, "timer_start");

    // Queue up some jobs.
    for (uint32_t i = 0; i < max_jobs; i++) {
        ScheduleJob();
    }

    render_start = time(nullptr);
}

void EngineRun() {
    uv_run(uv_default_loop());
}

uint32_t SyncMesh(Mesh* mesh) {
    uint32_t id = 0;
    if (mesh != nullptr) {
        // Store the mesh in the library and get back its ID.
        id = lib->NextMeshID();
        mesh->id = id;
        lib->StoreMesh(id, mesh);
    }

    return id;
}

void OnStatsTimeout(uv_timer_t* timer, int status) {
    assert(timer == &stats_timer);
    assert(status == 0);

    Camera* cam = lib->LookupCamera();
    assert(cam != nullptr);
    stats.primary_progress = cam->Progress();

    stats.Reset();

    // TODO
    TOUTLN("Stats!");
}

void ScheduleJob() {
    int result = 0;

    // Don't schedule anything if we're maxed out.
    if (active_jobs >= max_jobs) {
        return;
    }

    // Generate a new primary ray.
    Camera* cam = lib->LookupCamera();
    assert(cam != nullptr);
    FatRay* ray = new FatRay;
    if (cam->GeneratePrimary(ray)) {
        // Queue it for work.
        uv_work_t* req = reinterpret_cast<uv_work_t*>(malloc(sizeof(uv_work_t)));
        req->data = ray;
        result = uv_queue_work(uv_default_loop(), req, OnWork, AfterWork);
        CheckUVResult(result, "queue_work");
        active_jobs++;
    }
}

void OnWork(uv_work_t* req) {
    // !!! WARNING !!!
    // Everything this function does and calls must be thread-safe. This
    // function will NOT run in the main thread, it runs on the thread pool.

    // Pull the ray out of the data baton.
    FatRay *ray = reinterpret_cast<FatRay*>(req->data);

    // Allocate results of this work.
    WorkResults* results = new WorkResults;

    //// Dispatch the ray.
    //ProcessRay(ray, results);
    delete ray; // TODO

    //// Pass the work results back through the data baton.
    req->data = results;
}

void AfterWork(uv_work_t* req) {
    assert(req != nullptr);
    assert(req->data != nullptr);

    //// Pull the work result out of the data baton.
    WorkResults* results = reinterpret_cast<WorkResults*>(req->data);

    //// Do buffer operations.
    //Image* image = lib->LookupImage();
    //assert(image != nullptr);
    //for (auto& op : results->ops) {
    //    switch (op.kind) {
    //        case BufferOp::Kind::WRITE:
    //            image->Write(op.buffer, op.x, op.y, op.value);
    //            break;

    //        case BufferOp::Kind::ACCUMULATE:
    //            image->Accumulate(op.buffer, op.x, op.y, op.value);
    //            break;
    //    }
    //}
    //
    //// Forward rays and kill them off.
    //for (auto& forward : results->forwards) {
    //    if (forward.node == nullptr) {
    //        // We didn't know where to send it, so queue it for processing.
    //        rayq->Push(forward.ray);
    //    } else {
    //        // Send it and kill the local copy.
    //        forward.ray->workers_touched++;
    //        forward.node->SendRay(forward.ray);
    //        delete forward.ray;
    //    }
    //}

    //// Merge render stats.
    //stats.intersects_produced += results->intersects_produced;
    //stats.illuminates_produced += results->illuminates_produced;
    //stats.lights_produced += results->lights_produced;
    //stats.intersects_killed += results->intersects_killed;
    //stats.illuminates_killed += results->illuminates_killed;
    //stats.lights_killed += results->lights_killed;
    //for (const auto& kv : results->workers_touched) {
    //    trav_stats.workers_touched[kv.first] += kv.second;
    //}

    delete results;
    free(req);

    // This job is done. Schedule more work.
    active_jobs--;
    if (active_jobs == 0) {
        StopRender();
    } else {
        ScheduleJob();
    }
}

void StopRender() {
    int result = 0;

    render_stop = time(nullptr);

    // Stop the stats timer.
    result = uv_timer_stop(&stats_timer);
    CheckUVResult(result, "timer_stop");
    uv_close(reinterpret_cast<uv_handle_t*>(&stats_timer), nullptr);

    // Dump out timers.
    TOUTLN("Time spent loading: " << (load_stop - load_start) << " seconds.");
    TOUTLN("Time spent building: " << (build_stop - build_start) << " seconds.");
    TOUTLN("Time spent rendering: " << (render_stop - render_start) << " seconds.");
}

} // namespace fr
<commit_msg>Baseline renders indirect with no tracers.<commit_after>#include "engine.hpp"

#include <ctime>
#include <cstdlib>
#include <iostream>
#include <cassert>
#include <vector>
#include <utility>

#include "uv.h"

#include "scripting.hpp"
#include "types.hpp"
#include "utils.hpp"

using std::string;
using std::flush;
using std::cout;
using std::endl;
using std::vector;
using std::pair;
using std::make_pair;
using glm::vec3;

namespace fr {

/// The library for the current render.
static Library* lib = nullptr;

/// The maximum number of uninteresting stats intervals before we declare the
/// rendering complete.
static uint32_t max_intervals = 0;

/// The maximum number of jobs "in flight" at any given time.
static uint32_t max_jobs = 0;

/// The number of jobs currently available for running on libuv's thread pool.
static uint32_t active_jobs = 0;

/// The timer for reporting stats during rendering.
static uv_timer_t stats_timer;

/// The scene file we're rendering.
static string scene;

/// Render stats for this worker.
static RenderStats stats;

/// Timers for measuring total time.
static time_t load_start;
static time_t load_stop;
static time_t build_start;
static time_t build_stop;
static time_t render_start;
static time_t render_stop;

uint32_t SyncMesh(Mesh* mesh);
void ScheduleJob();
void StopRender();
void ProcessRay(FatRay* ray, WorkResults* results);
void ProcessIntersect(FatRay* ray, WorkResults* results);
void ProcessLight(FatRay* ray, WorkResults* results);
void IlluminateIntersection(FatRay* ray, WorkResults* work);

void OnStatsTimeout(uv_timer_t* timer, int status);
void OnWork(uv_work_t* req);
void AfterWork(uv_work_t* req);

void EngineInit(const string& config_file, const string& scene_file,
 uint32_t intervals, uint32_t jobs) {
    lib = new Library;

    scene = scene_file;
    max_intervals = intervals;
    max_jobs = jobs;

    // Randomize the world.
    srand(time(0));

    // Parse the config file.
    ConfigScript config_script;
    TOUTLN("Loading config from " << config_file << ".");
    if (!config_script.Parse(config_file, lib)) {
        TERRLN("Can't continue with bad config.");
        exit(EXIT_FAILURE);
    }
    TOUTLN("Config loaded.");

    Config* config = lib->LookupConfig();
    assert(config != nullptr);

    // Create the image with all the requested buffers.
    Image* image = new Image(config->width, config->height);
    for (const auto& buffer : config->buffers) {
        image->AddBuffer(buffer);
    }
    lib->StoreImage(image);

    load_start = time(nullptr);

    // Parse the scene.
    SceneScript scene_script(SyncMesh);
    TOUTLN("Loading scene from " << scene << ".");
    if (!scene_script.Parse(scene, lib)) {
        TERRLN("Can't continue with bad scene.");
        exit(EXIT_FAILURE);
    }

    load_stop = time(nullptr);

    TOUT("Building BVH" << flush);
    build_start = time(nullptr);

    // Build triangle BVHs for each mesh.
    vector<pair<uint32_t, BoundingBox>> mesh_bounds;
    lib->ForEachMesh([&mesh_bounds](uint32_t id, Mesh* mesh) {
        mesh->bvh = new BVH(mesh);
        mesh_bounds.emplace_back(make_pair(id, mesh->bvh->Extents()));
        cout << "." << flush;
    });

    // Build the mesh BVH from the mesh extents.
    BVH* mbvh = new BVH(mesh_bounds);
    lib->StoreMBVH(mbvh);
    cout << "." << endl;

    build_stop = time(nullptr);
    TOUTLN("Local BVH ready.");

    // Set the camera range.
    Camera* camera = lib->LookupCamera();
    assert(camera != nullptr);
    camera->SetRange(0, config->width);

    // Start the stats timer.
    int result = 0;
    result = uv_timer_init(uv_default_loop(), &stats_timer);
    CheckUVResult(result, "timer_init");
    result = uv_timer_start(&stats_timer, OnStatsTimeout, 1000, 1000);
    CheckUVResult(result, "timer_start");

    // Queue up some jobs.
    for (uint32_t i = 0; i < max_jobs; i++) {
        ScheduleJob();
    }

    render_start = time(nullptr);
}

void EngineRun() {
    uv_run(uv_default_loop());
}

uint32_t SyncMesh(Mesh* mesh) {
    uint32_t id = 0;
    if (mesh != nullptr) {
        // Store the mesh in the library and get back its ID.
        id = lib->NextMeshID();
        mesh->id = id;
        lib->StoreMesh(id, mesh);

        uint32_t mat_id = mesh->material;
        Material* mat = lib->LookupMaterial(mat_id);
        assert(mat != nullptr);

        uint32_t shader_id = mat->shader;
        Shader* shader = lib->LookupShader(shader_id);
        assert(shader != nullptr);

        // Prep the shader if we haven't already.
        if (shader->script == nullptr) {
            shader->script = new ShaderScript(shader->code, lib);
        }

        // Prep any procedural textures for execution.
        for (const auto& kv : mat->textures) {
            uint32_t tex_id = kv.second;
            Texture* tex = lib->LookupTexture(tex_id);
            assert(mat != nullptr);
            if (tex->kind == Texture::Kind::PROCEDURAL && tex->script == nullptr) {
                tex->script = new TextureScript(tex->code);
            }
        }
    }

    return id;
}

void OnStatsTimeout(uv_timer_t* timer, int status) {
    assert(timer == &stats_timer);
    assert(status == 0);

    Camera* cam = lib->LookupCamera();
    assert(cam != nullptr);
    stats.primary_progress = cam->Progress();

    stats.Reset();

    // TODO
    TOUTLN("Stats!");
}

void ScheduleJob() {
    int result = 0;

    // Don't schedule anything if we're maxed out.
    if (active_jobs >= max_jobs) {
        return;
    }

    // Generate a new primary ray.
    Camera* cam = lib->LookupCamera();
    assert(cam != nullptr);
    FatRay* ray = new FatRay;
    if (cam->GeneratePrimary(ray)) {
        // Queue it for work.
        uv_work_t* req = reinterpret_cast<uv_work_t*>(malloc(sizeof(uv_work_t)));
        req->data = ray;
        result = uv_queue_work(uv_default_loop(), req, OnWork, AfterWork);
        CheckUVResult(result, "queue_work");
        active_jobs++;
    }
}

void OnWork(uv_work_t* req) {
    // !!! WARNING !!!
    // Everything this function does and calls must be thread-safe. This
    // function will NOT run in the main thread, it runs on the thread pool.

    // Pull the ray out of the data baton.
    FatRay *ray = reinterpret_cast<FatRay*>(req->data);

    // Allocate results of this work.
    WorkResults* results = new WorkResults;

    //// Dispatch the ray.
    ProcessRay(ray, results);

    //// Pass the work results back through the data baton.
    req->data = results;
}

void AfterWork(uv_work_t* req) {
    assert(req != nullptr);
    assert(req->data != nullptr);

    // Pull the work result out of the data baton.
    WorkResults* results = reinterpret_cast<WorkResults*>(req->data);

    //// Do buffer operations.
    Image* image = lib->LookupImage();
    assert(image != nullptr);
    for (auto& op : results->ops) {
        switch (op.kind) {
            case BufferOp::Kind::WRITE:
                image->Write(op.buffer, op.x, op.y, op.value);
                break;

            case BufferOp::Kind::ACCUMULATE:
                image->Accumulate(op.buffer, op.x, op.y, op.value);
                break;
        }
    }

    //// Forward rays and kill them off.
    //for (auto& forward : results->forwards) {
    //    if (forward.node == nullptr) {
    //        // We didn't know where to send it, so queue it for processing.
    //        rayq->Push(forward.ray);
    //    } else {
    //        // Send it and kill the local copy.
    //        forward.ray->workers_touched++;
    //        forward.node->SendRay(forward.ray);
    //        delete forward.ray;
    //    }
    //}

    //// Merge render stats.
    stats.intersects_produced += results->intersects_produced;
    stats.illuminates_produced += results->illuminates_produced;
    stats.lights_produced += results->lights_produced;
    stats.intersects_killed += results->intersects_killed;
    stats.illuminates_killed += results->illuminates_killed;
    stats.lights_killed += results->lights_killed;

    delete results;
    free(req);

    // This job is done. Schedule more work.
    active_jobs--;
    if (active_jobs == 0) {
        StopRender();
    } else {
        ScheduleJob();
    }
}

void StopRender() {
    int result = 0;

    Config* config = lib->LookupConfig();
    assert(config != nullptr);

    Image* final = lib->LookupImage();
    assert(final != nullptr);

    render_stop = time(nullptr);

    // Stop the stats timer.
    result = uv_timer_stop(&stats_timer);
    CheckUVResult(result, "timer_stop");
    uv_close(reinterpret_cast<uv_handle_t*>(&stats_timer), nullptr);

    // Write out the final image.
    final->ToEXRFile(config->name + ".exr");
    TOUTLN("Wrote " << config->name << ".exr.");

    // Dump out timers.
    TOUTLN("Time spent loading: " << (load_stop - load_start) << " seconds.");
    TOUTLN("Time spent building: " << (build_stop - build_start) << " seconds.");
    TOUTLN("Time spent rendering: " << (render_stop - render_start) << " seconds.");
}

void ProcessRay(FatRay* ray, WorkResults* results) {
    // !!! WARNING !!!
    // Everything this function does and calls must be thread-safe. This
    // function will NOT run in the main thread, it runs on the thread pool.

    switch (ray->kind) {
        case FatRay::Kind::INTERSECT:
            ProcessIntersect(ray, results);
            break;

        case FatRay::Kind::LIGHT:
            ProcessLight(ray, results);
            break;

        default:
            TERRLN("Unknown ray kind " << ray->kind << ".");
            break;
    }
}

void ProcessIntersect(FatRay* ray, WorkResults* results) {
    // !!! WARNING !!!
    // Everything this function does and calls must be thread-safe. This
    // function will NOT run in the main thread, it runs on the thread pool.

    // Test geometry for intersection.
    ray->traversal.hit = lib->Intersect(ray, 1);

    // Did it hit anything?
    if (ray->hit.worker > 0) {
        // Yes it did. Illuminate the intersection and kill the ray.
        IlluminateIntersection(ray, results);
    }

    // Kill the ray.
    delete ray;
    results->intersects_killed++;
    return;
}

void ProcessLight(FatRay* ray, WorkResults* results) {
    // !!! WARNING !!!
    // Everything this function does and calls must be thread-safe. This
    // function will NOT run in the main thread, it runs on the thread pool.

    // TODO
}

void IlluminateIntersection(FatRay* ray, WorkResults* results) {
    // !!! WARNING !!!
    // Everything this function does and calls must be thread-safe. This
    // function will NOT run in the main thread, it runs on the thread pool.

    // Where did we hit?
    vec3 hit = ray->EvaluateAt(ray->hit.t);

    // Find the shader and run the indirect() function.
    Mesh* mesh = lib->LookupMesh(ray->hit.mesh);
    assert(mesh != nullptr);

    Material* mat = lib->LookupMaterial(mesh->material);
    assert(mat != nullptr);

    Shader* shader = lib->LookupShader(mat->shader);
    assert(shader != nullptr);
    assert(shader->script != nullptr);

    shader->script->Indirect(ray, hit, results);

    // TODO: process traced rays in results immediately (recursive)

    // TODO: light this intersection by generating light rays and processing
    // them immediately (recursive)
}

} // namespace fr
<|endoftext|>


<commit_before>#ifndef DUNE_STUFF_GRID_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRID_PROVIDER_CUBE_HH

// dune-common
#include <dune/common/parametertree.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

// dune-grid
#include <dune/grid/utility/structuredgridfactory.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/alugrid.hh>
#include <dune/grid/sgrid.hh>
#include <dune/grid/common/mcmgmapper.hh>
#include <dune/grid/io/file/vtk/vtkwriter.hh>

namespace Dune
{

namespace Stuff
{

namespace Grid
{

namespace Provider
{

/**
  \brief  Creates a grid of a cube in various dimensions.

          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
          dimensions. Tested with

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,

 \c SGRID, \c variant 1, dim = 1, 2, 3,

 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,

 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and

 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

  \tparam GridImp
          Type of the underlying grid.
  \tparam variant
          Type of the codim 0 elements:

\c 1: cubes

2: simplices

  **/
template< typename GridImp, int variant >
class GenericCube
{
public:
  //! Type of the provided grid.
  typedef GridImp GridType;

  //! Dimension of the provided grid.
  static const int dim = GridType::dimension;

  //! Type of the grids coordinates.
  typedef Dune::FieldVector< typename GridType::ctype, dim > CoordinateType;

  //! Unique identifier: \c stuff.grid.provider.cube
  static const std::string id;

  /**
    \brief      Creates a cube.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys.

                The actual keys are:

 \c lowerLeft: \a double that is used as a lower left corner in each dimension.

 \c upperRight: \a double that is used as a upper right corner in each dimension.

    **/
  GenericCube(const Dune::ParameterTree& paramTree)
    : lowerLeft_(0.0),
      upperRight_(0.0)
  {
    // check for parameters
    const double lowerLeft = paramTree.get("lowerLeft", 0.0);
    const double upperRight = paramTree.get("upperRight", 1.0);
    assert(lowerLeft < upperRight);
    const int level = paramTree.get("level", 1);
    lowerLeft_ = lowerLeft;
    upperRight_ = upperRight;
    buildGrid(lowerLeft_, upperRight_, level);
  } // Cube(const Dune::ParameterTree& paramTree)

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A vector that is used as a lower left corner.
    \param[in]  upperRight
                A vector that is used as a upper right corner.
    **/
  GenericCube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : lowerLeft_(lowerLeft),
      upperRight_(upperRight)
  {
    buildGrid(lowerLeft_, upperRight_, level);
  }

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A double that is used as a lower left corner in each dimension.
    \param[in]  upperRight
                A double that is used as a upper right corner in each dimension.
    **/
  GenericCube(const double lowerLeft, const double upperRight, const int level = 1)
    : lowerLeft_(lowerLeft),
      upperRight_(upperRight)
  {
    buildGrid(lowerLeft_, upperRight_, level);
  }

  /**
    \brief  Provides access to the created grid.
    \return Reference to the grid.
    **/
  GridType& grid()
  {
    return *grid_;
  }

  const GridType& grid() const
  {
    return *grid_;
  }

private:
  template< int dim >
  struct P0Layout
  {
    bool contains(Dune::GeometryType& geometry)
    {
      if (geometry.dim() == dim)
        return true;
      return false;
    }
  }; // layout class for codim 0 mapper

  /**
    \brief      Visualizes the grid using Dune::VTKWriter.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys, or

 a subtree named Cube::id + \c .visualize, containing the following keys.

                The actual keys are:

 \c grid: if specified, filename of the vtk file in which the grid which can be obtained via
                  grid() is visualized (\a if \a not \a specified: \a no \a visualization).

 \c mdGrid: if specified, filename of the vtk file in which the multidomain grid which can be
                  obtained via mdGrid() is visualized (\a if \a not \a specified: \a no \a visualization).

    **/
public:
  void visualize(Dune::ParameterTree& paramTree) const
  {
    const std::string localId = "visualize";
    // get correct parameters
    Dune::ParameterTree* paramsP = &paramTree;
    if (paramsP->hasSub(id))
      paramsP = &(paramsP->sub(id));
    if (paramsP->hasSub(localId))
      paramsP = &(paramsP->sub(localId));
    Dune::ParameterTree& params = *paramsP;
    // check for grid visualization
    if (params.hasKey("grid")) {
      const std::string filenameGrid = params.get("grid", id + ".grid");
      // grid view
      typedef GridImp GridType;
      GridType& grid = this->grid();
      typedef typename GridType::LeafGridView GridView;
      GridView gridView = grid.leafView();
      // mapper
      Dune::LeafMultipleCodimMultipleGeomTypeMapper< GridType, P0Layout > mapper(grid);
      std::vector< double > data(mapper.size());
      // walk the grid
      typedef typename GridView::template Codim<0>::Iterator ElementIterator;
      typedef typename GridView::template Codim<0>::Entity ElementType;
      typedef typename ElementType::LeafIntersectionIterator FacetIteratorType;
      for (ElementIterator it = gridView.template begin<0>(); it != gridView.template end<0>(); ++it)
      {
        ElementType& element = *it;
        data[mapper.map(element)] = 0.0;
        int numberOfBoundarySegments = 0;
        bool isOnBoundary = false;
        for (FacetIteratorType facet = element.ileafbegin();
             facet != element.ileafend();
             ++facet) {
          if (!facet->neighbor() && facet->boundary()){
            isOnBoundary = true;
            numberOfBoundarySegments += 1;
            data[mapper.map(element)] += double(facet->boundaryId());
          }
        }
        if (isOnBoundary) {
          data[mapper.map(element)] /= double(numberOfBoundarySegments);
        }
      } // walk the grid
      // write to vtk
      Dune::VTKWriter< GridView > vtkwriter(gridView);
      vtkwriter.addCellData(data, "boundaryId");
      vtkwriter.write(filenameGrid, Dune::VTK::ascii);
    } // check for grid visualization
  } // void visualize(Dune::ParameterTree& paramTree)

private:
  void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level)
  {
    Dune::array< unsigned int, dim > numElements;
    std::fill(numElements.begin(), numElements.end(), 1);
    switch (variant) {
      case 1:
        grid_ = Dune::StructuredGridFactory< GridType >::createCubeGrid(lowerLeft, upperRight, numElements);
        break;
      case 2:
        grid_ = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lowerLeft, upperRight, numElements);
        break;
      default:
        DUNE_THROW(Dune::NotImplemented, "Variant " << variant << " of cube not implemented.");
    }
    grid_->globalRefine(level);
    return;
  } // void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight)

protected:
  CoordinateType lowerLeft_;
  CoordinateType upperRight_;

private:
  Dune::shared_ptr< GridType > grid_;
}; // class GenericCube

template< typename GridImp, int variant >
const std::string GenericCube< GridImp, variant >::id = "stuff.grid.provider.cube";

// default implementation of a cube for any grid
// tested for
// dim = 2
//  ALUGRID_SIMPLEX, variant 2
//  ALUGRID_CONFORM, variant 2
// dim = 3
//  ALUGRID_SIMPLEX, variant 2
template< typename GridType >
class Cube
  : public GenericCube< GridType, 2 >
{
private:
  typedef GenericCube< GridType, 2 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube

// specialization of Cube for YaspGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::YaspGrid< dim > >
  : public GenericCube< Dune::YaspGrid< dim >, 1 >
{
private:
  typedef GenericCube< Dune::YaspGrid< dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::YaspGrid< dim > >

// specialization of Cube for SGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::SGrid< dim, dim > >
  : public GenericCube< Dune::SGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::SGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::SGrid< dim, dim > >

// specialization of Cube for ALUCubeGrid
// tested for dim = 2, 3
template< int dim >
class Cube< Dune::ALUCubeGrid< dim, dim > >
  : public GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::ALUCubeGrid< dim, dim > >

template< typename GridType >
class UnitCube
  : public Cube< GridType >
{
private:
  typedef Cube< GridType > BaseType;

public:
  UnitCube(const Dune::ParameterTree& paramTree)
    : BaseType(0.0, 1.0, paramTree.get("level", 1))
  {}

  UnitCube(const int level = 1)
    : BaseType(0.0, 1.0, level)
  {}
}; // class UnitCube

} // namespace Provider

} // namespace Grid

} // namespace Stuff

} // namespace Dune

#endif // DUNE_STUFF_GRID_PROVIDER_CUBE_HH
<commit_msg>[grid.provider.cube] added lowerLeft() and upperRight()<commit_after>#ifndef DUNE_STUFF_GRID_PROVIDER_CUBE_HH
#define DUNE_STUFF_GRID_PROVIDER_CUBE_HH

// dune-common
#include <dune/common/parametertree.hh>
#include <dune/common/shared_ptr.hh>
#include <dune/common/exceptions.hh>
#include <dune/common/fvector.hh>

// dune-grid
#include <dune/grid/utility/structuredgridfactory.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/alugrid.hh>
#include <dune/grid/sgrid.hh>
#include <dune/grid/common/mcmgmapper.hh>
#include <dune/grid/io/file/vtk/vtkwriter.hh>

namespace Dune
{

namespace Stuff
{

namespace Grid
{

namespace Provider
{

/**
  \brief  Creates a grid of a cube in various dimensions.

          Default implementation using the Dune::StructuredGridFactory to create a grid of a cube in 1, 2 or 3
          dimensions. Tested with

 \c YASPGRID, \c variant 1, dim = 1, 2, 3,

 \c SGRID, \c variant 1, dim = 1, 2, 3,

 \c ALUGRID_SIMPLEX, \c variant 2, dim = 2, 3,

 \c ALUGRID_CONFORM, \c variant 2, dim = 2, 2 and

 \c ALUGRID_CUBE, \c variant 1, dim = 2, 3.

  \tparam GridImp
          Type of the underlying grid.
  \tparam variant
          Type of the codim 0 elements:

\c 1: cubes

2: simplices

  **/
template< typename GridImp, int variant >
class GenericCube
{
public:
  //! Type of the provided grid.
  typedef GridImp GridType;

  //! Dimension of the provided grid.
  static const int dim = GridType::dimension;

  //! Type of the grids coordinates.
  typedef Dune::FieldVector< typename GridType::ctype, dim > CoordinateType;

  //! Unique identifier: \c stuff.grid.provider.cube
  static const std::string id;

  /**
    \brief      Creates a cube.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys.

                The actual keys are:

 \c lowerLeft: \a double that is used as a lower left corner in each dimension.

 \c upperRight: \a double that is used as a upper right corner in each dimension.

    **/
  GenericCube(const Dune::ParameterTree& paramTree)
    : lowerLeft_(0.0),
      upperRight_(0.0)
  {
    // check for parameters
    const double lowerLeft = paramTree.get("lowerLeft", 0.0);
    const double upperRight = paramTree.get("upperRight", 1.0);
    assert(lowerLeft < upperRight);
    const int level = paramTree.get("level", 1);
    lowerLeft_ = lowerLeft;
    upperRight_ = upperRight;
    buildGrid(lowerLeft_, upperRight_, level);
  } // Cube(const Dune::ParameterTree& paramTree)

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A vector that is used as a lower left corner.
    \param[in]  upperRight
                A vector that is used as a upper right corner.
    **/
  GenericCube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : lowerLeft_(lowerLeft),
      upperRight_(upperRight)
  {
    buildGrid(lowerLeft_, upperRight_, level);
  }

  /**
    \brief      Creates a cube.
    \param[in]  lowerLeft
                A double that is used as a lower left corner in each dimension.
    \param[in]  upperRight
                A double that is used as a upper right corner in each dimension.
    **/
  GenericCube(const double lowerLeft, const double upperRight, const int level = 1)
    : lowerLeft_(lowerLeft),
      upperRight_(upperRight)
  {
    buildGrid(lowerLeft_, upperRight_, level);
  }

  /**
    \brief  Provides access to the created grid.
    \return Reference to the grid.
    **/
  GridType& grid()
  {
    return *grid_;
  }

  const GridType& grid() const
  {
    return *grid_;
  }

  const CoordinateType& lowerLeft() const
  {
    return lowerLeft_;
  }

  const CoordinateType& upperRight() const
  {
    return upperRight_;
  }

private:
  template< int dim >
  struct P0Layout
  {
    bool contains(Dune::GeometryType& geometry)
    {
      if (geometry.dim() == dim)
        return true;
      return false;
    }
  }; // layout class for codim 0 mapper

  /**
    \brief      Visualizes the grid using Dune::VTKWriter.
    \param[in]  paramTree
                A Dune::ParameterTree containing

 the following keys directly or

 a subtree named Cube::id, containing the following keys, or

 a subtree named Cube::id + \c .visualize, containing the following keys.

                The actual keys are:

 \c grid: if specified, filename of the vtk file in which the grid which can be obtained via
                  grid() is visualized (\a if \a not \a specified: \a no \a visualization).

 \c mdGrid: if specified, filename of the vtk file in which the multidomain grid which can be
                  obtained via mdGrid() is visualized (\a if \a not \a specified: \a no \a visualization).

    **/
public:
  void visualize(Dune::ParameterTree& paramTree) const
  {
    const std::string localId = "visualize";
    // get correct parameters
    Dune::ParameterTree* paramsP = &paramTree;
    if (paramsP->hasSub(id))
      paramsP = &(paramsP->sub(id));
    if (paramsP->hasSub(localId))
      paramsP = &(paramsP->sub(localId));
    Dune::ParameterTree& params = *paramsP;
    // check for grid visualization
    if (params.hasKey("grid")) {
      const std::string filenameGrid = params.get("grid", id + ".grid");
      // grid view
      typedef GridImp GridType;
      GridType& grid = this->grid();
      typedef typename GridType::LeafGridView GridView;
      GridView gridView = grid.leafView();
      // mapper
      Dune::LeafMultipleCodimMultipleGeomTypeMapper< GridType, P0Layout > mapper(grid);
      std::vector< double > data(mapper.size());
      // walk the grid
      typedef typename GridView::template Codim<0>::Iterator ElementIterator;
      typedef typename GridView::template Codim<0>::Entity ElementType;
      typedef typename ElementType::LeafIntersectionIterator FacetIteratorType;
      for (ElementIterator it = gridView.template begin<0>(); it != gridView.template end<0>(); ++it)
      {
        ElementType& element = *it;
        data[mapper.map(element)] = 0.0;
        int numberOfBoundarySegments = 0;
        bool isOnBoundary = false;
        for (FacetIteratorType facet = element.ileafbegin();
             facet != element.ileafend();
             ++facet) {
          if (!facet->neighbor() && facet->boundary()){
            isOnBoundary = true;
            numberOfBoundarySegments += 1;
            data[mapper.map(element)] += double(facet->boundaryId());
          }
        }
        if (isOnBoundary) {
          data[mapper.map(element)] /= double(numberOfBoundarySegments);
        }
      } // walk the grid
      // write to vtk
      Dune::VTKWriter< GridView > vtkwriter(gridView);
      vtkwriter.addCellData(data, "boundaryId");
      vtkwriter.write(filenameGrid, Dune::VTK::ascii);
    } // check for grid visualization
  } // void visualize(Dune::ParameterTree& paramTree)

private:
  void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level)
  {
    Dune::array< unsigned int, dim > numElements;
    std::fill(numElements.begin(), numElements.end(), 1);
    switch (variant) {
      case 1:
        grid_ = Dune::StructuredGridFactory< GridType >::createCubeGrid(lowerLeft, upperRight, numElements);
        break;
      case 2:
        grid_ = Dune::StructuredGridFactory< GridType >::createSimplexGrid(lowerLeft, upperRight, numElements);
        break;
      default:
        DUNE_THROW(Dune::NotImplemented, "Variant " << variant << " of cube not implemented.");
    }
    grid_->globalRefine(level);
    return;
  } // void buildGrid(const CoordinateType& lowerLeft, const CoordinateType& upperRight)

  CoordinateType lowerLeft_;
  CoordinateType upperRight_;
  Dune::shared_ptr< GridType > grid_;
}; // class GenericCube

template< typename GridImp, int variant >
const std::string GenericCube< GridImp, variant >::id = "stuff.grid.provider.cube";

// default implementation of a cube for any grid
// tested for
// dim = 2
//  ALUGRID_SIMPLEX, variant 2
//  ALUGRID_CONFORM, variant 2
// dim = 3
//  ALUGRID_SIMPLEX, variant 2
template< typename GridType >
class Cube
  : public GenericCube< GridType, 2 >
{
private:
  typedef GenericCube< GridType, 2 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube

// specialization of Cube for YaspGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::YaspGrid< dim > >
  : public GenericCube< Dune::YaspGrid< dim >, 1 >
{
private:
  typedef GenericCube< Dune::YaspGrid< dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::YaspGrid< dim > >

// specialization of Cube for SGrid
// tested for dim = 1, 2, 3
template< int dim >
class Cube< Dune::SGrid< dim, dim > >
  : public GenericCube< Dune::SGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::SGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::SGrid< dim, dim > >

// specialization of Cube for ALUCubeGrid
// tested for dim = 2, 3
template< int dim >
class Cube< Dune::ALUCubeGrid< dim, dim > >
  : public GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 >
{
private:
  typedef GenericCube< Dune::ALUCubeGrid< dim, dim >, 1 > BaseType;

public:
  typedef typename BaseType::CoordinateType CoordinateType;

  Cube(const Dune::ParameterTree& paramTree)
    : BaseType(paramTree)
  {}

  Cube(const CoordinateType& lowerLeft, const CoordinateType& upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}

  Cube(const double lowerLeft, const double upperRight, const int level = 1)
    : BaseType(lowerLeft, upperRight, level)
  {}
}; // class Cube< Dune::ALUCubeGrid< dim, dim > >

template< typename GridType >
class UnitCube
  : public Cube< GridType >
{
private:
  typedef Cube< GridType > BaseType;

public:
  UnitCube(const Dune::ParameterTree& paramTree)
    : BaseType(0.0, 1.0, paramTree.get("level", 1))
  {}

  UnitCube(const int level = 1)
    : BaseType(0.0, 1.0, level)
  {}
}; // class UnitCube

} // namespace Provider

} // namespace Grid

} // namespace Stuff

} // namespace Dune

#endif // DUNE_STUFF_GRID_PROVIDER_CUBE_HH
<|endoftext|>