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

#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

#include "bootstrp/prj.hxx"

#include <string.hxx>
#include <list.hxx>
#include <fsys.hxx>
#include <stream.hxx>

#include "cppdep.hxx"

class RscHrcDep : public CppDep
{
public:
                    RscHrcDep();
    virtual         ~RscHrcDep();

    virtual void    Execute();
};

RscHrcDep::RscHrcDep()  :
    CppDep()
{
}

RscHrcDep::~RscHrcDep()
{
}

void RscHrcDep::Execute()
{
    CppDep::Execute();
}

//static String aDelim;

/* poor man's getopt() */
int     simple_getopt(char *argv[], const char *optstring);
#ifdef WNT
static char *optarg = NULL;
static int  optind = 1;
static int  optopt = 0;
static int  opterr = 0;
#endif

int
#ifdef WNT
_cdecl
#endif
main( int argc, char **argv )
{
    int c;
    char aBuf[255];
    char pOutputFileName[255];
    char pSrsFileName[255];
    String aSrsBaseName;
    BOOL bSource = FALSE;
    ByteString aRespArg;
    String aDelim = String(DirEntry::GetAccessDelimiter());

    RscHrcDep *pDep = new RscHrcDep;

    pOutputFileName[0] = 0;
    pSrsFileName[0] = 0;

    for ( int i=1; i<argc; i++)
    {
        strcpy( aBuf, (const char *)argv[i] );
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'o' && aBuf[3] == '=' )
        {
            strcpy(pOutputFileName, &aBuf[4]);
            //break;
        }
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'p' && aBuf[3] == '=' )
        {
            strcpy(pSrsFileName, &aBuf[4]);
            String aName( pSrsFileName, gsl_getSystemTextEncoding());
            DirEntry aDest( aName );
            aSrsBaseName = aDest.GetBase();
            //break;
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'i' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'I' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '@' )
        {
            ByteString aToken;
            String aRespName( &aBuf[1], gsl_getSystemTextEncoding());
            SimpleConfig aConfig( aRespName );
            while ( (aToken = aConfig.GetNext()) != "")
            {
                char aBuf2[255];
                (void) strcpy( aBuf2, aToken.GetBuffer());
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'o' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    //break;
                }
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'p' )
                {
                    strcpy(pSrsFileName, &aBuf2[3]);
                    String aName( pSrsFileName, gsl_getSystemTextEncoding());
                    DirEntry aDest( aName );
                    aSrsBaseName = aDest.GetBase();
                    //break;
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'i' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'I' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (( aBuf2[0] != '-' ) && ( aBuf2[0] != '@' ))
                {
                    pDep->AddSource( &aBuf2[0] );
                    aRespArg += " ";
                    aRespArg += &aBuf2[0];
                    bSource = TRUE;
                }
            }
        }
    }

    while( 1 )
    {
        c = simple_getopt( argv,
        "_abcdefghi:jklmnopqrstuvwxyzABCDEFGHI:JKLMNOPQRSTUVWXYZ1234567890/-+=.\\()\"");
        if ( c == -1 )
            break;

        switch( c )
        {
            case 0:
                break;
            case 'a' :
#ifdef DEBUG_VERBOSE
                printf("option a\n");
#endif
                break;

            case 'l' :
#ifdef DEBUG_VERBOSE
                printf("option l with Value %s\n", optarg );
#endif
                pDep->AddSource( optarg );
                break;

            case 'h' :
            case 'H' :
            case '?' :
                printf("RscDep 1.0 (c)2000 StarOffice\n");
                break;

            default:
#ifdef DEBUG_VERBOSE
                printf("Unknown getopt error\n");
#endif
                ;
        }
    }

    DirEntry aEntry(".");
    aEntry.ToAbs();
    String aCwd = aEntry.GetName();
/*  USHORT nPos;
#ifndef UNX
    while ( (nPos = aCwd.Search('\\') != STRING_NOTFOUND  ))
#else
    while ( (nPos = aCwd.Search('/') != STRING_NOTFOUND  ))
#endif
    {
        String attt = aCwd.Copy( 0, nPos );
        aCwd.Erase( 0, nPos );
    } */
    SvFileStream aOutStream;
    String aOutputFileName( pOutputFileName, gsl_getSystemTextEncoding());
    DirEntry aOutEntry( aOutputFileName );
    String aOutPath = aOutEntry.GetPath().GetFull();

    String aFileName( aOutPath );
    aFileName += aDelim;
    aFileName += aCwd;
    aFileName += String(".", gsl_getSystemTextEncoding());
    aFileName += aSrsBaseName;
    aFileName += String(".dprr", gsl_getSystemTextEncoding());
    //fprintf( stderr, "OutFileName : %s \n",aFileName.GetStr());
    aOutStream.Open( aFileName, STREAM_WRITE );

    ByteString aString;
    if ( optind < argc )
    {
#ifdef DEBUG_VERBOSE
        printf("further arguments : ");
#endif
        aString = ByteString( pSrsFileName );
        aString += ByteString(" : " );

        while ( optind < argc )
        {
            if (!bSource )
            {
                aString += ByteString(" " );
                aString += ByteString( argv[optind]);
                pDep->AddSource( argv[optind++]);
            }
            else
            {
                optind++;
            }
        }
    }
    aString += aRespArg;
    pDep->Execute();
    ByteStringList *pLst = pDep->GetDepList();
    ULONG nCount = pLst->Count();
    if ( nCount == 0 )
    {
        aOutStream.WriteLine( aString );
    }
    else
    {
        aString += ByteString( "\\" );
        aOutStream.WriteLine( aString );
    }

    for ( ULONG j=0; j<nCount; j++ )
    {
        ByteString *pStr = pLst->GetObject(j);
#ifdef UNX
        pStr->SearchAndReplaceAll('\\', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
#ifdef WNT
        pStr->SearchAndReplaceAll('/', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
        if ( j != (nCount-1) )
            *pStr += ByteString( "\\" );
        aOutStream.WriteLine( *pStr );
    }
    delete pDep;
    aOutStream.Close();

    return 0;
}

/* my very simple minded implementation of getopt()
 * it's too sad that getopt() is not available everywhere
 * note: this is not a full POSIX conforming getopt()
 */
int simple_getopt(char *argv[], const char *optstring)
{
    char *arg = argv[optind];

    /* skip all response file arguments */
    if ( arg ) {
        while ( *arg == '@' )
            arg = argv[++optind];

        if ( arg[0] == '-' && arg[1] != '\0' ) {
            const char *popt;
            int c = arg[1];
            if ( (popt = strchr(optstring, c)) == NULL ) {
                optopt = c;
                if ( opterr )
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                return '?';
            }
            if ( *(++popt) == ':') {
                 if ( arg[2] != '\0' ) {
                     optarg = ++arg;
                 } else {
                     optarg = argv[++optind];
                 }
             } else {
                 optarg = NULL;
             }
             ++optind;
             return c;
        }
    }
    return -1;
}

<commit_msg>INTEGRATION: CWS pchfix02 (1.21.44); FILE MERGED 2006/09/01 17:54:47 kaib 1.21.44.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: rscdep.cxx,v $
 *
 *  $Revision: 1.22 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 00:49:23 $
 *
 *  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_tools.hxx"
#ifdef UNX
#include <unistd.h>
#endif

#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

#include "bootstrp/prj.hxx"

#include <string.hxx>
#include <list.hxx>
#include <fsys.hxx>
#include <stream.hxx>

#include "cppdep.hxx"

class RscHrcDep : public CppDep
{
public:
                    RscHrcDep();
    virtual         ~RscHrcDep();

    virtual void    Execute();
};

RscHrcDep::RscHrcDep()  :
    CppDep()
{
}

RscHrcDep::~RscHrcDep()
{
}

void RscHrcDep::Execute()
{
    CppDep::Execute();
}

//static String aDelim;

/* poor man's getopt() */
int     simple_getopt(char *argv[], const char *optstring);
#ifdef WNT
static char *optarg = NULL;
static int  optind = 1;
static int  optopt = 0;
static int  opterr = 0;
#endif

int
#ifdef WNT
_cdecl
#endif
main( int argc, char **argv )
{
    int c;
    char aBuf[255];
    char pOutputFileName[255];
    char pSrsFileName[255];
    String aSrsBaseName;
    BOOL bSource = FALSE;
    ByteString aRespArg;
    String aDelim = String(DirEntry::GetAccessDelimiter());

    RscHrcDep *pDep = new RscHrcDep;

    pOutputFileName[0] = 0;
    pSrsFileName[0] = 0;

    for ( int i=1; i<argc; i++)
    {
        strcpy( aBuf, (const char *)argv[i] );
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'o' && aBuf[3] == '=' )
        {
            strcpy(pOutputFileName, &aBuf[4]);
            //break;
        }
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'p' && aBuf[3] == '=' )
        {
            strcpy(pSrsFileName, &aBuf[4]);
            String aName( pSrsFileName, gsl_getSystemTextEncoding());
            DirEntry aDest( aName );
            aSrsBaseName = aDest.GetBase();
            //break;
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'i' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'I' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '@' )
        {
            ByteString aToken;
            String aRespName( &aBuf[1], gsl_getSystemTextEncoding());
            SimpleConfig aConfig( aRespName );
            while ( (aToken = aConfig.GetNext()) != "")
            {
                char aBuf2[255];
                (void) strcpy( aBuf2, aToken.GetBuffer());
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'o' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    //break;
                }
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'p' )
                {
                    strcpy(pSrsFileName, &aBuf2[3]);
                    String aName( pSrsFileName, gsl_getSystemTextEncoding());
                    DirEntry aDest( aName );
                    aSrsBaseName = aDest.GetBase();
                    //break;
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'i' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'I' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (( aBuf2[0] != '-' ) && ( aBuf2[0] != '@' ))
                {
                    pDep->AddSource( &aBuf2[0] );
                    aRespArg += " ";
                    aRespArg += &aBuf2[0];
                    bSource = TRUE;
                }
            }
        }
    }

    while( 1 )
    {
        c = simple_getopt( argv,
        "_abcdefghi:jklmnopqrstuvwxyzABCDEFGHI:JKLMNOPQRSTUVWXYZ1234567890/-+=.\\()\"");
        if ( c == -1 )
            break;

        switch( c )
        {
            case 0:
                break;
            case 'a' :
#ifdef DEBUG_VERBOSE
                printf("option a\n");
#endif
                break;

            case 'l' :
#ifdef DEBUG_VERBOSE
                printf("option l with Value %s\n", optarg );
#endif
                pDep->AddSource( optarg );
                break;

            case 'h' :
            case 'H' :
            case '?' :
                printf("RscDep 1.0 (c)2000 StarOffice\n");
                break;

            default:
#ifdef DEBUG_VERBOSE
                printf("Unknown getopt error\n");
#endif
                ;
        }
    }

    DirEntry aEntry(".");
    aEntry.ToAbs();
    String aCwd = aEntry.GetName();
/*  USHORT nPos;
#ifndef UNX
    while ( (nPos = aCwd.Search('\\') != STRING_NOTFOUND  ))
#else
    while ( (nPos = aCwd.Search('/') != STRING_NOTFOUND  ))
#endif
    {
        String attt = aCwd.Copy( 0, nPos );
        aCwd.Erase( 0, nPos );
    } */
    SvFileStream aOutStream;
    String aOutputFileName( pOutputFileName, gsl_getSystemTextEncoding());
    DirEntry aOutEntry( aOutputFileName );
    String aOutPath = aOutEntry.GetPath().GetFull();

    String aFileName( aOutPath );
    aFileName += aDelim;
    aFileName += aCwd;
    aFileName += String(".", gsl_getSystemTextEncoding());
    aFileName += aSrsBaseName;
    aFileName += String(".dprr", gsl_getSystemTextEncoding());
    //fprintf( stderr, "OutFileName : %s \n",aFileName.GetStr());
    aOutStream.Open( aFileName, STREAM_WRITE );

    ByteString aString;
    if ( optind < argc )
    {
#ifdef DEBUG_VERBOSE
        printf("further arguments : ");
#endif
        aString = ByteString( pSrsFileName );
        aString += ByteString(" : " );

        while ( optind < argc )
        {
            if (!bSource )
            {
                aString += ByteString(" " );
                aString += ByteString( argv[optind]);
                pDep->AddSource( argv[optind++]);
            }
            else
            {
                optind++;
            }
        }
    }
    aString += aRespArg;
    pDep->Execute();
    ByteStringList *pLst = pDep->GetDepList();
    ULONG nCount = pLst->Count();
    if ( nCount == 0 )
    {
        aOutStream.WriteLine( aString );
    }
    else
    {
        aString += ByteString( "\\" );
        aOutStream.WriteLine( aString );
    }

    for ( ULONG j=0; j<nCount; j++ )
    {
        ByteString *pStr = pLst->GetObject(j);
#ifdef UNX
        pStr->SearchAndReplaceAll('\\', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
#ifdef WNT
        pStr->SearchAndReplaceAll('/', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
        if ( j != (nCount-1) )
            *pStr += ByteString( "\\" );
        aOutStream.WriteLine( *pStr );
    }
    delete pDep;
    aOutStream.Close();

    return 0;
}

/* my very simple minded implementation of getopt()
 * it's too sad that getopt() is not available everywhere
 * note: this is not a full POSIX conforming getopt()
 */
int simple_getopt(char *argv[], const char *optstring)
{
    char *arg = argv[optind];

    /* skip all response file arguments */
    if ( arg ) {
        while ( *arg == '@' )
            arg = argv[++optind];

        if ( arg[0] == '-' && arg[1] != '\0' ) {
            const char *popt;
            int c = arg[1];
            if ( (popt = strchr(optstring, c)) == NULL ) {
                optopt = c;
                if ( opterr )
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                return '?';
            }
            if ( *(++popt) == ':') {
                 if ( arg[2] != '\0' ) {
                     optarg = ++arg;
                 } else {
                     optarg = argv[++optind];
                 }
             } else {
                 optarg = NULL;
             }
             ++optind;
             return c;
        }
    }
    return -1;
}

<|endoftext|>


<commit_before>#pragma once

#include <crest/basis/homogenized_basis.hpp>

// Must include detail/qr here because it does not seem to be included by LGMRES,
// which it should be
#include <amgcl/detail/qr.hpp>
#include <amgcl/amg.hpp>
#include <amgcl/coarsening/smoothed_aggregation.hpp>
#include <amgcl/relaxation/spai0.hpp>
#include <amgcl/backend/eigen.hpp>
#include <amgcl/solver/lgmres.hpp>
#include <amgcl/make_solver.hpp>

#ifdef _OPENMP
#include <omp.h>
#endif

namespace crest
{
    namespace detail
    {
        template <typename Scalar>
        class CorrectorBlockMatrix
        {
        public:
            typedef Eigen::SparseMatrix<Scalar, Eigen::RowMajor> Matrix;

            explicit CorrectorBlockMatrix(Matrix stiffness, Matrix quasi_interpolator)
                    : _stiffness(std::move(stiffness)), _quasi_interpolator(std::move(quasi_interpolator)) {}

            const Matrix & stiffness() const { return _stiffness; }

            const Matrix & quasi_interpolator() const { return _quasi_interpolator; }

            Eigen::Index rows() const { return stiffness().rows() + quasi_interpolator().rows(); }

            Eigen::Index cols() const { return stiffness().cols() + quasi_interpolator().cols(); }

        private:
            Matrix _stiffness;
            Matrix _quasi_interpolator;
        };

        template <typename Scalar>
        class CorrectorBlockMatrixIdentityPreconditioner
        {
        public:
            typedef amgcl::backend::eigen<Scalar> Backend;
            typedef Backend backend_type;
            typedef CorrectorBlockMatrix<Scalar> matrix;
            typedef typename Backend::vector vector;
            typedef typename Backend::value_type value_type;

            typedef amgcl::detail::empty_params params;
            typedef typename Backend::params backend_params;

            template <class Matrix>
            CorrectorBlockMatrixIdentityPreconditioner(
                    const Matrix & M,
                    const params & prm = params(),
                    const backend_params & bprm = backend_params())
                    : _matrix(&M)
            {
                (void) prm;
                (void) bprm;
            }

            template <class Vec1, class Vec2>
            void apply(const Vec1 & rhs, Vec2 && x) const
            {
                amgcl::backend::copy(rhs, x);
            }

            const matrix & system_matrix() const
            {
                return *_matrix;
            }

        private:
            const matrix * _matrix;
        };

        template <typename Scalar, typename StiffnessPreconditioner>
        class CorrectorBlockPreconditioner {
        public:
            typedef amgcl::backend::eigen<Scalar> Backend;
            typedef Eigen::SparseMatrix<Scalar, Eigen::RowMajor> SparseMatrix;

            typedef Backend backend_type;
            typedef CorrectorBlockMatrix<Scalar> matrix;
            typedef typename Backend::vector vector;
            typedef typename Backend::value_type value_type;

            typedef typename Backend::params backend_params;

            struct params
            {
                typename StiffnessPreconditioner::params stiffness_precond_params;
                const SparseMatrix * schur_inverse_approx;

                params() : schur_inverse_approx(nullptr) {}
            };

            template <class Matrix>
            CorrectorBlockPreconditioner(
                    const Matrix & M,
                    const params & prm = params(),
                    const backend_params & bprm = backend_params())
                    : _matrix(&M),
                      _stiffness_preconditioner(M.stiffness()),
                      _schur_inverse_approx(prm.schur_inverse_approx),
                      v(M.stiffness().rows()),
                      w(M.quasi_interpolator().rows()),
                      z(M.stiffness().rows()),
                      y(M.stiffness().rows()),
                      S_inv_w(M.quasi_interpolator().rows()),
                      corrector_buffer(M.stiffness().rows())
            {
                (void) bprm;
                const auto & I_H = M.quasi_interpolator();
                const auto & S_inv = *_schur_inverse_approx;
                I_H_transpose_S_inv = I_H.transpose() * S_inv;
            }

            template <class Vec1, class Vec2>
            void apply(const Vec1 & rhs, Vec2 & x) const
            {
                amgcl::backend::clear(x);

                const auto & S_inv = *_schur_inverse_approx;
                const auto n = _matrix->stiffness().rows();
                const auto m = _matrix->quasi_interpolator().rows();

                v = rhs.topRows(n);
                w = rhs.bottomRows(m);
                S_inv_w = S_inv * w;
                z = I_H_transpose_S_inv * w;
                y = v + z;

                _stiffness_preconditioner.apply(y, corrector_buffer);
                x.topRows(n) = corrector_buffer;
                x.bottomRows(m) = - S_inv_w;
            }

            const matrix & system_matrix() const
            {
                return *_matrix;
            }

        private:
            const matrix * _matrix;
            StiffnessPreconditioner _stiffness_preconditioner;
            const SparseMatrix * _schur_inverse_approx;

            // Buffers used to avoid unnecessary allocation
            mutable VectorX<Scalar> v;
            mutable VectorX<Scalar> w;
            mutable VectorX<Scalar> z;
            mutable VectorX<Scalar> y;
            mutable VectorX<Scalar> S_inv_w;
            mutable VectorX<Scalar> corrector_buffer;
            mutable SparseMatrix I_H_transpose_S_inv;
        };
    }
}

namespace crest
{
    template <typename Scalar>
    class AmgCorrectorSolver : public CorrectorSolver<Scalar>
    {
    public:
        virtual std::vector<Eigen::Triplet<Scalar>> resolve_element_correctors_for_patch(
                const BiscaleMesh<Scalar, int> & mesh,
                const std::vector<int> & coarse_patch_interior,
                const std::vector<int> & fine_patch_interior,
                const Eigen::SparseMatrix<Scalar> & global_coarse_stiffness,
                const Eigen::SparseMatrix<Scalar> & global_fine_stiffness,
                const Eigen::SparseMatrix<Scalar> & global_quasi_interpolator,
                int coarse_element) const override
        {
            // We actually DON'T want to use multiple threads in this instance,
            // in order to get a fair comparison with other schemes.
#ifdef _OPENMP
            const auto num_threads = omp_get_max_threads();
            omp_set_num_threads(1);
#endif

            typedef Eigen::SparseMatrix<Scalar, Eigen::RowMajor> RowMajorMatrix;
            const RowMajorMatrix I_H = sparse_submatrix(global_quasi_interpolator,
                                                        coarse_patch_interior,
                                                        fine_patch_interior);
            const RowMajorMatrix A_h = sparse_submatrix(global_fine_stiffness,
                                                        fine_patch_interior,
                                                        fine_patch_interior);
            const RowMajorMatrix A_H = sparse_submatrix(global_coarse_stiffness,
                                                        coarse_patch_interior,
                                                        coarse_patch_interior);

            assert(A_h.rows() > 0);
            const auto m = I_H.rows();

            typedef amgcl::backend::eigen<Scalar> Backend;

            typedef amgcl::amg<
                    Backend,
                    amgcl::coarsening::smoothed_aggregation,
                    amgcl::relaxation::spai0
            > StiffnessPreconditioner;

            typedef detail::CorrectorBlockPreconditioner<Scalar, StiffnessPreconditioner> BlockPreconditioner;
            typedef amgcl::solver::lgmres<Backend> IterativeSolver;
            typedef amgcl::make_solver<BlockPreconditioner, IterativeSolver> Solver;

            std::vector<Eigen::Triplet<Scalar>> triplets;

            detail::CorrectorBlockMatrix<Scalar> C(std::move(A_h), std::move(I_H));

            typename Solver::params params;
            params.precond.schur_inverse_approx = &A_H;
//            params.precond.stiffness_precond_params.coarse_enough = 1000;
            // TODO: Make parameters configurable
//            params.solver.tol = 1e-9; //std::numeric_limits<Scalar>::epsilon();
            params.solver.tol = std::numeric_limits<Scalar>::epsilon();
            params.solver.pside = amgcl::precond::right;
            Solver solver(C, params);

            for (int i = 0; i < 3; ++i)
            {
                const auto b = this->local_rhs(mesh, fine_patch_interior, coarse_element, i);

                VectorX<Scalar> sol(C.rows());
                sol.setZero();

                VectorX<Scalar> rhs(C.rows());
                rhs << b, VectorX<Scalar>::Zero(m);

                int    iters;
                double error;
                boost::tie(iters, error) = solver(rhs, sol);

                const auto global_index = mesh.coarse_mesh().elements()[coarse_element].vertex_indices[i];
                for (size_t k = 0; k < fine_patch_interior.size(); ++k)
                {
                    const auto component = sol(k);
                    // Due to rounding issues, some components that should perhaps be zero in exact arithmetic
                    // may be non-zero, and as such we might end up with a denser matrix than we should actually
                    // have. To prevent this, we introduce a threshold which determines whether to keep the entry.
                    // TODO: Make this threshold configurable?
                    if (std::abs(component) > 1e-12)
                    {
                        triplets.emplace_back(Eigen::Triplet<Scalar>(global_index, fine_patch_interior[k], component));
                    }
                }
            }

            // It's crucical that we restore the number of threads used by OpenMP upon exit. Note that this
            // isn't exception safe (would have to use some RAII wrapper instead).
#ifdef _OPENMP
            omp_set_num_threads(num_threads);
#endif

            return triplets;
        }
    };
}

namespace amgcl
{
    namespace backend
    {

        template <typename Scalar>
        struct rows_impl<::crest::detail::CorrectorBlockMatrix<Scalar>>
        {
            static size_t get(const ::crest::detail::CorrectorBlockMatrix<Scalar> &matrix) {
                return matrix.rows();
            }
        };

        template < class Alpha, class V1, class Beta, class V2, typename Scalar>
        struct spmv_impl<
                Alpha, ::crest::detail::CorrectorBlockMatrix<Scalar>, V1, Beta, V2,
                typename boost::enable_if<
                        typename boost::mpl::and_<
                                typename is_eigen_type<V1>::type,
                                typename is_eigen_type<V2>::type
                        >::type
                >::type
        >
        {
            static void apply(Alpha alpha, const ::crest::detail::CorrectorBlockMatrix<Scalar> &mat, const V1 &x, Beta beta, V2 &y)
            {
                const auto & A = mat.stiffness();
                const auto & I_H = mat.quasi_interpolator();
                const auto n = A.rows();
                const auto m = I_H.rows();

                if (!math::is_zero(beta))
                {
                    y = beta * y;
                    y.topRows(n) += alpha * A * x.topRows(n) + alpha * I_H.transpose() * x.bottomRows(m);
                    y.bottomRows(m) += alpha * I_H * x.topRows(n);
                } else
                {
                    // mat * x
                    y.topRows(n) = alpha * A * x.topRows(n) + alpha * I_H.transpose() * x.bottomRows(m);
                    y.bottomRows(m) = alpha * I_H * x.topRows(n);
                }
            }
        };

        template < class V1, class V2, class V3, typename Scalar >
        struct residual_impl<
                ::crest::detail::CorrectorBlockMatrix<Scalar>, V1, V2, V3,
                typename boost::enable_if<
                        typename boost::mpl::and_<
                                typename is_eigen_type<V1>::type,
                                typename is_eigen_type<V2>::type,
                                typename is_eigen_type<V3>::type
                        >::type
                >::type
        >
        {
            static void apply(const V1 &rhs, const ::crest::detail::CorrectorBlockMatrix<Scalar> &A, const V2 &x, V3 &r)
            {
                // Let r = Ax
                backend::spmv(1.0, A, x, 0, r);
                // Adjust r so that r = rhs - Ax
                r = rhs - r;
            }
        };

        template <typename Scalar>
        struct value_type<::crest::detail::CorrectorBlockMatrix<Scalar>, void>
        {
            typedef Scalar type;
        };
    }
}
<commit_msg>Make sure to give LGMRES a clear start<commit_after>#pragma once

#include <crest/basis/homogenized_basis.hpp>

// Must include detail/qr here because it does not seem to be included by LGMRES,
// which it should be
#include <amgcl/detail/qr.hpp>
#include <amgcl/amg.hpp>
#include <amgcl/coarsening/smoothed_aggregation.hpp>
#include <amgcl/relaxation/spai0.hpp>
#include <amgcl/backend/eigen.hpp>
#include <amgcl/solver/lgmres.hpp>
#include <amgcl/make_solver.hpp>

#ifdef _OPENMP
#include <omp.h>
#endif

namespace crest
{
    namespace detail
    {
        template <typename Scalar>
        class CorrectorBlockMatrix
        {
        public:
            typedef Eigen::SparseMatrix<Scalar, Eigen::RowMajor> Matrix;

            explicit CorrectorBlockMatrix(Matrix stiffness, Matrix quasi_interpolator)
                    : _stiffness(std::move(stiffness)), _quasi_interpolator(std::move(quasi_interpolator)) {}

            const Matrix & stiffness() const { return _stiffness; }

            const Matrix & quasi_interpolator() const { return _quasi_interpolator; }

            Eigen::Index rows() const { return stiffness().rows() + quasi_interpolator().rows(); }

            Eigen::Index cols() const { return stiffness().cols() + quasi_interpolator().cols(); }

        private:
            Matrix _stiffness;
            Matrix _quasi_interpolator;
        };

        template <typename Scalar>
        class CorrectorBlockMatrixIdentityPreconditioner
        {
        public:
            typedef amgcl::backend::eigen<Scalar> Backend;
            typedef Backend backend_type;
            typedef CorrectorBlockMatrix<Scalar> matrix;
            typedef typename Backend::vector vector;
            typedef typename Backend::value_type value_type;

            typedef amgcl::detail::empty_params params;
            typedef typename Backend::params backend_params;

            template <class Matrix>
            CorrectorBlockMatrixIdentityPreconditioner(
                    const Matrix & M,
                    const params & prm = params(),
                    const backend_params & bprm = backend_params())
                    : _matrix(&M)
            {
                (void) prm;
                (void) bprm;
            }

            template <class Vec1, class Vec2>
            void apply(const Vec1 & rhs, Vec2 && x) const
            {
                amgcl::backend::copy(rhs, x);
            }

            const matrix & system_matrix() const
            {
                return *_matrix;
            }

        private:
            const matrix * _matrix;
        };

        template <typename Scalar, typename StiffnessPreconditioner>
        class CorrectorBlockPreconditioner {
        public:
            typedef amgcl::backend::eigen<Scalar> Backend;
            typedef Eigen::SparseMatrix<Scalar, Eigen::RowMajor> SparseMatrix;

            typedef Backend backend_type;
            typedef CorrectorBlockMatrix<Scalar> matrix;
            typedef typename Backend::vector vector;
            typedef typename Backend::value_type value_type;

            typedef typename Backend::params backend_params;

            struct params
            {
                typename StiffnessPreconditioner::params stiffness_precond_params;
                const SparseMatrix * schur_inverse_approx;

                params() : schur_inverse_approx(nullptr) {}
            };

            template <class Matrix>
            CorrectorBlockPreconditioner(
                    const Matrix & M,
                    const params & prm = params(),
                    const backend_params & bprm = backend_params())
                    : _matrix(&M),
                      _stiffness_preconditioner(M.stiffness()),
                      _schur_inverse_approx(prm.schur_inverse_approx),
                      v(M.stiffness().rows()),
                      w(M.quasi_interpolator().rows()),
                      z(M.stiffness().rows()),
                      y(M.stiffness().rows()),
                      S_inv_w(M.quasi_interpolator().rows()),
                      corrector_buffer(M.stiffness().rows())
            {
                (void) bprm;
                const auto & I_H = M.quasi_interpolator();
                const auto & S_inv = *_schur_inverse_approx;
                I_H_transpose_S_inv = I_H.transpose() * S_inv;
            }

            template <class Vec1, class Vec2>
            void apply(const Vec1 & rhs, Vec2 & x) const
            {
                amgcl::backend::clear(x);

                const auto & S_inv = *_schur_inverse_approx;
                const auto n = _matrix->stiffness().rows();
                const auto m = _matrix->quasi_interpolator().rows();

                v = rhs.topRows(n);
                w = rhs.bottomRows(m);
                S_inv_w = S_inv * w;
                z = I_H_transpose_S_inv * w;
                y = v + z;

                _stiffness_preconditioner.apply(y, corrector_buffer);
                x.topRows(n) = corrector_buffer;
                x.bottomRows(m) = - S_inv_w;
            }

            const matrix & system_matrix() const
            {
                return *_matrix;
            }

        private:
            const matrix * _matrix;
            StiffnessPreconditioner _stiffness_preconditioner;
            const SparseMatrix * _schur_inverse_approx;

            // Buffers used to avoid unnecessary allocation
            mutable VectorX<Scalar> v;
            mutable VectorX<Scalar> w;
            mutable VectorX<Scalar> z;
            mutable VectorX<Scalar> y;
            mutable VectorX<Scalar> S_inv_w;
            mutable VectorX<Scalar> corrector_buffer;
            mutable SparseMatrix I_H_transpose_S_inv;
        };
    }
}

namespace crest
{
    template <typename Scalar>
    class AmgCorrectorSolver : public CorrectorSolver<Scalar>
    {
    public:
        virtual std::vector<Eigen::Triplet<Scalar>> resolve_element_correctors_for_patch(
                const BiscaleMesh<Scalar, int> & mesh,
                const std::vector<int> & coarse_patch_interior,
                const std::vector<int> & fine_patch_interior,
                const Eigen::SparseMatrix<Scalar> & global_coarse_stiffness,
                const Eigen::SparseMatrix<Scalar> & global_fine_stiffness,
                const Eigen::SparseMatrix<Scalar> & global_quasi_interpolator,
                int coarse_element) const override
        {
            // We actually DON'T want to use multiple threads in this instance,
            // in order to get a fair comparison with other schemes.
#ifdef _OPENMP
            const auto num_threads = omp_get_max_threads();
            omp_set_num_threads(1);
#endif

            typedef Eigen::SparseMatrix<Scalar, Eigen::RowMajor> RowMajorMatrix;
            const RowMajorMatrix I_H = sparse_submatrix(global_quasi_interpolator,
                                                        coarse_patch_interior,
                                                        fine_patch_interior);
            const RowMajorMatrix A_h = sparse_submatrix(global_fine_stiffness,
                                                        fine_patch_interior,
                                                        fine_patch_interior);
            const RowMajorMatrix A_H = sparse_submatrix(global_coarse_stiffness,
                                                        coarse_patch_interior,
                                                        coarse_patch_interior);

            assert(A_h.rows() > 0);
            const auto m = I_H.rows();

            typedef amgcl::backend::eigen<Scalar> Backend;

            typedef amgcl::amg<
                    Backend,
                    amgcl::coarsening::smoothed_aggregation,
                    amgcl::relaxation::spai0
            > StiffnessPreconditioner;

            typedef detail::CorrectorBlockPreconditioner<Scalar, StiffnessPreconditioner> BlockPreconditioner;
            typedef amgcl::solver::lgmres<Backend> IterativeSolver;
            typedef amgcl::make_solver<BlockPreconditioner, IterativeSolver> Solver;

            std::vector<Eigen::Triplet<Scalar>> triplets;

            detail::CorrectorBlockMatrix<Scalar> C(std::move(A_h), std::move(I_H));

            typename Solver::params params;
            params.precond.schur_inverse_approx = &A_H;
//            params.precond.stiffness_precond_params.coarse_enough = 1000;
            // TODO: Make parameters configurable
//            params.solver.tol = 1e-9; //std::numeric_limits<Scalar>::epsilon();
            params.solver.tol = std::numeric_limits<Scalar>::epsilon();
            params.solver.pside = amgcl::precond::right;
            params.solver.always_reset = true;
            params.solver.store_Av = false;
            Solver solver(C, params);

            for (int i = 0; i < 3; ++i)
            {
                const auto b = this->local_rhs(mesh, fine_patch_interior, coarse_element, i);

                VectorX<Scalar> sol(C.rows());
                sol.setZero();

                VectorX<Scalar> rhs(C.rows());
                rhs << b, VectorX<Scalar>::Zero(m);

                int    iters;
                double error;
                boost::tie(iters, error) = solver(rhs, sol);

                const auto global_index = mesh.coarse_mesh().elements()[coarse_element].vertex_indices[i];
                for (size_t k = 0; k < fine_patch_interior.size(); ++k)
                {
                    const auto component = sol(k);
                    // Due to rounding issues, some components that should perhaps be zero in exact arithmetic
                    // may be non-zero, and as such we might end up with a denser matrix than we should actually
                    // have. To prevent this, we introduce a threshold which determines whether to keep the entry.
                    // TODO: Make this threshold configurable?
                    if (std::abs(component) > 1e-12)
                    {
                        triplets.emplace_back(Eigen::Triplet<Scalar>(global_index, fine_patch_interior[k], component));
                    }
                }
            }

            // It's crucical that we restore the number of threads used by OpenMP upon exit. Note that this
            // isn't exception safe (would have to use some RAII wrapper instead).
#ifdef _OPENMP
            omp_set_num_threads(num_threads);
#endif

            return triplets;
        }
    };
}

namespace amgcl
{
    namespace backend
    {

        template <typename Scalar>
        struct rows_impl<::crest::detail::CorrectorBlockMatrix<Scalar>>
        {
            static size_t get(const ::crest::detail::CorrectorBlockMatrix<Scalar> &matrix) {
                return matrix.rows();
            }
        };

        template < class Alpha, class V1, class Beta, class V2, typename Scalar>
        struct spmv_impl<
                Alpha, ::crest::detail::CorrectorBlockMatrix<Scalar>, V1, Beta, V2,
                typename boost::enable_if<
                        typename boost::mpl::and_<
                                typename is_eigen_type<V1>::type,
                                typename is_eigen_type<V2>::type
                        >::type
                >::type
        >
        {
            static void apply(Alpha alpha, const ::crest::detail::CorrectorBlockMatrix<Scalar> &mat, const V1 &x, Beta beta, V2 &y)
            {
                const auto & A = mat.stiffness();
                const auto & I_H = mat.quasi_interpolator();
                const auto n = A.rows();
                const auto m = I_H.rows();

                if (!math::is_zero(beta))
                {
                    y = beta * y;
                    y.topRows(n) += alpha * A * x.topRows(n) + alpha * I_H.transpose() * x.bottomRows(m);
                    y.bottomRows(m) += alpha * I_H * x.topRows(n);
                } else
                {
                    // mat * x
                    y.topRows(n) = alpha * A * x.topRows(n) + alpha * I_H.transpose() * x.bottomRows(m);
                    y.bottomRows(m) = alpha * I_H * x.topRows(n);
                }
            }
        };

        template < class V1, class V2, class V3, typename Scalar >
        struct residual_impl<
                ::crest::detail::CorrectorBlockMatrix<Scalar>, V1, V2, V3,
                typename boost::enable_if<
                        typename boost::mpl::and_<
                                typename is_eigen_type<V1>::type,
                                typename is_eigen_type<V2>::type,
                                typename is_eigen_type<V3>::type
                        >::type
                >::type
        >
        {
            static void apply(const V1 &rhs, const ::crest::detail::CorrectorBlockMatrix<Scalar> &A, const V2 &x, V3 &r)
            {
                // Let r = Ax
                backend::spmv(1.0, A, x, 0, r);
                // Adjust r so that r = rhs - Ax
                r = rhs - r;
            }
        };

        template <typename Scalar>
        struct value_type<::crest::detail::CorrectorBlockMatrix<Scalar>, void>
        {
            typedef Scalar type;
        };
    }
}
<|endoftext|>


<commit_before>// RUN: cat %s | %cling -Xclang -verify | FileCheck %s

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/StoredValueRef.h"

cling::StoredValueRef V;
V // CHECK: (cling::StoredValueRef) <<<invalid>>> @0x{{.*}}

gCling->evaluate("return 1;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int) 1]

long LongV = 17;
gCling->evaluate("LongV;", V);
V // CHECK: (cling::StoredValueRef) boxes [(long) 17]

int* IntP = (int*)0x12;
gCling->evaluate("IntP;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

cling::StoredValueRef Result;
gCling->evaluate("V", Result);
// Here we check what happens for record type like cling::StoredValueRef; they are returned by reference.
Result // CHECK: (cling::StoredValueRef) boxes [(cling::StoredValueRef &) &0x{{.*}}]
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

// Savannah #96277
gCling->evaluate("gCling->declare(\"double sin(double);\"); double one = sin(3.141/2);", V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]

gCling->process("double one = sin(3.141/2);", &V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]
one // CHECK: (double) 1.000
int one; // expected-error {{redefinition of 'one' with a different type: 'int' vs 'double'}} expected-note {{previous definition is here}}

// Make sure that PR#98434 doesn't get reintroduced.
.rawInput
void f(int) { return; }
.rawInput

gCling->evaluate("f", V);
V.isValid() //CHECK: {{\([_]B|b}}ool) true
// end PR#98434

// Check lifetime of objects in StoredValue
.rawInput 1
struct WithDtor {
   static int fgCount;
   WithDtor() { ++fgCount; }
   WithDtor(const WithDtor&) { ++fgCount; }
   ~WithDtor() { --fgCount; }
};
int WithDtor::fgCount = 0;
WithDtor getWithDtor() { return WithDtor(); }
#include <vector>
std::vector<WithDtor> getWithDtorVec() { std::vector<WithDtor> ret; ret.resize(7); return ret; }
.rawInput 0

cling::StoredValueRef* VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtor()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(WithDtor) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 1
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0

// Check destructor call for templates
VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtorVec()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(std::vector<WithDtor>) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 7
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0
<commit_msg>Aggregate returns do not work on 32bit; see ROOT-5860.<commit_after>// RUN: cat %s | %cling -Xclang -verify | FileCheck %s
// XFAIL: i686, i386
// due to aggregate return in getWithDtor(); see ROOT-5860

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/StoredValueRef.h"

cling::StoredValueRef V;
V // CHECK: (cling::StoredValueRef) <<<invalid>>> @0x{{.*}}

gCling->evaluate("return 1;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int) 1]

long LongV = 17;
gCling->evaluate("LongV;", V);
V // CHECK: (cling::StoredValueRef) boxes [(long) 17]

int* IntP = (int*)0x12;
gCling->evaluate("IntP;", V);
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

cling::StoredValueRef Result;
gCling->evaluate("V", Result);
// Here we check what happens for record type like cling::StoredValueRef; they are returned by reference.
Result // CHECK: (cling::StoredValueRef) boxes [(cling::StoredValueRef &) &0x{{.*}}]
V // CHECK: (cling::StoredValueRef) boxes [(int *) 0x12]

// Savannah #96277
gCling->evaluate("gCling->declare(\"double sin(double);\"); double one = sin(3.141/2);", V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]

gCling->process("double one = sin(3.141/2);", &V);
V // CHECK: (cling::StoredValueRef) boxes [(double) 1.000000e+00]
one // CHECK: (double) 1.000
int one; // expected-error {{redefinition of 'one' with a different type: 'int' vs 'double'}} expected-note {{previous definition is here}}

// Make sure that PR#98434 doesn't get reintroduced.
.rawInput
void f(int) { return; }
.rawInput

gCling->evaluate("f", V);
V.isValid() //CHECK: {{\([_]B|b}}ool) true
// end PR#98434

// Check lifetime of objects in StoredValue
.rawInput 1
struct WithDtor {
   static int fgCount;
   WithDtor() { ++fgCount; }
   WithDtor(const WithDtor&) { ++fgCount; }
   ~WithDtor() { --fgCount; }
};
int WithDtor::fgCount = 0;
WithDtor getWithDtor() { return WithDtor(); }
#include <vector>
std::vector<WithDtor> getWithDtorVec() { std::vector<WithDtor> ret; ret.resize(7); return ret; }
.rawInput 0

cling::StoredValueRef* VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtor()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(WithDtor) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 1
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0

// Check destructor call for templates
VOnHeap = new cling::StoredValueRef();
gCling->evaluate("getWithDtorVec()", *VOnHeap);
*VOnHeap //CHECK: (cling::StoredValueRef) boxes [(std::vector<WithDtor>) @0x{{.*}}]
WithDtor::fgCount //CHECK: (int) 7
delete VOnHeap;
WithDtor::fgCount //CHECK: (int) 0
<|endoftext|>


<commit_before>#ifndef OROGEN_<%= typekit.name %>_OPAQUE_FWD_HPP
#define OROGEN_<%= typekit.name %>_OPAQUE_FWD_HPP

<% opaque_types             = type_sets.opaque_types.find_all { |op| !op.generate_templates? } %>
<% types_containing_opaques = type_sets.types.find_all { |t| t.contains_opaques? && !t.opaque? } %>
<% all_types = opaque_types.map { |op| op.type } + types_containing_opaques %>
<% all_types.dup.each do |type|
       all_types << typekit.intermediate_type_for(type)
   end
   templates, classes = all_types.partition do |type|
       type.name =~ /</
   end
%>

<%= template_includes = templates.inject(Set.new) do |all, type|
       all |= typekit.include_for_type(type).to_set
    end
    typekit.cxx_gen_includes(*template_includes)
%>

<% current_namespace = '/' %>
<% classes.sort_by(&:name).each do |type| %>
<% while type.respond_to?(:deference) %>
<%     type = type.deference %>
<% end %>
<%= Orocos::Generation.adapt_namespace(current_namespace, type.namespace) %>
<%     current_namespace = type.namespace %>
class <%= type.basename %>;
<% end %>
<%= Orocos::Generation.adapt_namespace(current_namespace, '/') %>

#endif

<commit_msg>gen: fix some corner-cases in forward declaration generation<commit_after>#ifndef OROGEN_<%= typekit.name %>_OPAQUE_FWD_HPP
#define OROGEN_<%= typekit.name %>_OPAQUE_FWD_HPP

<% opaque_types             = type_sets.opaque_types.find_all { |op| !op.generate_templates? } %>
<% types_containing_opaques = type_sets.types.find_all { |t| t.contains_opaques? && !t.opaque? } %>
<% all_types = opaque_types.map { |op| op.type } + types_containing_opaques
   all_types.dup.each do |type|
       all_types << typekit.intermediate_type_for(type)
   end
   all_types.map! do |type|
       if type <= Typelib::ArrayType
           while type.respond_to?(:deference)
               type = type.deference
           end
       end
       type
   end
   need_full_definition, forward_declared = all_types.partition do |type|
       type.name =~ /</ || (type.opaque? && type.metadata.get('opaque_is_typedef').include?('1'))
   end
%>

<%= includes = need_full_definition.inject(Set.new) do |all, type|
       all |= typekit.include_for_type(type).to_set
    end
    typekit.cxx_gen_includes(*includes)
%>

<% current_namespace = '/' %>
<% forward_declared.sort_by(&:name).each do |type| %>
<%= Orocos::Generation.adapt_namespace(current_namespace, type.namespace) %>
<%     current_namespace = type.namespace %>
class <%= type.basename %>;
<% end %>
<%= Orocos::Generation.adapt_namespace(current_namespace, '/') %>

#endif

<|endoftext|>


<commit_before>/*
 * libcpu: i386_decoder.cpp
 */

#include <llvm/MC/MCAsmInfo.h>
#include <llvm/MC/MCDisassembler.h>
#include <llvm/MC/MCInst.h>
#include <llvm/MC/MCInstPrinter.h>
#include <llvm/MC/MCRegisterInfo.h>
#include <llvm/MC/MCSubtargetInfo.h>
#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Support/MemoryObject.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>

#include "i386_arch.h"

static const MCDisassembler *DisAsm = NULL;
static MCInstPrinter *InstPrinter = NULL;
static const MCInstrInfo *InstInfo = NULL;

/*
// A subclass of LLVM's MemoryObject that wraps a pointer as an unbounded array
// of bytes.
//
// When we have an MCDisassembler object, we'll point it into this MemoryObject
// to decode an instruction.
*/
namespace {
	class DirectMemoryObject : public MemoryObject {
	private:
		const uint8_t *Bytes;
	public:
		DirectMemoryObject(const uint8_t *bytes) : Bytes(bytes) {}

		uint64_t getBase() const { return 0; }
		uint64_t getExtent() const { return 0; }

		int readByte(uint64_t Addr, uint8_t *Byte) const {
			*Byte = Bytes[Addr];
			return 0;
		}
	};
}

/*
// Initializes our global disassembler and printer.
// Largely ripped out of llvm-mc.
*/
static void InitializeGlobals()
{
	// Initialize the X86 disassembler
	LLVMInitializeX86Disassembler();

	// We need to make a target triple for i386
	Triple triple(sys::getDefaultTargetTriple());
	triple.setArch(Triple::getArchTypeForLLVMName("x86"));

	// Look up this target in LLVM's registry
	std::string Err;
	const Target *T = TargetRegistry::lookupTarget(triple.getTriple(), Err);
	if (!T)
	{
		errs() << "Failed to get target for " << triple.getTriple() << "\n";
		abort();
	}

	OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(triple.getTriple()));
	if (!AsmInfo) {
		errs() << "Failed to get target for target\n";
		abort();
	}

	OwningPtr<const MCSubtargetInfo> STI(T->createMCSubtargetInfo(triple.getTriple(), "", ""));
	if (!STI) {
		errs() << "Failed to get subtarget for target\n";
		abort();
	}

	DisAsm = T->createMCDisassembler(*STI);
	if (!DisAsm) {
		errs() << "Failed to get disassembler for target\n";
		abort();
	}

	OwningPtr<const MCRegisterInfo> MRI(T->createMCRegInfo(triple.getTriple()));
	if (!MRI) {
		errs() << "Failed to get register info for target\n";
		abort();
	}

	InstInfo = (T->createMCInstrInfo());
	if (!InstInfo) {
		errs() << "Failed to get instruction info for target\n";
		abort();
	}

	int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
	InstPrinter = T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo,
		                                 *InstInfo, *MRI, *STI);
	if (!InstPrinter) {
		errs() << "Failed to get instruction printer for target\n";
		abort();
	}
}

/*
// Vends a shared MCDisassembler object.
*/
static const MCDisassembler *GetDisassembler()
{
	if (!DisAsm)
		InitializeGlobals();

	return DisAsm;
}

/*
// Vends a shared MCInstPrinter object.
*/
static MCInstPrinter *GetInstPrinter()
{
	if (!InstPrinter)
		InitializeGlobals();

	return InstPrinter;
}

/*
// Decodes one instruction from the buffer.
*/
MCInst DecodeInstruction(cpu_t *cpu, addr_t pc, uint64_t *_size)
{
	uint64_t size = 0;
	uint64_t index = pc;
	MCInst insn;

	// Decode the instruction
	DirectMemoryObject memoryObject(cpu->RAM);

	MCDisassembler::DecodeStatus S;
    S = GetDisassembler()->getInstruction(insn, size, memoryObject, index,
                                          nulls(), nulls());

	switch (S)
	{
		case MCDisassembler::Fail:
			errs() << "Warning: Invalid instruction encoding\n";
			if (size == 0)
				size = 1;
			break;

		case MCDisassembler::SoftFail:
			errs() << "Warning: Potentially undefined instruction encoding\n";
			// Fall through

		case MCDisassembler::Success:
			break;
	}

	if (_size)
		*_size = size;

	return insn;
}

/*
// Returns an MCInstrDesc for the given opcode.
*/
const MCInstrDesc &DescForInst(const MCInst &insn)
{
	if (!InstInfo)
		InitializeGlobals();

	return InstInfo->get(insn.getOpcode());
}

/*
// Returns an MCInstInfo instance.
*/
const MCInstrInfo *GetInstInfo()
{
	if (!InstInfo)
		InitializeGlobals();

	return InstInfo;
}

/*
// Returns a human-readable version of the instruction.
*/
std::string DisasmInstruction(MCInst insn)
{
	std::string output;
	raw_string_ostream sos(output);
	GetInstPrinter()->printInst(&insn, sos, "");
	return sos.str();
}

int arch_i386_disasm_instr(cpu_t *cpu, addr_t pc, char *line, unsigned int max_line)
{
	uint64_t size;
	MCInst insn = DecodeInstruction(cpu, pc, &size);
	strlcpy(line, DisasmInstruction(insn).c_str(), max_line);
	return size;
}
<commit_msg>fix build<commit_after>/*
 * libcpu: i386_decoder.cpp
 */

#include <llvm/MC/MCAsmInfo.h>
#include <llvm/MC/MCDisassembler.h>
#include <llvm/MC/MCInst.h>
#include <llvm/MC/MCInstPrinter.h>
#include <llvm/MC/MCRegisterInfo.h>
#include <llvm/MC/MCSubtargetInfo.h>
#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Support/MemoryObject.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/TargetRegistry.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>

#include "i386_arch.h"

static const MCDisassembler *DisAsm = NULL;
static MCInstPrinter *InstPrinter = NULL;
static const MCInstrInfo *InstInfo = NULL;

/*
// A subclass of LLVM's MemoryObject that wraps a pointer as an unbounded array
// of bytes.
//
// When we have an MCDisassembler object, we'll point it into this MemoryObject
// to decode an instruction.
*/
namespace {
	class DirectMemoryObject : public MemoryObject {
	private:
		const uint8_t *Bytes;
	public:
		DirectMemoryObject(const uint8_t *bytes) : Bytes(bytes) {}

		uint64_t getBase() const { return 0; }
		uint64_t getExtent() const { return 0; }

		int readByte(uint64_t Addr, uint8_t *Byte) const {
			*Byte = Bytes[Addr];
			return 0;
		}
	};
}

/*
// Initializes our global disassembler and printer.
// Largely ripped out of llvm-mc.
*/
static void InitializeGlobals()
{
	// Initialize the X86 disassembler
	LLVMInitializeX86Disassembler();

	// We need to make a target triple for i386
	Triple triple(sys::getDefaultTargetTriple());
	triple.setArch(Triple::getArchTypeForLLVMName("x86"));

	// Look up this target in LLVM's registry
	std::string Err;
	const Target *T = TargetRegistry::lookupTarget(triple.getTriple(), Err);
	if (!T)
	{
		errs() << "Failed to get target for " << triple.getTriple() << "\n";
		abort();
	}

	OwningPtr<const MCRegisterInfo> MRI(T->createMCRegInfo(triple.getTriple()));
	if (!MRI) {
		errs() << "Failed to get register info for target\n";
		abort();
	}

	OwningPtr<const MCAsmInfo> AsmInfo(T->createMCAsmInfo(*T->createMCRegInfo(triple.getTriple()), triple.getTriple()));
	if (!AsmInfo) {
		errs() << "Failed to get target for target\n";
		abort();
	}

	OwningPtr<const MCSubtargetInfo> STI(T->createMCSubtargetInfo(triple.getTriple(), "", ""));
	if (!STI) {
		errs() << "Failed to get subtarget for target\n";
		abort();
	}

	DisAsm = T->createMCDisassembler(*STI);
	if (!DisAsm) {
		errs() << "Failed to get disassembler for target\n";
		abort();
	}

	InstInfo = (T->createMCInstrInfo());
	if (!InstInfo) {
		errs() << "Failed to get instruction info for target\n";
		abort();
	}

	int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
	InstPrinter = T->createMCInstPrinter(AsmPrinterVariant, *AsmInfo,
		                                 *InstInfo, *MRI, *STI);
	if (!InstPrinter) {
		errs() << "Failed to get instruction printer for target\n";
		abort();
	}
}

/*
// Vends a shared MCDisassembler object.
*/
static const MCDisassembler *GetDisassembler()
{
	if (!DisAsm)
		InitializeGlobals();

	return DisAsm;
}

/*
// Vends a shared MCInstPrinter object.
*/
static MCInstPrinter *GetInstPrinter()
{
	if (!InstPrinter)
		InitializeGlobals();

	return InstPrinter;
}

/*
// Decodes one instruction from the buffer.
*/
MCInst DecodeInstruction(cpu_t *cpu, addr_t pc, uint64_t *_size)
{
	uint64_t size = 0;
	uint64_t index = pc;
	MCInst insn;

	// Decode the instruction
	DirectMemoryObject memoryObject(cpu->RAM);

	MCDisassembler::DecodeStatus S;
    S = GetDisassembler()->getInstruction(insn, size, memoryObject, index,
                                          nulls(), nulls());

	switch (S)
	{
		case MCDisassembler::Fail:
			errs() << "Warning: Invalid instruction encoding\n";
			if (size == 0)
				size = 1;
			break;

		case MCDisassembler::SoftFail:
			errs() << "Warning: Potentially undefined instruction encoding\n";
			// Fall through

		case MCDisassembler::Success:
			break;
	}

	if (_size)
		*_size = size;

	return insn;
}

/*
// Returns an MCInstrDesc for the given opcode.
*/
const MCInstrDesc &DescForInst(const MCInst &insn)
{
	if (!InstInfo)
		InitializeGlobals();

	return InstInfo->get(insn.getOpcode());
}

/*
// Returns an MCInstInfo instance.
*/
const MCInstrInfo *GetInstInfo()
{
	if (!InstInfo)
		InitializeGlobals();

	return InstInfo;
}

/*
// Returns a human-readable version of the instruction.
*/
std::string DisasmInstruction(MCInst insn)
{
	std::string output;
	raw_string_ostream sos(output);
	GetInstPrinter()->printInst(&insn, sos, "");
	return sos.str();
}

int arch_i386_disasm_instr(cpu_t *cpu, addr_t pc, char *line, unsigned int max_line)
{
	uint64_t size;
	MCInst insn = DecodeInstruction(cpu, pc, &size);
	strlcpy(line, DisasmInstruction(insn).c_str(), max_line);
	return size;
}
<|endoftext|>


<commit_before>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkContourVtkMapper3D.h"
#include "mitkDataTreeNode.h"
#include "mitkProperties.h"
#include "mitkColorProperty.h"
#include "mitkOpenGLRenderer.h"

#include <vtkActor.h>
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkAppendPolyData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkFollower.h>
#include <vtkAssembly.h>
#include <vtkProp3DCollection.h>
#include <vtkRenderer.h>
#include <vtkTransform.h>
#include <vtkTubeFilter.h>
#include <vtkPolygon.h>

#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <stdlib.h>

mitk::ContourVtkMapper3D::ContourVtkMapper3D()
{
    m_VtkPolyDataMapper = vtkPolyDataMapper::New();
    m_Actor = vtkActor::New();
    m_Actor->SetMapper(m_VtkPolyDataMapper);

    m_Contour = vtkPolyData::New();
 	  m_TubeFilter = vtkTubeFilter::New();

}

mitk::ContourVtkMapper3D::~ContourVtkMapper3D()
{
    m_VtkPolyDataMapper->Delete();
    m_Actor->Delete();
}

void mitk::ContourVtkMapper3D::GenerateData(mitk::BaseRenderer* renderer)
{
    if(IsVisible(renderer)==false)
    {
        m_Actor->VisibilityOff();
        return;
    }
    m_Actor->VisibilityOn();

		m_Contour = vtkPolyData::New();

    mitk::Contour::Pointer input  = const_cast<mitk::Contour*>(this->GetInput());
		bool makeContour = true;

    if (makeContour)
		{
		  vtkPolyData *m_Contour = vtkPolyData::New();
		  vtkPoints *points = vtkPoints::New();
		  vtkCellArray *lines = vtkCellArray::New();

      Contour::InputType idx = input->GetContourPath()->StartOfInput();

      Contour::InputType end = input->GetContourPath()->EndOfInput();
      if (end > 50000) end = 0;
      vtkIdType ptIndex = 0;
      vtkIdType lastPointIndex = 0;

      mitk::Contour::PointsContainerPointer contourPoints = input->GetPoints();
      mitk::Contour::PointsContainerIterator pointsIt = contourPoints->Begin();
      unsigned int counter = 0;

      while ( pointsIt != contourPoints->End() )
      {
        if (counter %2 == 0)
        {
          Contour::BoundingBoxType::PointType point;
          point = pointsIt.Value();
          points->InsertPoint(ptIndex, point[0],point[1],point[2]);
          if (ptIndex>0)
          {
            int cell[2] = {ptIndex-1,ptIndex};
            lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell);
         }
          lastPointIndex = ptIndex;
          ptIndex++;
        }
        counter++;
        pointsIt++;
        idx+=5;
			}

      if (input->GetClosed())
      {
        int cell[2] = {lastPointIndex,0};
        lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell);
      }

			m_Contour->SetPoints(points);
	//	  points->Delete();
  		m_Contour->SetLines(lines);
			m_Contour->Update();

		  m_TubeFilter->SetInput(m_Contour);
		  m_TubeFilter->SetRadius(1);
      m_TubeFilter->Update();
      m_VtkPolyDataMapper->SetInput(m_TubeFilter->GetOutput());
      float rgba[4]={0.0f,1.0f,0.0f,0.6f};
      m_Actor->GetProperty()->SetColor(rgba);
      m_Actor->SetMapper(m_VtkPolyDataMapper);
    }
}

vtkProp* mitk::ContourVtkMapper3D::GetProp()
{
  return m_Actor;
}

const mitk::Contour* mitk::ContourVtkMapper3D::GetInput()
{
    return static_cast<const mitk::Contour* > ( GetData() );
}
<commit_msg>ENH: subsampling strategy<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
Module:    $RCSfile$
Language:  C++
Date:      $Date$
Version:   $Revision$

Copyright (c) German Cancer Research Center, Division of Medical and
Biological Informatics. All rights reserved.
See MITKCopyright.txt or http://www.mitk.org/copyright.html for details.

This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.  See the above copyright notices for more information.

=========================================================================*/

#include "mitkContourVtkMapper3D.h"
#include "mitkDataTreeNode.h"
#include "mitkProperties.h"
#include "mitkColorProperty.h"
#include "mitkOpenGLRenderer.h"

#include <vtkActor.h>
#include <vtkActor.h>
#include <vtkCellArray.h>
#include <vtkAppendPolyData.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkFollower.h>
#include <vtkAssembly.h>
#include <vtkProp3DCollection.h>
#include <vtkRenderer.h>
#include <vtkTransform.h>
#include <vtkTubeFilter.h>
#include <vtkPolygon.h>

#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <stdlib.h>

mitk::ContourVtkMapper3D::ContourVtkMapper3D()
{
    m_VtkPolyDataMapper = vtkPolyDataMapper::New();
    m_Actor = vtkActor::New();
    m_Actor->SetMapper(m_VtkPolyDataMapper);

    m_Contour = NULL;
 	  m_TubeFilter = vtkTubeFilter::New();
}

mitk::ContourVtkMapper3D::~ContourVtkMapper3D()
{
    m_VtkPolyDataMapper->Delete();
    m_Actor->Delete();
    if(m_Contour!=NULL)
      m_Contour->Delete();
}

void mitk::ContourVtkMapper3D::GenerateData(mitk::BaseRenderer* renderer)
{
    if(IsVisible(renderer)==false)
    {
        m_Actor->VisibilityOff();
        return;
    }
    m_Actor->VisibilityOn();

    if(m_Contour!=NULL)
      m_Contour->Delete();

		m_Contour = vtkPolyData::New();

    mitk::Contour::Pointer input  = const_cast<mitk::Contour*>(this->GetInput());
		bool makeContour = true;

    if (makeContour)
		{
		  vtkPoints *points = vtkPoints::New();
		  vtkCellArray *lines = vtkCellArray::New();

      int numPts=input->GetNumberOfPoints();
      if(numPts>20)
        numPts = 20;
      mitk::Contour::PathPointer path = input->GetContourPath();
      mitk::Contour::PathType::InputType cstart = path->StartOfInput();
      mitk::Contour::PathType::InputType cend   = path->EndOfInput();
      mitk::Contour::PathType::InputType cstep  = (cend-cstart+1)/numPts;
      mitk::Contour::PathType::InputType ccur;

      vtkIdType ptIndex = 0;
      vtkIdType lastPointIndex = 0;

      mitk::Contour::PointsContainerPointer contourPoints = input->GetPoints();
      mitk::Contour::PointsContainerIterator pointsIt = contourPoints->Begin();

      float vtkpoint[3];
      unsigned int i;
      for(i=0, ccur=cstart; i<numPts; ++i, ccur+=cstep)
      {
          itk2vtk(path->Evaluate(ccur), vtkpoint);
          points->InsertPoint(ptIndex, vtkpoint);
          if (ptIndex>0)
          {
            int cell[2] = {ptIndex-1,ptIndex};
            lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell);
          }
          lastPointIndex = ptIndex;
          ptIndex++;
			}

      if (input->GetClosed())
      {
        int cell[2] = {lastPointIndex,0};
        lines->InsertNextCell((vtkIdType)2,(vtkIdType*) cell);
      }

			m_Contour->SetPoints(points);
		  points->Delete();
  		m_Contour->SetLines(lines);
			m_Contour->Update();

		  m_TubeFilter->SetInput(m_Contour);
		  m_TubeFilter->SetRadius(1);
      m_TubeFilter->Update();
      m_VtkPolyDataMapper->SetInput(m_TubeFilter->GetOutput());
      float rgba[4]={0.0f,1.0f,0.0f,0.6f};
      m_Actor->GetProperty()->SetColor(rgba);
      m_Actor->SetMapper(m_VtkPolyDataMapper);
    }
}

vtkProp* mitk::ContourVtkMapper3D::GetProp()
{
  return m_Actor;
}

const mitk::Contour* mitk::ContourVtkMapper3D::GetInput()
{
    return static_cast<const mitk::Contour* > ( GetData() );
}
<|endoftext|>


<commit_before>#include "mitkPolyDataGLMapper2D.h"

#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkSurfaceData.h"
#include "mitkColorProperty.h"
#include "mitkFloatProperty.h"
#include "mitkBoolProperty.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkBaseVtkMapper3D.h"

#include <vtkPolyData.h>
#include <vtkPolyDataSource.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkPolyData.h>
#include <vtkTransform.h>
#include <vtkLinearTransform.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkScalarsToColors.h>

#include <itkProcessObject.h>

const mitk::BaseData *mitk::PolyDataGLMapper2D::GetInput( void )
{
    if ( this->GetNumberOfInputs() < 1 )
    {
        return 0;
    }

    return dynamic_cast<const mitk::BaseData * > ( GetData() );
}

void mitk::PolyDataGLMapper2D::Paint( mitk::BaseRenderer * renderer )
{
    if ( IsVisible( renderer ) == false )
        return ;

    // ok, das ist aus GenerateData kopiert
    mitk::BaseData::Pointer input = const_cast<mitk::BaseData*>( this->GetInput() );

    assert( input );

    input->Update();

    vtkPolyData * vtkpolydata = this->GetVtkPolyData();
    assert( vtkpolydata );

    vtkTransform * vtktransform = GetDataTreeNode() ->GetVtkTransform();
    vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();

    Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
    PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() );

    if ( vtkpolydata != NULL )
    {
        Vector3D point;
        Vector3D normal;

        if ( worldPlaneGeometry.IsNotNull() )
        {
            // set up vtkPlane according to worldGeometry
            point = worldPlaneGeometry->GetPlaneView().point;
            normal = worldPlaneGeometry->GetPlaneView().normal;
            normal.normalize();
            m_Plane->SetTransform( NULL );
        }
        else
        {
            //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"?
            return ;
            AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>( renderer->GetCurrentWorldGeometry2D() );
            if ( worldAbstractGeometry.IsNotNull() )
            {
                // set up vtkPlane according to worldGeometry
                point = worldAbstractGeometry->GetPlaneView().point;
                normal = worldAbstractGeometry->GetPlaneView().normal;
                normal.normalize();
                m_Plane->SetTransform( worldAbstractGeometry->GetVtkAbstractTransform() ->GetInverse() );
            }
            else
                return ;
        }

        float vp[ 3 ], vnormal[ 3 ];
        vec2vtk( point, vp );
        vec2vtk( normal, vnormal );

        //normally, we would need to transform the surface and cut the transformed surface with the cutter.
        //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
        //@todo It probably does not work for scaling operations yet:scaling operations have to be
        //dealed with after the cut is performed by scaling the contour.
        inversetransform->TransformPoint( vp, vp );
        inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal );

        m_Plane->SetOrigin( vp );
        m_Plane->SetNormal( vnormal );

        // set data into cutter
        m_Cutter->SetInput( vtkpolydata );
        //    m_Cutter->GenerateCutScalarsOff();
        //    m_Cutter->SetSortByToSortByCell();

        // calculate the cut
        m_Cutter->Update();

        // fetch geometry
        mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
        assert( displayGeometry );
        //  float toGL=displayGeometry->GetSizeInDisplayUnits().y;

        //apply color and opacity read from the PropertyList
        ApplyProperties( renderer );

        // traverse the cut contour
        vtkPolyData * contour = m_Cutter->GetOutput();

        vtkPoints *vpoints = contour->GetPoints();
        vtkCellArray *vpolys = contour->GetLines();
        vtkPointData *vpointdata = contour->GetPointData();
        vtkDataArray* vscalars = vpointdata->GetScalars();

        vtkCellData *vcelldata = contour->GetCellData();
        vtkDataArray* vcellscalars = vcelldata->GetScalars();

        int i, numberOfCells = vpolys->GetNumberOfCells();

        Point3D p;
        Point2D p2d, last, first;

        vpolys->InitTraversal();
        vtkScalarsToColors* lut = GetVtkLUT();
        assert ( lut != NULL );

        for ( i = 0;i < numberOfCells;++i )
        {
            int *cell, cellSize;

            vpolys->GetNextCell( cellSize, cell );

            if ( m_ColorByCellData )
            {  // color each cell according to cell data
                float * color = lut->GetColor( vcellscalars->GetComponent( i, 0 ) );
                glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
            }
            else if ( m_ColorByPointData )
            {
                float* color = lut->GetColor( vscalars->GetComponent( i, 0 ) );
                glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
            }

            glBegin ( GL_LINE_LOOP );
            for ( int j = 0;j < cellSize;++j )
            {
                vpoints->GetPoint( cell[ j ], vp );
                //take transformation via vtktransform into account
                vtktransform->TransformPoint( vp, vp );

                vtk2vec( vp, p );

                //convert 3D point (in mm) to 2D point on slice (also in mm)
                worldGeometry->Map( p, p2d );

                //convert point (until now mm and in worldcoordinates) to display coordinates (units )
                displayGeometry->MMToDisplay( p2d, p2d );

                //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left )
                //p2d.y=toGL-p2d.y;

                //add the current vertex to the line
                glVertex2f( p2d.x, p2d.y );
            }
            glEnd ();
        }
    }
}

vtkPolyDataMapper* mitk::PolyDataGLMapper2D::GetVtkPolyDataMapper()
{
    mitk::DataTreeNode::Pointer node = this->GetDataTreeNode();
    if ( node.IsNull() )
        return NULL;

    mitk::BaseVtkMapper3D::Pointer mitkMapper = dynamic_cast< mitk::BaseVtkMapper3D* > ( node->GetMapper( 2 ) );
    if ( mitkMapper.IsNull() )
        return NULL;

    ( ( itk::ProcessObject* ) mitkMapper.GetPointer() ) ->Update();

    vtkActor* actor = dynamic_cast<vtkActor*>( mitkMapper->GetProp() );

    if ( actor == NULL )
        return NULL;

    return dynamic_cast<vtkPolyDataMapper*>( actor->GetMapper() );
}

vtkPolyData* mitk::PolyDataGLMapper2D::GetVtkPolyData( )
{
    vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper();
    if ( polyDataMapper == NULL )
        return NULL;
    else
        return polyDataMapper->GetInput();
}

vtkScalarsToColors* mitk::PolyDataGLMapper2D::GetVtkLUT( )
{
    vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper();
    if ( polyDataMapper == NULL )
        return NULL;
    else
        return polyDataMapper->GetLookupTable();
}

bool mitk::PolyDataGLMapper2D::IsConvertibleToVtkPolyData()
{
    return ( GetVtkPolyDataMapper() != NULL );
}

void mitk::PolyDataGLMapper2D::Update()
{}

mitk::PolyDataGLMapper2D::PolyDataGLMapper2D()
{
    m_Plane = vtkPlane::New();
    m_Cutter = vtkCutter::New();

    m_Cutter->SetCutFunction( m_Plane );
    m_Cutter->GenerateValues( 1, 0, 1 );

    m_ColorByCellData = false;
    m_ColorByPointData = false;

    //m_LUT = vtkLookupTable::New();
    //m_LUT->SetTableRange( 0, 255 );
    //m_LUT->SetNumberOfColors( 255 );
    //m_LUT->SetRampToLinear ();
    //m_LUT->Build();
}

mitk::PolyDataGLMapper2D::~PolyDataGLMapper2D()
{}

<commit_msg>Fixed bug in colouring by point data.<commit_after>#include "mitkPolyDataGLMapper2D.h"

#include "mitkBaseRenderer.h"
#include "mitkPlaneGeometry.h"
#include "mitkSurfaceData.h"
#include "mitkColorProperty.h"
#include "mitkFloatProperty.h"
#include "mitkBoolProperty.h"
#include "mitkAbstractTransformGeometry.h"
#include "mitkBaseVtkMapper3D.h"

#include <vtkPolyData.h>
#include <vtkPolyDataSource.h>
#include <vtkPlane.h>
#include <vtkCutter.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkLookupTable.h>
#include <vtkPointData.h>
#include <vtkCellData.h>
#include <vtkDataArray.h>
#include <vtkPolyData.h>
#include <vtkTransform.h>
#include <vtkLinearTransform.h>
#include <vtkActor.h>
#include <vtkPolyDataMapper.h>
#include <vtkScalarsToColors.h>

#include <itkProcessObject.h>

const mitk::BaseData *mitk::PolyDataGLMapper2D::GetInput( void )
{
    if ( this->GetNumberOfInputs() < 1 )
    {
        return 0;
    }

    return dynamic_cast<const mitk::BaseData * > ( GetData() );
}

void mitk::PolyDataGLMapper2D::Paint( mitk::BaseRenderer * renderer )
{
    if ( IsVisible( renderer ) == false )
        return ;

    // ok, das ist aus GenerateData kopiert
    mitk::BaseData::Pointer input = const_cast<mitk::BaseData*>( this->GetInput() );

    assert( input );

    input->Update();

    vtkPolyData * vtkpolydata = this->GetVtkPolyData();
    assert( vtkpolydata );

    vtkTransform * vtktransform = GetDataTreeNode() ->GetVtkTransform();
    vtkLinearTransform * inversetransform = vtktransform->GetLinearInverse();

    Geometry2D::ConstPointer worldGeometry = renderer->GetCurrentWorldGeometry2D();
    PlaneGeometry::ConstPointer worldPlaneGeometry = dynamic_cast<const PlaneGeometry*>( worldGeometry.GetPointer() );

    if ( vtkpolydata != NULL )
    {
        Vector3D point;
        Vector3D normal;

        if ( worldPlaneGeometry.IsNotNull() )
        {
            // set up vtkPlane according to worldGeometry
            point = worldPlaneGeometry->GetPlaneView().point;
            normal = worldPlaneGeometry->GetPlaneView().normal;
            normal.normalize();
            m_Plane->SetTransform( NULL );
        }
        else
        {
            //@FIXME: does not work correctly. Does m_Plane->SetTransform really transforms a "plane plane" into a "curved plane"?
            return ;
            AbstractTransformGeometry::ConstPointer worldAbstractGeometry = dynamic_cast<const AbstractTransformGeometry*>( renderer->GetCurrentWorldGeometry2D() );
            if ( worldAbstractGeometry.IsNotNull() )
            {
                // set up vtkPlane according to worldGeometry
                point = worldAbstractGeometry->GetPlaneView().point;
                normal = worldAbstractGeometry->GetPlaneView().normal;
                normal.normalize();
                m_Plane->SetTransform( worldAbstractGeometry->GetVtkAbstractTransform() ->GetInverse() );
            }
            else
                return ;
        }

        float vp[ 3 ], vnormal[ 3 ];
        vec2vtk( point, vp );
        vec2vtk( normal, vnormal );

        //normally, we would need to transform the surface and cut the transformed surface with the cutter.
        //This might be quite slow. Thus, the idea is, to perform an inverse transform of the plane instead.
        //@todo It probably does not work for scaling operations yet:scaling operations have to be
        //dealed with after the cut is performed by scaling the contour.
        inversetransform->TransformPoint( vp, vp );
        inversetransform->TransformNormalAtPoint( vp, vnormal, vnormal );

        m_Plane->SetOrigin( vp );
        m_Plane->SetNormal( vnormal );

        // set data into cutter
        m_Cutter->SetInput( vtkpolydata );
        //    m_Cutter->GenerateCutScalarsOff();
        //    m_Cutter->SetSortByToSortByCell();

        // calculate the cut
        m_Cutter->Update();

        // fetch geometry
        mitk::DisplayGeometry::Pointer displayGeometry = renderer->GetDisplayGeometry();
        assert( displayGeometry );
        //  float toGL=displayGeometry->GetSizeInDisplayUnits().y;

        //apply color and opacity read from the PropertyList
        ApplyProperties( renderer );

        // traverse the cut contour
        vtkPolyData * contour = m_Cutter->GetOutput();

        vtkPoints *vpoints = contour->GetPoints();
        vtkCellArray *vpolys = contour->GetLines();
        vtkPointData *vpointdata = contour->GetPointData();
        vtkDataArray* vscalars = vpointdata->GetScalars();

        vtkCellData *vcelldata = contour->GetCellData();
        vtkDataArray* vcellscalars = vcelldata->GetScalars();

        int i, numberOfCells = vpolys->GetNumberOfCells();

        Point3D p;
        Point2D p2d, last, first;

        vpolys->InitTraversal();
        vtkScalarsToColors* lut = GetVtkLUT();
        assert ( lut != NULL );

        for ( i = 0;i < numberOfCells;++i )
        {
            int *cell, cellSize;

            vpolys->GetNextCell( cellSize, cell );

            if ( m_ColorByCellData )
            {  // color each cell according to cell data
                float * color = lut->GetColor( vcellscalars->GetComponent( i, 0 ) );
                glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
            }
            if ( m_ColorByPointData )
            {
                float* color = lut->GetColor( vscalars->GetComponent( cell[0], 0 ) );
                glColor3f( color[ 0 ], color[ 1 ], color[ 2 ] );
            }

            glBegin ( GL_LINE_LOOP );
            for ( int j = 0;j < cellSize;++j )
            {
                vpoints->GetPoint( cell[ j ], vp );
                //take transformation via vtktransform into account
                vtktransform->TransformPoint( vp, vp );

                vtk2vec( vp, p );

                //convert 3D point (in mm) to 2D point on slice (also in mm)
                worldGeometry->Map( p, p2d );

                //convert point (until now mm and in worldcoordinates) to display coordinates (units )
                displayGeometry->MMToDisplay( p2d, p2d );

                //convert display coordinates ( (0,0) is top-left ) in GL coordinates ( (0,0) is bottom-left )
                //p2d.y=toGL-p2d.y;

                //add the current vertex to the line
                glVertex2f( p2d.x, p2d.y );
            }
            glEnd ();
        }
    }
}

vtkPolyDataMapper* mitk::PolyDataGLMapper2D::GetVtkPolyDataMapper()
{
    mitk::DataTreeNode::Pointer node = this->GetDataTreeNode();
    if ( node.IsNull() )
        return NULL;

    mitk::BaseVtkMapper3D::Pointer mitkMapper = dynamic_cast< mitk::BaseVtkMapper3D* > ( node->GetMapper( 2 ) );
    if ( mitkMapper.IsNull() )
        return NULL;

    ( ( itk::ProcessObject* ) mitkMapper.GetPointer() ) ->Update();

    vtkActor* actor = dynamic_cast<vtkActor*>( mitkMapper->GetProp() );

    if ( actor == NULL )
        return NULL;

    return dynamic_cast<vtkPolyDataMapper*>( actor->GetMapper() );
}

vtkPolyData* mitk::PolyDataGLMapper2D::GetVtkPolyData( )
{
    vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper();
    if ( polyDataMapper == NULL )
        return NULL;
    else
        return polyDataMapper->GetInput();
}

vtkScalarsToColors* mitk::PolyDataGLMapper2D::GetVtkLUT( )
{
    vtkPolyDataMapper * polyDataMapper = GetVtkPolyDataMapper();
    if ( polyDataMapper == NULL )
        return NULL;
    else
        return polyDataMapper->GetLookupTable();
}

bool mitk::PolyDataGLMapper2D::IsConvertibleToVtkPolyData()
{
    return ( GetVtkPolyDataMapper() != NULL );
}

void mitk::PolyDataGLMapper2D::Update()
{}

mitk::PolyDataGLMapper2D::PolyDataGLMapper2D()
{
    m_Plane = vtkPlane::New();
    m_Cutter = vtkCutter::New();

    m_Cutter->SetCutFunction( m_Plane );
    m_Cutter->GenerateValues( 1, 0, 1 );

    m_ColorByCellData = false;
    m_ColorByPointData = false;

    //m_LUT = vtkLookupTable::New();
    //m_LUT->SetTableRange( 0, 255 );
    //m_LUT->SetNumberOfColors( 255 );
    //m_LUT->SetRampToLinear ();
    //m_LUT->Build();
}

mitk::PolyDataGLMapper2D::~PolyDataGLMapper2D()
{}

<|endoftext|>