<commit_before>#include "RpcImageServer.h"
#include "ImageServerCfg.h"
#include "ImageProcess.h"
#include "ImageProcessTask.h"
#include <image-manager/ImageServerStorage.h>
#include <image-manager/ImageServerRequest.h>
#include "errno.h"
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <glog/logging.h>

#include <tfs_client_api.h>

using namespace tfs::client;
using namespace tfs::common;

namespace sf1r
{

RpcImageServer::RpcImageServer(const std::string& host, uint16_t port, uint32_t threadNum)
    : host_(host)
    , port_(port)
    , threadNum_(threadNum)
    , is_exporting_(false)
    , export_thread_(NULL)
{
}

RpcImageServer::~RpcImageServer()
{
    std::cout << "~RpcImageServer()" << std::endl;
    stop();
}

void RpcImageServer::start()
{
    instance.listen(host_, port_);
    instance.start(threadNum_);
}

void RpcImageServer::join()
{
    instance.join();
}

void RpcImageServer::run()
{
    start();
    join();
}

void RpcImageServer::stop()
{
    instance.end();
    instance.join();
    if(export_thread_)
    {
        export_thread_->interrupt();
        export_thread_->join();
        delete export_thread_;
    }
}

void RpcImageServer::dispatch(msgpack::rpc::request req)
{
    try
    {
        std::string method;
        req.method().convert(&method);

        if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_TEST])
        {
            msgpack::type::tuple<bool> params;
            req.params().convert(&params);

            req.result(true);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_GET_IMAGE_COLOR])
        {
            msgpack::type::tuple<ImageColorData> params;
            req.params().convert(&params);
            ImageColorData& reqdata = params.get<0>();

            reqdata.success = ImageServerStorage::get()->GetImageColor(reqdata.img_file, reqdata.result_img_color);
            if(!reqdata.success)
            {
                // try to recalculate the color
                //std::string picFilePath = ImageServerCfg::get()->getImageFilePath() + "/" + reqdata.img_file;
                char* data = NULL;
                std::size_t datasize = 0;
                if(ImageServerStorage::get()->DownloadImageData(reqdata.img_file, data, datasize))
                {
                    int indexCollection[COLOR_RET_NUM];
                    bool ret = getImageColor(data, datasize, indexCollection, COLOR_RET_NUM);
                    if(ret){
                        std::ostringstream oss;
                        for(std::size_t i = 0; i < COLOR_RET_NUM - 1; ++i)
                        {
                            oss << indexCollection[i] << ",";
                        }
                        oss << indexCollection[COLOR_RET_NUM - 1];

                        reqdata.success = ImageServerStorage::get()->SetImageColor(reqdata.img_file, oss.str());
                        reqdata.result_img_color = oss.str();
                        //LOG(INFO) << "got request image color for fileName=" << reqdata.img_file << "result:" <<
                        //   oss.str() << std::endl;
                    }else{
                        LOG(WARNING) << "getImageColor failed imagePath=" << reqdata.img_file << std::endl;
                        reqdata.success = false;
                    }
                    delete[] data;
                }
                else
                {
                    LOG(INFO) << "getImage data failed while get image color imagePath=" << reqdata.img_file << std::endl;
                    reqdata.success = false;
                }
            }
            req.result(reqdata);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_UPLOAD_IMAGE])
        {
            msgpack::type::tuple<UploadImageData> params;
            req.params().convert(&params);
            UploadImageData& reqdata = params.get<0>();
            std::string ret_file;
            if(reqdata.param_type == 0)
            {
                reqdata.success = ImageServerStorage::get()->UploadImageFile(reqdata.img_file, ret_file);
            }
            else if(reqdata.param_type == 1)
            {
                reqdata.success = ImageServerStorage::get()->UploadImageData(reqdata.img_file.data(),
                    reqdata.img_file.size(), ret_file);
            }
            else
            {
                reqdata.success = false;
            }
            if(reqdata.success)
            {
                // write log file
                //
                ofstream ofs;
                try
                {
                    ofs.open(ImageServerCfg::get()->getUploadImageLog().c_str(), ofstream::app);
                    ofs << ret_file.c_str() << std::endl;
                    ofs.close();
                }
                catch(std::exception& e)
                {
                    LOG(ERROR) << "write upload log failed: " << ret_file << std::endl;
                    ofs.close();
                }
            }
            else
            {
                if(reqdata.param_type == 0)
                    LOG(WARNING) << "file upload failed: " << reqdata.img_file << std::endl;
                else
                    LOG(WARNING) << "image data upload failed: " << std::endl;
            }
            reqdata.img_file = ret_file;
            req.result(reqdata);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_DELETE_IMAGE])
        {
            msgpack::type::tuple<DeleteImageData> params;
            req.params().convert(&params);
            DeleteImageData& reqdata = params.get<0>();
            reqdata.success = ImageServerStorage::get()->DeleteImage(reqdata.img_file);
            req.result(reqdata);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_EXPORT_IMAGE])
        {
            msgpack::type::tuple<ExportImageData> params;
            req.params().convert(&params);
            ExportImageData& reqdata = params.get<0>();
            req.result(reqdata);
            if(is_exporting_)
            {
                LOG(WARNING) << "image is already exporting! Ignore any more request." << std::endl;
                return;
            }
            is_exporting_ = true;
            if(export_thread_)
            {
                delete export_thread_;
            }

            export_thread_ = new boost::thread(&RpcImageServer::exportimage, this,
                    reqdata.img_log_file, reqdata.out_dir);

        }
        else if(method == ImageServerRequest::method_names[ImageServerRequest::METHOD_COMPUTE_IMAGE_COLOR])
        {
            msgpack::type::tuple<ComputeImageColorData> params;
            req.params().convert(&params);
            ComputeImageColorData& reqdata = params.get<0>();

            Request *image_computereq = new Request;
            image_computereq->filePath = reqdata.filepath;
            image_computereq->filetype = reqdata.filetype;
            LOG(INFO) << "got image file color computing request:" << reqdata.filepath << endl;
            MSG msg(image_computereq);
            reqdata.success = true;
            if(!ImageProcessTask::instance()->put(msg)){
                LOG(ERROR) << "failed to enqueue fileName:" << reqdata.filepath << endl;
                reqdata.success = false;
            }
            req.result(reqdata);
        }
        else
        {
            req.error(msgpack::rpc::NO_METHOD_ERROR);
        }
    }
    catch (const msgpack::type_error& e)
    {
        req.error(msgpack::rpc::ARGUMENT_ERROR);
    }
    catch (const std::exception& e)
    {
        req.error(std::string(e.what()));
    }
}

void RpcImageServer::exportimage(const std::string& log_file, const std::string& outdir)
{
    size_t total_export = 0;
    size_t failed_cnt = 0;
    ifstream ifs;
    ofstream export_log;
    struct timeval tv_start, tv_end;
    try
    {
        ifs.open(log_file.c_str(), ifstream::in);
        export_log.open((outdir + "/" + std::string("export.log")).c_str(), ofstream::app);

        gettimeofday(&tv_start, NULL);
        export_log << " === export start: " << tv_start.tv_sec << " === " << std::endl;
        while(ifs.good())
        {
            ++total_export;
            char file_name[TFS_FILE_LEN];
            ifs.getline(file_name, TFS_FILE_LEN);
            char* buffer = NULL;
            std::size_t buf_size = 0;
            bool ret = ImageServerStorage::get()->DownloadImageData(file_name, buffer, buf_size);
            if(ret)
            {
                ofstream ofs;
                try
                {
                    ofs.open((outdir + "/" + file_name).c_str(), ofstream::trunc);
                    ofs.write(buffer, buf_size);
                }
                catch(std::exception& e)
                {
                    ++failed_cnt;
                    export_log << "export failed (save data to out file error) : " << e.what() << ",file: " << file_name << std::endl;
                }
                if(ofs.is_open())
                    ofs.close();
                delete[] buffer;
            }
            else
            {
                ++failed_cnt;
                export_log << "export failed (download error): " << file_name << std::endl;
            }
            boost::this_thread::interruption_point();
        }
    }
    catch(boost::thread_interrupted& )
    {
        LOG(INFO) << "exporting aborted. " << std::endl;
    }
    catch(std::exception& e)
    {
        LOG(WARNING) << "exception while exporting: " << e.what() << std::endl;
    }
    if(ifs.is_open())
    {
        ifs.close();
    }
    if(export_log.is_open())
    {
        export_log << "export finished, total export : " << total_export << ", failed: " << failed_cnt << std::endl;
        gettimeofday(&tv_end, NULL);
        export_log << " === export end: " << tv_end.tv_sec << " === " << std::endl;
        export_log.close();
    }
    is_exporting_ = false;
}

}
<commit_msg>add log for upload image if the time is too long<commit_after>#include "RpcImageServer.h"
#include "ImageServerCfg.h"
#include "ImageProcess.h"
#include "ImageProcessTask.h"
#include <image-manager/ImageServerStorage.h>
#include <image-manager/ImageServerRequest.h>
#include "errno.h"
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
#include <boost/thread.hpp>
#include <glog/logging.h>

#include <tfs_client_api.h>

using namespace tfs::client;
using namespace tfs::common;

namespace sf1r
{

RpcImageServer::RpcImageServer(const std::string& host, uint16_t port, uint32_t threadNum)
    : host_(host)
    , port_(port)
    , threadNum_(threadNum)
    , is_exporting_(false)
    , export_thread_(NULL)
{
}

RpcImageServer::~RpcImageServer()
{
    std::cout << "~RpcImageServer()" << std::endl;
    stop();
}

void RpcImageServer::start()
{
    instance.listen(host_, port_);
    instance.start(threadNum_);
}

void RpcImageServer::join()
{
    instance.join();
}

void RpcImageServer::run()
{
    start();
    join();
}

void RpcImageServer::stop()
{
    instance.end();
    instance.join();
    if(export_thread_)
    {
        export_thread_->interrupt();
        export_thread_->join();
        delete export_thread_;
    }
}

void RpcImageServer::dispatch(msgpack::rpc::request req)
{
    try
    {
        std::string method;
        req.method().convert(&method);

        if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_TEST])
        {
            msgpack::type::tuple<bool> params;
            req.params().convert(&params);

            req.result(true);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_GET_IMAGE_COLOR])
        {
            msgpack::type::tuple<ImageColorData> params;
            req.params().convert(&params);
            ImageColorData& reqdata = params.get<0>();

            reqdata.success = ImageServerStorage::get()->GetImageColor(reqdata.img_file, reqdata.result_img_color);
            if(!reqdata.success)
            {
                // try to recalculate the color
                //std::string picFilePath = ImageServerCfg::get()->getImageFilePath() + "/" + reqdata.img_file;
                char* data = NULL;
                std::size_t datasize = 0;
                if(ImageServerStorage::get()->DownloadImageData(reqdata.img_file, data, datasize))
                {
                    int indexCollection[COLOR_RET_NUM];
                    bool ret = getImageColor(data, datasize, indexCollection, COLOR_RET_NUM);
                    if(ret){
                        std::ostringstream oss;
                        for(std::size_t i = 0; i < COLOR_RET_NUM - 1; ++i)
                        {
                            oss << indexCollection[i] << ",";
                        }
                        oss << indexCollection[COLOR_RET_NUM - 1];

                        reqdata.success = ImageServerStorage::get()->SetImageColor(reqdata.img_file, oss.str());
                        reqdata.result_img_color = oss.str();
                        //LOG(INFO) << "got request image color for fileName=" << reqdata.img_file << "result:" <<
                        //   oss.str() << std::endl;
                    }else{
                        LOG(WARNING) << "getImageColor failed imagePath=" << reqdata.img_file << std::endl;
                        reqdata.success = false;
                    }
                    delete[] data;
                }
                else
                {
                    LOG(INFO) << "getImage data failed while get image color imagePath=" << reqdata.img_file << std::endl;
                    reqdata.success = false;
                }
            }
            req.result(reqdata);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_UPLOAD_IMAGE])
        {
            struct timeval tv_start, tv_end;
            gettimeofday(&tv_start, NULL);
            msgpack::type::tuple<UploadImageData> params;
            req.params().convert(&params);
            UploadImageData& reqdata = params.get<0>();
            std::string ret_file;
            if(reqdata.param_type == 0)
            {
                reqdata.success = ImageServerStorage::get()->UploadImageFile(reqdata.img_file, ret_file);
            }
            else if(reqdata.param_type == 1)
            {
                reqdata.success = ImageServerStorage::get()->UploadImageData(reqdata.img_file.data(),
                    reqdata.img_file.size(), ret_file);
            }
            else
            {
                reqdata.success = false;
            }
            gettimeofday(&tv_end, NULL);
            int interval = tv_end.tv_sec - tv_start.tv_sec;
            if( interval > 1)
                LOG(WARNING) << "upload time larger than 1s : " << interval << endl;
            if(reqdata.success)
            {
                // write log file
                //
                ofstream ofs;
                try
                {
                    ofs.open(ImageServerCfg::get()->getUploadImageLog().c_str(), ofstream::app);
                    ofs << ret_file.c_str() << std::endl;
                    ofs.close();
                }
                catch(std::exception& e)
                {
                    LOG(ERROR) << "write upload log failed: " << ret_file << std::endl;
                    ofs.close();
                }
            }
            else
            {
                if(reqdata.param_type == 0)
                    LOG(WARNING) << "file upload failed: " << reqdata.img_file << std::endl;
                else
                    LOG(WARNING) << "image data upload failed: " << std::endl;
            }
            gettimeofday(&tv_end, NULL);
            interval = tv_end.tv_sec - tv_start.tv_sec;
            if( interval > 1)
                LOG(WARNING) << "upload time total larger than 1s : " << interval << endl;
            reqdata.img_file = ret_file;
            req.result(reqdata);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_DELETE_IMAGE])
        {
            msgpack::type::tuple<DeleteImageData> params;
            req.params().convert(&params);
            DeleteImageData& reqdata = params.get<0>();
            reqdata.success = ImageServerStorage::get()->DeleteImage(reqdata.img_file);
            req.result(reqdata);
        }
        else if (method == ImageServerRequest::method_names[ImageServerRequest::METHOD_EXPORT_IMAGE])
        {
            msgpack::type::tuple<ExportImageData> params;
            req.params().convert(&params);
            ExportImageData& reqdata = params.get<0>();
            req.result(reqdata);
            if(is_exporting_)
            {
                LOG(WARNING) << "image is already exporting! Ignore any more request." << std::endl;
                return;
            }
            is_exporting_ = true;
            if(export_thread_)
            {
                delete export_thread_;
            }

            export_thread_ = new boost::thread(&RpcImageServer::exportimage, this,
                    reqdata.img_log_file, reqdata.out_dir);

        }
        else if(method == ImageServerRequest::method_names[ImageServerRequest::METHOD_COMPUTE_IMAGE_COLOR])
        {
            msgpack::type::tuple<ComputeImageColorData> params;
            req.params().convert(&params);
            ComputeImageColorData& reqdata = params.get<0>();

            Request *image_computereq = new Request;
            image_computereq->filePath = reqdata.filepath;
            image_computereq->filetype = reqdata.filetype;
            LOG(INFO) << "got image file color computing request:" << reqdata.filepath << endl;
            MSG msg(image_computereq);
            reqdata.success = true;
            if(!ImageProcessTask::instance()->put(msg)){
                LOG(ERROR) << "failed to enqueue fileName:" << reqdata.filepath << endl;
                reqdata.success = false;
            }
            req.result(reqdata);
        }
        else
        {
            req.error(msgpack::rpc::NO_METHOD_ERROR);
        }
    }
    catch (const msgpack::type_error& e)
    {
        req.error(msgpack::rpc::ARGUMENT_ERROR);
    }
    catch (const std::exception& e)
    {
        req.error(std::string(e.what()));
    }
}

void RpcImageServer::exportimage(const std::string& log_file, const std::string& outdir)
{
    size_t total_export = 0;
    size_t failed_cnt = 0;
    ifstream ifs;
    ofstream export_log;
    struct timeval tv_start, tv_end;
    try
    {
        ifs.open(log_file.c_str(), ifstream::in);
        export_log.open((outdir + "/" + std::string("export.log")).c_str(), ofstream::app);

        gettimeofday(&tv_start, NULL);
        export_log << " === export start: " << tv_start.tv_sec << " === " << std::endl;
        while(ifs.good())
        {
            ++total_export;
            char file_name[TFS_FILE_LEN];
            ifs.getline(file_name, TFS_FILE_LEN);
            char* buffer = NULL;
            std::size_t buf_size = 0;
            bool ret = ImageServerStorage::get()->DownloadImageData(file_name, buffer, buf_size);
            if(ret)
            {
                ofstream ofs;
                try
                {
                    ofs.open((outdir + "/" + file_name).c_str(), ofstream::trunc);
                    ofs.write(buffer, buf_size);
                }
                catch(std::exception& e)
                {
                    ++failed_cnt;
                    export_log << "export failed (save data to out file error) : " << e.what() << ",file: " << file_name << std::endl;
                }
                if(ofs.is_open())
                    ofs.close();
                delete[] buffer;
            }
            else
            {
                ++failed_cnt;
                export_log << "export failed (download error): " << file_name << std::endl;
            }
            boost::this_thread::interruption_point();
        }
    }
    catch(boost::thread_interrupted& )
    {
        LOG(INFO) << "exporting aborted. " << std::endl;
    }
    catch(std::exception& e)
    {
        LOG(WARNING) << "exception while exporting: " << e.what() << std::endl;
    }
    if(ifs.is_open())
    {
        ifs.close();
    }
    if(export_log.is_open())
    {
        export_log << "export finished, total export : " << total_export << ", failed: " << failed_cnt << std::endl;
        gettimeofday(&tv_end, NULL);
        export_log << " === export end: " << tv_end.tv_sec << " === " << std::endl;
        export_log.close();
    }
    is_exporting_ = false;
}

}
<|endoftext|>


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

Program:   Medical Imaging & Interaction Toolkit
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 "mitkSurface.h"
#include "mitkCommon.h"
#include "mitkVector.h"
#include "mitkTimeSlicedGeometry.h"

#include "vtkPolyData.h"
#include "vtkSphereSource.h"

#include <fstream>

int mitkSurfaceTest(int /*argc*/, char* /*argv*/[])
{
  mitk::Surface::Pointer surface;
  std::cout << "Testing mitk::Surface::New(): ";
  surface = mitk::Surface::New();
  if (surface.IsNull()) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing mitk::Surface::PrintSelf() for empty surface: ";
  surface->PrintSelf();
  std::cout<<"[PASSED]"<<std::endl;

  vtkSphereSource* sphereSource = vtkSphereSource::New();
  sphereSource->SetCenter(0,0,0);
  sphereSource->SetRadius(5.0);
  sphereSource->SetThetaResolution(10);
  sphereSource->SetPhiResolution(10);
  sphereSource->Update();

  vtkPolyData* polys = sphereSource->GetOutput();
  surface->SetVtkPolyData( polys );
  sphereSource->Delete();
  std::cout << "Testing mitk::Surface::SetVtkPolyData(): ";
  if (surface->GetVtkPolyData() ==  NULL ) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  {
    vtkFloatingPointType bounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

    polys->ComputeBounds();
    polys->GetBounds( bounds );

    std::cout << "Testing GetBoundingBox() ";
    surface->UpdateOutputInformation();
    surface->SetRequestedRegionToLargestPossibleRegion();
    //  mitk::BoundingBox bb = const_cast<mitk::BoundingBox*>(
    mitk::BoundingBox* bb = const_cast<mitk::BoundingBox*>(surface->GetGeometry()->GetBoundingBox());
    mitk::BoundingBox::BoundsArrayType surfBounds = bb->GetBounds();

    if ( bounds[0] != surfBounds[0]
    || bounds[1] != surfBounds[1]
    || bounds[2] != surfBounds[2]
    || bounds[3] != surfBounds[3]
    || bounds[4] != surfBounds[4]
    || bounds[5] != surfBounds[5]
    ) {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
    else {
      std::cout<<"[PASSED]"<<std::endl;
    }
  }

  std::cout << "Testing mitk::Surface::Expand( timesteps ): ";
  surface->Expand(5);
  surface->Update();
  surface->SetRequestedRegionToLargestPossibleRegion();
  mitk::Surface::RegionType requestedRegion = surface->GetRequestedRegion();

  if ( requestedRegion.GetSize(3) != 5 ) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing mitk::Surface::Testing 4D surface data creation: ";

//  surface = mitk::Surface::New();
  //mitk::Geometry3D::Pointer geometry = surface->GetTimeSlicedGeometry()->GetGeometry3D(0);
  //geometry->GetVtkTransform()->Identity();
  //geometry->GetVtkTransform()->Translate(10,10,10);
  //geometry->TransferVtkToItkTransform();
  //mitk::TimeSlicedGeometry* timeSlicedGeometry = surface->GetTimeSlicedGeometry();
  //timeSlicedGeometry->InitializeEvenlyTimed(geometry, 5);

  vtkFloatingPointType bounds[5][6];

  for (int i=0;i<5;i++) {
    vtkSphereSource* sphereSource = vtkSphereSource::New();
    sphereSource->SetCenter(0,0,0);
    sphereSource->SetRadius(1.0 * (i+1.0));
    sphereSource->SetThetaResolution(10);
    sphereSource->SetPhiResolution(10);
    sphereSource->Update();
    sphereSource->GetOutput()->ComputeBounds();
    sphereSource->GetOutput()->GetBounds( bounds[i] );
    surface->SetVtkPolyData( sphereSource->GetOutput(),i );
    sphereSource->Delete();
  }

  surface->UpdateOutputInformation();
  surface->SetRequestedRegionToLargestPossibleRegion();

  bool passed = true;
  for (int i=0;i<5;i++)
  {
    mitk::BoundingBox::BoundsArrayType surfBounds = (const_cast<mitk::BoundingBox*>(surface->GetTimeSlicedGeometry()->GetGeometry3D(i)->GetBoundingBox()))->GetBounds();

    if ( bounds[i][0] != surfBounds[0]
    || bounds[i][1] != surfBounds[1]
    || bounds[i][2] != surfBounds[2]
    || bounds[i][3] != surfBounds[3]
    || bounds[i][4] != surfBounds[4]
    || bounds[i][5] != surfBounds[5] )
    {
      passed = false;
      break;
    }
  }

  if (!passed)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing correctness of geometry for surface->GetUpdatedTimeSlicedGeometry(): \n";
  const mitk::TimeSlicedGeometry* inputTimeGeometry = surface->GetUpdatedTimeSlicedGeometry();

  int time = 3;
  int timestep=0;
  timestep = inputTimeGeometry->MSToTimeStep( time );

  std::cout << "time: "<< time << std::endl;
  std::cout << "timestep: "<<timestep << std::endl;

  if (time != timestep)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Explicitly changing the data of timestep 3 and checking for timebounds correctness of surface's geometry again:\n";

  sphereSource = vtkSphereSource::New();
  sphereSource->SetCenter(0,0,0);
  sphereSource->SetRadius( 100.0 );
  sphereSource->SetThetaResolution(10);
  sphereSource->SetPhiResolution(10);
  sphereSource->Update();
  surface->SetVtkPolyData( sphereSource->GetOutput(), 3 );
  sphereSource->Delete();

  inputTimeGeometry = surface->GetUpdatedTimeSlicedGeometry();
  time = 3;
  timestep=0;
  timestep = inputTimeGeometry->MSToTimeStep( time );

  std::cout << "time: "<< time << std::endl;
  std::cout << "timestep: "<<timestep << std::endl;

  if (time != timestep)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing copying a Surface with Graft()" << std::endl;

  unsigned int numberoftimesteps = surface->GetTimeSteps();
  mitk::Surface::Pointer dummy = mitk::Surface::New();
  dummy->Graft(surface);
  std::cout << "polyData != NULL ??" << std::endl;
  if (dummy->GetVtkPolyData() == NULL)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "orig-numberofTimeSteps:" << numberoftimesteps << "  copy-numberofTimeSteps:" << dummy->GetTimeSteps() << std::endl;
  if (dummy->GetTimeSteps() != numberoftimesteps)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>COMP: Missing parameters<commit_after>/*=========================================================================

Program:   Medical Imaging & Interaction Toolkit
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 "mitkSurface.h"
#include "mitkCommon.h"
#include "mitkVector.h"
#include "mitkTimeSlicedGeometry.h"

#include "vtkPolyData.h"
#include "vtkSphereSource.h"

#include <fstream>

int mitkSurfaceTest(int /*argc*/, char* /*argv*/[])
{
  mitk::Surface::Pointer surface;
  std::cout << "Testing mitk::Surface::New(): ";
  surface = mitk::Surface::New();
  if (surface.IsNull()) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing mitk::Surface::PrintSelf() for empty surface: ";
  surface->PrintSelf(std::cout, 0);
  std::cout<<"[PASSED]"<<std::endl;

  vtkSphereSource* sphereSource = vtkSphereSource::New();
  sphereSource->SetCenter(0,0,0);
  sphereSource->SetRadius(5.0);
  sphereSource->SetThetaResolution(10);
  sphereSource->SetPhiResolution(10);
  sphereSource->Update();

  vtkPolyData* polys = sphereSource->GetOutput();
  surface->SetVtkPolyData( polys );
  sphereSource->Delete();
  std::cout << "Testing mitk::Surface::SetVtkPolyData(): ";
  if (surface->GetVtkPolyData() ==  NULL ) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  {
    vtkFloatingPointType bounds[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};

    polys->ComputeBounds();
    polys->GetBounds( bounds );

    std::cout << "Testing GetBoundingBox() ";
    surface->UpdateOutputInformation();
    surface->SetRequestedRegionToLargestPossibleRegion();
    //  mitk::BoundingBox bb = const_cast<mitk::BoundingBox*>(
    mitk::BoundingBox* bb = const_cast<mitk::BoundingBox*>(surface->GetGeometry()->GetBoundingBox());
    mitk::BoundingBox::BoundsArrayType surfBounds = bb->GetBounds();

    if ( bounds[0] != surfBounds[0]
    || bounds[1] != surfBounds[1]
    || bounds[2] != surfBounds[2]
    || bounds[3] != surfBounds[3]
    || bounds[4] != surfBounds[4]
    || bounds[5] != surfBounds[5]
    ) {
      std::cout<<"[FAILED]"<<std::endl;
      return EXIT_FAILURE;
    }
    else {
      std::cout<<"[PASSED]"<<std::endl;
    }
  }

  std::cout << "Testing mitk::Surface::Expand( timesteps ): ";
  surface->Expand(5);
  surface->Update();
  surface->SetRequestedRegionToLargestPossibleRegion();
  mitk::Surface::RegionType requestedRegion = surface->GetRequestedRegion();

  if ( requestedRegion.GetSize(3) != 5 ) {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else {
  std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing mitk::Surface::Testing 4D surface data creation: ";

//  surface = mitk::Surface::New();
  //mitk::Geometry3D::Pointer geometry = surface->GetTimeSlicedGeometry()->GetGeometry3D(0);
  //geometry->GetVtkTransform()->Identity();
  //geometry->GetVtkTransform()->Translate(10,10,10);
  //geometry->TransferVtkToItkTransform();
  //mitk::TimeSlicedGeometry* timeSlicedGeometry = surface->GetTimeSlicedGeometry();
  //timeSlicedGeometry->InitializeEvenlyTimed(geometry, 5);

  vtkFloatingPointType bounds[5][6];

  for (int i=0;i<5;i++) {
    vtkSphereSource* sphereSource = vtkSphereSource::New();
    sphereSource->SetCenter(0,0,0);
    sphereSource->SetRadius(1.0 * (i+1.0));
    sphereSource->SetThetaResolution(10);
    sphereSource->SetPhiResolution(10);
    sphereSource->Update();
    sphereSource->GetOutput()->ComputeBounds();
    sphereSource->GetOutput()->GetBounds( bounds[i] );
    surface->SetVtkPolyData( sphereSource->GetOutput(),i );
    sphereSource->Delete();
  }

  surface->UpdateOutputInformation();
  surface->SetRequestedRegionToLargestPossibleRegion();

  bool passed = true;
  for (int i=0;i<5;i++)
  {
    mitk::BoundingBox::BoundsArrayType surfBounds = (const_cast<mitk::BoundingBox*>(surface->GetTimeSlicedGeometry()->GetGeometry3D(i)->GetBoundingBox()))->GetBounds();

    if ( bounds[i][0] != surfBounds[0]
    || bounds[i][1] != surfBounds[1]
    || bounds[i][2] != surfBounds[2]
    || bounds[i][3] != surfBounds[3]
    || bounds[i][4] != surfBounds[4]
    || bounds[i][5] != surfBounds[5] )
    {
      passed = false;
      break;
    }
  }

  if (!passed)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing correctness of geometry for surface->GetUpdatedTimeSlicedGeometry(): \n";
  const mitk::TimeSlicedGeometry* inputTimeGeometry = surface->GetUpdatedTimeSlicedGeometry();

  int time = 3;
  int timestep=0;
  timestep = inputTimeGeometry->MSToTimeStep( time );

  std::cout << "time: "<< time << std::endl;
  std::cout << "timestep: "<<timestep << std::endl;

  if (time != timestep)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Explicitly changing the data of timestep 3 and checking for timebounds correctness of surface's geometry again:\n";

  sphereSource = vtkSphereSource::New();
  sphereSource->SetCenter(0,0,0);
  sphereSource->SetRadius( 100.0 );
  sphereSource->SetThetaResolution(10);
  sphereSource->SetPhiResolution(10);
  sphereSource->Update();
  surface->SetVtkPolyData( sphereSource->GetOutput(), 3 );
  sphereSource->Delete();

  inputTimeGeometry = surface->GetUpdatedTimeSlicedGeometry();
  time = 3;
  timestep=0;
  timestep = inputTimeGeometry->MSToTimeStep( time );

  std::cout << "time: "<< time << std::endl;
  std::cout << "timestep: "<<timestep << std::endl;

  if (time != timestep)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }
  else
  {
    std::cout<<"[PASSED]"<<std::endl;
  }

  std::cout << "Testing copying a Surface with Graft()" << std::endl;

  unsigned int numberoftimesteps = surface->GetTimeSteps();
  mitk::Surface::Pointer dummy = mitk::Surface::New();
  dummy->Graft(surface);
  std::cout << "polyData != NULL ??" << std::endl;
  if (dummy->GetVtkPolyData() == NULL)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }

  std::cout << "orig-numberofTimeSteps:" << numberoftimesteps << "  copy-numberofTimeSteps:" << dummy->GetTimeSteps() << std::endl;
  if (dummy->GetTimeSteps() != numberoftimesteps)
  {
    std::cout<<"[FAILED]"<<std::endl;
    return EXIT_FAILURE;
  }

  std::cout<<"[TEST DONE]"<<std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/** @file
 *
 * @ingroup dspLibrary
 *
 * @brief Container object that holds some audio in a chunk of memory.
 *
 * @see TTMatrix, TTAudioSignal
 *
 * @authors Timothy Place & Nathan Wolek
 *
 * @copyright Copyright © 2003-2012, Timothy Place & Nathan Wolek @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSampleMatrix.h"

#define thisTTClass			TTSampleMatrix
#define thisTTClassName		"samplematrix"
#define thisTTClassTags		"audio, buffer"

TTObjectPtr TTSampleMatrix::instantiate(TTSymbol& name, TTValue& arguments)
{
	return new TTSampleMatrix(arguments);
}

extern "C" void TTSampleMatrix::registerClass()
{
	TTClassRegister(thisTTClassName, thisTTClassTags, TTSampleMatrix::instantiate);
}

TTSampleMatrix::TTSampleMatrix(TTValue& arguments) :
	TTMatrix(arguments),
	mSampleRate(44100.0)
{
	this->setTypeWithoutResize(kTypeFloat64);
	this->setElementCountWithoutResize(1);
	this->resize();

	addAttributeWithGetterAndSetter(NumChannels,		kTypeInt32);
	addAttributeWithGetterAndSetter(Length,				kTypeFloat64);
	addAttributeWithGetterAndSetter(LengthInSamples,	kTypeInt32);
	addAttribute(SampleRate,							kTypeFloat64);

	addMessage(normalize);
	addMessageWithArguments(fill);

	addMessageWithArguments(getValueAtIndex);
	registerMessage("peek", (TTMethod)&TTSampleMatrix::getValueAtIndex);
	registerMessage("peeki", (TTMethod)&TTSampleMatrix::getValueAtIndex);

	addMessageWithArguments(setValueAtIndex);
	registerMessage("poke", (TTMethod)&TTSampleMatrix::setValueAtIndex);

	// TODO: more messages to implement
	//	"readFile"   (requires libsndfile straightening-out)
	//	"writeFile"  (requires libsndfile straightening-out)
	//	a way to query attributes: for example what is the sr and bpm of an AIFF file?
}

TTSampleMatrix::~TTSampleMatrix()
{
	;
}

TTErr TTSampleMatrix::setNumChannels(const TTValue& newNumChannels)
{
	return setColumnCount(newNumChannels);
}

TTErr TTSampleMatrix::getNumChannels(TTValue& returnedChannelCount)
{
	returnedChannelCount = mNumChannels;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLength(const TTValue& newLength)
{
	TTValue newLengthInSamples = TTFloat64(newLength) * mSampleRate * 0.001;
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLength(TTValue& returnedLength)
{
	returnedLength = (mLengthInSamples / mSampleRate) * 1000.0;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLengthInSamples(const TTValue& newLengthInSamples)
{
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLengthInSamples(TTValue& returnedLengthInSamples)
{
	returnedLengthInSamples = mLengthInSamples;
	return kTTErrNone;
}

TTErr TTSampleMatrix::getValueAtIndex(const TTValue& index, TTValue &output)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;
	TTErr			err;

	index.get(i++, sampleIndex);
	if (index.getSize() > 2)		// TODO: sure would be nice to change the name of this method to "size" or something...
		index.get(i++, sampleChannel);

	err = peek(sampleIndex, sampleChannel, sampleValue);
	if (!err)
		output.set(i++, sampleValue);
	return err;
}

TTErr TTSampleMatrix::peek(const TTUInt64 index, const TTUInt16 channel, TTSampleValue& value)
{
	TTRowID p_index = index;
	TTColumnID p_channel = channel;

	makeInBounds(p_index, p_channel); // out of range values are clipped
	get2d(p_index, p_channel, value);
	return kTTErrNone;
}

// a first attempt at interpolation for the SampleMatrix. should be viewed as temporary.
// needs to be fleshed out with different options...
TTErr TTSampleMatrix::peeki(const TTFloat64 index, const TTUInt16 channel, TTSampleValue& value)
{
	// variables needed
    TTColumnID p_channel = channel;

	TTRowID indexThisInteger = TTRowID(index);
	TTFloat64 indexFractionalPart = index - indexThisInteger; // before makeInBounds to get the right value!
	makeInBounds(indexThisInteger, p_channel);  // out of range values are clipped

	TTRowID indexNextInteger = indexThisInteger + 1;
	makeRowIDInBounds(indexNextInteger, outOfBoundsWrap); //if we went beyond the mRowCount, go back to 0th sample

	TTSampleValue valueThisInteger, valueNextInteger;

	get2d(indexThisInteger, p_channel, valueThisInteger);
	get2d(indexNextInteger, p_channel, valueNextInteger);

	// simple linear interpolation adapted from TTDelay
	value = (valueNextInteger * (1.0 - indexFractionalPart)) + (valueThisInteger * indexFractionalPart);

	return kTTErrNone;
}

/**	Set the sample value for a given index.
	The first number passed in the index parameter will be interpreted as the sample index.
	If there are three numbers passed, then the second number, if passed, will designate the channel index (defaults to zero).
	The final value will be used as the sample value that will be copied to the designated index.
*/
TTErr TTSampleMatrix::setValueAtIndex(const TTValue& index, TTValue& unusedOutput)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;

	index.get(i++, sampleIndex);
	if (index.getSize() > 2)
		index.get(i++, sampleChannel);
	index.get(i++, sampleValue);

	return poke(sampleIndex, sampleChannel, sampleValue);
}

TTErr TTSampleMatrix::poke(const TTUInt64 index, const TTUInt16 channel, const TTSampleValue value)
{
	TTRowID p_index = index;
	TTColumnID p_channel = channel;

	TTBoolean weAreNotInBounds = makeInBounds(p_index,p_channel);

	if (weAreNotInBounds)
	{
		// don't go poking around out of bounds
		return kTTErrInvalidValue;
	} else {
		set2d(p_index, p_channel, value);
		return kTTErrNone;
	}
}

TTErr TTSampleMatrix::fill(const TTValue& value, TTValue& unusedOutput)
{
	TTSymbol	fillAlgorithm = value;

	if (fillAlgorithm == kTTSym_sine) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_sineMod) {							// (modulator version: ranges from 0.0 to 1.0, rather than -1.0 to 1.0)
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, 0.5 + (0.5 * sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosine) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosineMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, 0.5 + (0.5 * cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_ramp) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_rampMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_sawtooth) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel+1, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_sawtoothMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel+1, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_triangle) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt32 i=0; i < mLengthInSamples/2; i++) {
				set2d(i+1, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
				set2d(mLengthInSamples-i, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
			}
		}
	}
	else if (fillAlgorithm == kTTSym_triangleMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt32 i=0; i < mLengthInSamples/2; i++) {
				set2d(i+1, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
				set2d(mLengthInSamples-i, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
			}
		}
	}

	return kTTErrNone;
}

TTErr TTSampleMatrix::normalize(const TTValue& aValue)
{
	TTFloat64			normalizeTo = 1.0;
	TTRowID				m = mLengthInSamples; // mFrameLength
	TTColumnID			n = mNumChannels; // mNumChannels
	TTSampleValuePtr	samples = (TTSampleValuePtr)getLockedPointer();
	TTFloat64			peakValue = 0.0;
	TTFloat64			scalar;

	if (aValue.getSize() && TTFloat64(aValue) > 0.0)
		normalizeTo = aValue;

	for (int k=0; k<m*n; k++) {
		TTFloat64 magnitude = abs(samples[k]);

		if (magnitude > peakValue)
			peakValue = magnitude;
	}

	scalar = normalizeTo / peakValue;

	for (int k=0; k<m*n; k++)
		samples[k] *= scalar;

	releaseLockedPointer();
	return kTTErrNone;
}
<commit_msg>SampleMatrix:peeki() refinements<commit_after>/** @file
 *
 * @ingroup dspLibrary
 *
 * @brief Container object that holds some audio in a chunk of memory.
 *
 * @see TTMatrix, TTAudioSignal
 *
 * @authors Timothy Place & Nathan Wolek
 *
 * @copyright Copyright © 2003-2012, Timothy Place & Nathan Wolek @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSampleMatrix.h"

#define thisTTClass			TTSampleMatrix
#define thisTTClassName		"samplematrix"
#define thisTTClassTags		"audio, buffer"

TTObjectPtr TTSampleMatrix::instantiate(TTSymbol& name, TTValue& arguments)
{
	return new TTSampleMatrix(arguments);
}

extern "C" void TTSampleMatrix::registerClass()
{
	TTClassRegister(thisTTClassName, thisTTClassTags, TTSampleMatrix::instantiate);
}

TTSampleMatrix::TTSampleMatrix(TTValue& arguments) :
	TTMatrix(arguments),
	mSampleRate(44100.0)
{
	this->setTypeWithoutResize(kTypeFloat64);
	this->setElementCountWithoutResize(1);
	this->resize();

	addAttributeWithGetterAndSetter(NumChannels,		kTypeInt32);
	addAttributeWithGetterAndSetter(Length,				kTypeFloat64);
	addAttributeWithGetterAndSetter(LengthInSamples,	kTypeInt32);
	addAttribute(SampleRate,							kTypeFloat64);

	addMessage(normalize);
	addMessageWithArguments(fill);

	addMessageWithArguments(getValueAtIndex);
	registerMessage("peek", (TTMethod)&TTSampleMatrix::getValueAtIndex);
	registerMessage("peeki", (TTMethod)&TTSampleMatrix::getValueAtIndex);

	addMessageWithArguments(setValueAtIndex);
	registerMessage("poke", (TTMethod)&TTSampleMatrix::setValueAtIndex);

	// TODO: more messages to implement
	//	"readFile"   (requires libsndfile straightening-out)
	//	"writeFile"  (requires libsndfile straightening-out)
	//	a way to query attributes: for example what is the sr and bpm of an AIFF file?
}

TTSampleMatrix::~TTSampleMatrix()
{
	;
}

TTErr TTSampleMatrix::setNumChannels(const TTValue& newNumChannels)
{
	return setColumnCount(newNumChannels);
}

TTErr TTSampleMatrix::getNumChannels(TTValue& returnedChannelCount)
{
	returnedChannelCount = mNumChannels;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLength(const TTValue& newLength)
{
	TTValue newLengthInSamples = TTFloat64(newLength) * mSampleRate * 0.001;
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLength(TTValue& returnedLength)
{
	returnedLength = (mLengthInSamples / mSampleRate) * 1000.0;
	return kTTErrNone;
}

TTErr TTSampleMatrix::setLengthInSamples(const TTValue& newLengthInSamples)
{
	return setRowCount(newLengthInSamples);
}

TTErr TTSampleMatrix::getLengthInSamples(TTValue& returnedLengthInSamples)
{
	returnedLengthInSamples = mLengthInSamples;
	return kTTErrNone;
}

TTErr TTSampleMatrix::getValueAtIndex(const TTValue& index, TTValue &output)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;
	TTErr			err;

	index.get(i++, sampleIndex);
	if (index.getSize() > 2)		// TODO: sure would be nice to change the name of this method to "size" or something...
		index.get(i++, sampleChannel);

	err = peek(sampleIndex, sampleChannel, sampleValue);
	if (!err)
		output.set(i++, sampleValue);
	return err;
}

TTErr TTSampleMatrix::peek(const TTUInt64 index, const TTUInt16 channel, TTSampleValue& value)
{
	TTRowID p_index = index;
	TTColumnID p_channel = channel;

	makeInBounds(p_index, p_channel); // out of range values are clipped
	get2d(p_index, p_channel, value);
	return kTTErrNone;
}

// a first attempt at interpolation for the SampleMatrix. should be viewed as temporary.
// needs to be fleshed out with different options...
TTErr TTSampleMatrix::peeki(const TTFloat64 index, const TTUInt16 channel, TTSampleValue& value)
{
	// variables needed
    TTColumnID p_channel = channel;

	TTRowID indexThisInteger = TTRowID(index);
	TTFloat64 indexFractionalPart = index - indexThisInteger; // before makeInBounds to get the right value!

	TTBoolean weAreNotInBounds = makeInBounds(indexThisInteger, p_channel);  // out of range values are clipped

	if (weAreNotInBounds)
	{
		// no reason to interpolate, just use the first or last value
		get2d(indexThisInteger, p_channel, value);
		return kTTErrInvalidValue; // and report an error (is that what we want?)
	} else {
		TTRowID indexNextInteger = indexThisInteger + 1;
		makeRowIDInBounds(indexNextInteger); //does not allow interpolation between first and last sample
			//  (is that what we want? if not, insert outOfBoundsWrap)

		TTSampleValue valueThisInteger, valueNextInteger;

		get2d(indexThisInteger, p_channel, valueThisInteger);
		get2d(indexNextInteger, p_channel, valueNextInteger);

		// simple linear interpolation adapted from TTDelay
		value = (valueNextInteger * (1.0 - indexFractionalPart)) + (valueThisInteger * indexFractionalPart);

		return kTTErrNone;
	}
}

/**	Set the sample value for a given index.
	The first number passed in the index parameter will be interpreted as the sample index.
	If there are three numbers passed, then the second number, if passed, will designate the channel index (defaults to zero).
	The final value will be used as the sample value that will be copied to the designated index.
*/
TTErr TTSampleMatrix::setValueAtIndex(const TTValue& index, TTValue& unusedOutput)
{
	TTUInt32		sampleIndex;
	TTUInt16		sampleChannel = 0;
	TTSampleValue	sampleValue;
	TTUInt8			i = 0;

	index.get(i++, sampleIndex);
	if (index.getSize() > 2)
		index.get(i++, sampleChannel);
	index.get(i++, sampleValue);

	return poke(sampleIndex, sampleChannel, sampleValue);
}

TTErr TTSampleMatrix::poke(const TTUInt64 index, const TTUInt16 channel, const TTSampleValue value)
{
	TTRowID p_index = index;
	TTColumnID p_channel = channel;

	TTBoolean weAreNotInBounds = makeInBounds(p_index,p_channel);

	if (weAreNotInBounds)
	{
		// don't go poking around out of bounds
		return kTTErrInvalidValue;
	} else {
		set2d(p_index, p_channel, value);
		return kTTErrNone;
	}
}

TTErr TTSampleMatrix::fill(const TTValue& value, TTValue& unusedOutput)
{
	TTSymbol	fillAlgorithm = value;

	if (fillAlgorithm == kTTSym_sine) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_sineMod) {							// (modulator version: ranges from 0.0 to 1.0, rather than -1.0 to 1.0)
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, 0.5 + (0.5 * sin(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosine) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0))));
		}
	}
	else if (fillAlgorithm == kTTSym_cosineMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, 0.5 + (0.5 * cos(kTTTwoPi * (i / (TTFloat64(mLengthInSamples) - 1.0)))));
		}
	}
	else if (fillAlgorithm == kTTSym_ramp) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_rampMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(i+1, channel+1, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_sawtooth) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel+1, -1.0 + (2.0 * (float(i) / mLengthInSamples)));
		}
	}
	else if (fillAlgorithm == kTTSym_sawtoothMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt64 i=0; i<mLengthInSamples; i++)
				set2d(mLengthInSamples-i, channel+1, float(i) / mLengthInSamples);
		}
	}
	else if (fillAlgorithm == kTTSym_triangle) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt32 i=0; i < mLengthInSamples/2; i++) {
				set2d(i+1, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
				set2d(mLengthInSamples-i, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
			}
		}
	}
	else if (fillAlgorithm == kTTSym_triangleMod) {
		for (TTUInt16 channel=0; channel<mNumChannels; channel++) {
			for (TTUInt32 i=0; i < mLengthInSamples/2; i++) {
				set2d(i+1, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
				set2d(mLengthInSamples-i, channel+1, -1.0 + (4.0 * (float(i) / mLengthInSamples)));
			}
		}
	}

	return kTTErrNone;
}

TTErr TTSampleMatrix::normalize(const TTValue& aValue)
{
	TTFloat64			normalizeTo = 1.0;
	TTRowID				m = mLengthInSamples; // mFrameLength
	TTColumnID			n = mNumChannels; // mNumChannels
	TTSampleValuePtr	samples = (TTSampleValuePtr)getLockedPointer();
	TTFloat64			peakValue = 0.0;
	TTFloat64			scalar;

	if (aValue.getSize() && TTFloat64(aValue) > 0.0)
		normalizeTo = aValue;

	for (int k=0; k<m*n; k++) {
		TTFloat64 magnitude = abs(samples[k]);

		if (magnitude > peakValue)
			peakValue = magnitude;
	}

	scalar = normalizeTo / peakValue;

	for (int k=0; k<m*n; k++)
		samples[k] *= scalar;

	releaseLockedPointer();
	return kTTErrNone;
}
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/CXX11/Tensor>

using Eigen::Tensor;

template <int DataLayout>
static void test_simple_broadcasting()
{
  Tensor<float, 4, DataLayout> tensor(2,3,5,7);
  tensor.setRandom();
  array<ptrdiff_t, 4> broadcasts;
  broadcasts[0] = 1;
  broadcasts[1] = 1;
  broadcasts[2] = 1;
  broadcasts[3] = 1;

  Tensor<float, 4, DataLayout> no_broadcast;
  no_broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(no_broadcast.dimension(0), 2);
  VERIFY_IS_EQUAL(no_broadcast.dimension(1), 3);
  VERIFY_IS_EQUAL(no_broadcast.dimension(2), 5);
  VERIFY_IS_EQUAL(no_broadcast.dimension(3), 7);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 5; ++k) {
        for (int l = 0; l < 7; ++l) {
          VERIFY_IS_EQUAL(tensor(i,j,k,l), no_broadcast(i,j,k,l));
        }
      }
    }
  }

  broadcasts[0] = 2;
  broadcasts[1] = 3;
  broadcasts[2] = 1;
  broadcasts[3] = 4;
  Tensor<float, 4, DataLayout> broadcast;
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 4);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 5);
  VERIFY_IS_EQUAL(broadcast.dimension(3), 28);

  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 5; ++k) {
        for (int l = 0; l < 28; ++l) {
          VERIFY_IS_EQUAL(tensor(i%2,j%3,k%5,l%7), broadcast(i,j,k,l));
        }
      }
    }
  }
}

template <int DataLayout>
static void test_vectorized_broadcasting()
{
  Tensor<float, 3, DataLayout> tensor(8,3,5);
  tensor.setRandom();
  array<ptrdiff_t, 3> broadcasts;
  broadcasts[0] = 2;
  broadcasts[1] = 3;
  broadcasts[2] = 4;

  Tensor<float, 3, DataLayout> broadcast;
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 16);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 16; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%8,j%3,k%5), broadcast(i,j,k));
      }
    }
  }

  tensor.resize(11,3,5);
  tensor.setRandom();
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 22);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 22; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%11,j%3,k%5), broadcast(i,j,k));
      }
    }
  }
}

template <int DataLayout>
static void test_static_broadcasting()
{
  Tensor<float, 3, DataLayout> tensor(8,3,5);
  tensor.setRandom();
  Eigen::IndexList<Eigen::type2index<2>, Eigen::type2index<3>, Eigen::type2index<4>> broadcasts;

  Tensor<float, 3, DataLayout> broadcast;
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 16);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 16; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%8,j%3,k%5), broadcast(i,j,k));
      }
    }
  }

  tensor.resize(11,3,5);
  tensor.setRandom();
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 22);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 22; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%11,j%3,k%5), broadcast(i,j,k));
      }
    }
  }
}

template <int DataLayout>
static void test_fixed_size_broadcasting()
{
  // Need to add a [] operator to the Size class for this to work
#if 0
  Tensor<float, 1, DataLayout> t1(10);
  t1.setRandom();
  TensorFixedSize<float, Sizes<1>, DataLayout> t2;
  t2 = t2.constant(20.0f);

  Tensor<float, 1, DataLayout> t3 = t1 + t2.broadcast(Eigen::array<int, 1>{{10}});
  for (int i = 0; i < 10; ++i) {
    VERIFY_IS_APPROX(t3(i), t1(i) + t2(0));
  }

  TensorMap<TensorFixedSize<float, Sizes<1>, DataLayout> > t4(t2.data(), {{1}});
  Tensor<float, 1, DataLayout> t5 = t1 + t4.broadcast(Eigen::array<int, 1>{{10}});
  for (int i = 0; i < 10; ++i) {
    VERIFY_IS_APPROX(t5(i), t1(i) + t2(0));
  }
#endif
}

void test_cxx11_tensor_broadcasting()
{
  CALL_SUBTEST(test_simple_broadcasting<ColMajor>());
  CALL_SUBTEST(test_simple_broadcasting<RowMajor>());
  CALL_SUBTEST(test_vectorized_broadcasting<ColMajor>());
  CALL_SUBTEST(test_vectorized_broadcasting<RowMajor>());
  CALL_SUBTEST(test_static_broadcasting<ColMajor>());
  CALL_SUBTEST(test_static_broadcasting<RowMajor>());
  CALL_SUBTEST(test_fixed_size_broadcasting<ColMajor>());
  CALL_SUBTEST(test_fixed_size_broadcasting<RowMajor>());
}
<commit_msg>Fixed compilation error in the tensor broadcasting test<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/CXX11/Tensor>

using Eigen::Tensor;

template <int DataLayout>
static void test_simple_broadcasting()
{
  Tensor<float, 4, DataLayout> tensor(2,3,5,7);
  tensor.setRandom();
  array<ptrdiff_t, 4> broadcasts;
  broadcasts[0] = 1;
  broadcasts[1] = 1;
  broadcasts[2] = 1;
  broadcasts[3] = 1;

  Tensor<float, 4, DataLayout> no_broadcast;
  no_broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(no_broadcast.dimension(0), 2);
  VERIFY_IS_EQUAL(no_broadcast.dimension(1), 3);
  VERIFY_IS_EQUAL(no_broadcast.dimension(2), 5);
  VERIFY_IS_EQUAL(no_broadcast.dimension(3), 7);

  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 5; ++k) {
        for (int l = 0; l < 7; ++l) {
          VERIFY_IS_EQUAL(tensor(i,j,k,l), no_broadcast(i,j,k,l));
        }
      }
    }
  }

  broadcasts[0] = 2;
  broadcasts[1] = 3;
  broadcasts[2] = 1;
  broadcasts[3] = 4;
  Tensor<float, 4, DataLayout> broadcast;
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 4);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 5);
  VERIFY_IS_EQUAL(broadcast.dimension(3), 28);

  for (int i = 0; i < 4; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 5; ++k) {
        for (int l = 0; l < 28; ++l) {
          VERIFY_IS_EQUAL(tensor(i%2,j%3,k%5,l%7), broadcast(i,j,k,l));
        }
      }
    }
  }
}

template <int DataLayout>
static void test_vectorized_broadcasting()
{
  Tensor<float, 3, DataLayout> tensor(8,3,5);
  tensor.setRandom();
  array<ptrdiff_t, 3> broadcasts;
  broadcasts[0] = 2;
  broadcasts[1] = 3;
  broadcasts[2] = 4;

  Tensor<float, 3, DataLayout> broadcast;
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 16);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 16; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%8,j%3,k%5), broadcast(i,j,k));
      }
    }
  }

  tensor.resize(11,3,5);
  tensor.setRandom();
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 22);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 22; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%11,j%3,k%5), broadcast(i,j,k));
      }
    }
  }
}

template <int DataLayout>
static void test_static_broadcasting()
{
  Tensor<float, 3, DataLayout> tensor(8,3,5);
  tensor.setRandom();

#ifdef EIGEN_HAS_CONSTEXPR
  Eigen::IndexList<Eigen::type2index<2>, Eigen::type2index<3>, Eigen::type2index<4>> broadcasts;
#else
  Eigen::array<int, 3> broadcasts;
  broadcasts[0] = 2;
  broadcasts[1] = 3;
  broadcasts[2] = 4;
#endif

  Tensor<float, 3, DataLayout> broadcast;
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 16);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 16; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%8,j%3,k%5), broadcast(i,j,k));
      }
    }
  }

  tensor.resize(11,3,5);
  tensor.setRandom();
  broadcast = tensor.broadcast(broadcasts);

  VERIFY_IS_EQUAL(broadcast.dimension(0), 22);
  VERIFY_IS_EQUAL(broadcast.dimension(1), 9);
  VERIFY_IS_EQUAL(broadcast.dimension(2), 20);

  for (int i = 0; i < 22; ++i) {
    for (int j = 0; j < 9; ++j) {
      for (int k = 0; k < 20; ++k) {
        VERIFY_IS_EQUAL(tensor(i%11,j%3,k%5), broadcast(i,j,k));
      }
    }
  }
}

template <int DataLayout>
static void test_fixed_size_broadcasting()
{
  // Need to add a [] operator to the Size class for this to work
#if 0
  Tensor<float, 1, DataLayout> t1(10);
  t1.setRandom();
  TensorFixedSize<float, Sizes<1>, DataLayout> t2;
  t2 = t2.constant(20.0f);

  Tensor<float, 1, DataLayout> t3 = t1 + t2.broadcast(Eigen::array<int, 1>{{10}});
  for (int i = 0; i < 10; ++i) {
    VERIFY_IS_APPROX(t3(i), t1(i) + t2(0));
  }

  TensorMap<TensorFixedSize<float, Sizes<1>, DataLayout> > t4(t2.data(), {{1}});
  Tensor<float, 1, DataLayout> t5 = t1 + t4.broadcast(Eigen::array<int, 1>{{10}});
  for (int i = 0; i < 10; ++i) {
    VERIFY_IS_APPROX(t5(i), t1(i) + t2(0));
  }
#endif
}

void test_cxx11_tensor_broadcasting()
{
  CALL_SUBTEST(test_simple_broadcasting<ColMajor>());
  CALL_SUBTEST(test_simple_broadcasting<RowMajor>());
  CALL_SUBTEST(test_vectorized_broadcasting<ColMajor>());
  CALL_SUBTEST(test_vectorized_broadcasting<RowMajor>());
  CALL_SUBTEST(test_static_broadcasting<ColMajor>());
  CALL_SUBTEST(test_static_broadcasting<RowMajor>());
  CALL_SUBTEST(test_fixed_size_broadcasting<ColMajor>());
  CALL_SUBTEST(test_fixed_size_broadcasting<RowMajor>());
}
<|endoftext|>


<commit_before><commit_msg>Added scale to shadow positioning if positive<commit_after><|endoftext|>


<commit_before>#include "RigidBody.h"
#include "BoundaryVector.h"
#include "Geometry.h"
#include <gtest/gtest.h>

namespace {

class GeometryTest : public testing::Test {
protected:
    GeometryTest() {
        // Define a RigidBody with one point
        RigidBody body1;
        body1.addPoint(0.,0.);

        // Define a RigidBody wth two points
        RigidBody body2;
        body2.addPoint(0., 1.);
        body2.addPoint(0., -1.);

        _geom.addBody(body1);
        _geom.addBody(body2);
    }

    // data
    Geometry _geom;
};

TEST_F(GeometryTest, NoBodies) {
    Geometry emptyGeom;

    EXPECT_EQ( emptyGeom.getNumPoints(), 0 );

    BoundaryVector points = emptyGeom.getPoints();
    EXPECT_EQ( points.getNumPoints(), 0 );

    BoundaryVector velocities = emptyGeom.getVelocities();
    EXPECT_EQ( velocities.getNumPoints(), 0 );
}

TEST_F(GeometryTest, OneBody) {
    const double x = 3.;
    const double y = 5.;
    RigidBody body;
    body.addPoint(x,y);

    Geometry geom;
    EXPECT_EQ( geom.getNumPoints(), 0 );
    geom.addBody(body);
    EXPECT_EQ( geom.getNumPoints(), 1 );

    BoundaryVector pts = geom.getPoints();
    EXPECT_EQ( pts.getNumPoints(), 1 );
    EXPECT_DOUBLE_EQ( pts(X,0), x );
    EXPECT_DOUBLE_EQ( pts(Y,0), y );
}

TEST_F(GeometryTest, TwoBodies) {
    // Coordinates of points in bodies to test
    const double x[3] = {3, 5, 7};
    const double y[3] = {10, 20, 30};

    // Define a RigidBody with one point
    RigidBody body1;
    body1.addPoint( x[0], y[0] );
    Geometry geom;
    geom.addBody(body1);
    EXPECT_EQ( geom.getNumPoints(), 1 );

    // Define a RigidBody wth two points
    RigidBody body2;
    body2.addPoint( x[1], y[1] );
    body2.addPoint( x[2], y[2] );
    geom.addBody(body2);
    EXPECT_EQ( geom.getNumPoints(), 3 );

    BoundaryVector points = geom.getPoints();
    for (int i=0; i < 3; ++i) {
        EXPECT_DOUBLE_EQ( points(X,i), x[i] );
        EXPECT_DOUBLE_EQ( points(Y,i), y[i] );
    }
}

}  // namespace

<commit_msg>Minor changes to GeometryTest (deleting RigidBody objects after adding to Geometry)<commit_after>#include "RigidBody.h"
#include "BoundaryVector.h"
#include "Geometry.h"
#include <gtest/gtest.h>

namespace {

class GeometryTest : public testing::Test {
protected:
    GeometryTest() {
        // Define a RigidBody with one point
        RigidBody body1;
        body1.addPoint(0.,0.);

        // Define a RigidBody wth two points
        RigidBody body2;
        body2.addPoint(0., 1.);
        body2.addPoint(0., -1.);

        _geom.addBody(body1);
        _geom.addBody(body2);
    }

    // data
    Geometry _geom;
};

TEST_F(GeometryTest, NoBodies) {
    Geometry emptyGeom;

    EXPECT_EQ( emptyGeom.getNumPoints(), 0 );

    BoundaryVector points = emptyGeom.getPoints();
    EXPECT_EQ( points.getNumPoints(), 0 );

    BoundaryVector velocities = emptyGeom.getVelocities();
    EXPECT_EQ( velocities.getNumPoints(), 0 );
}

TEST_F(GeometryTest, OneBody) {
    const double x = 3.;
    const double y = 5.;
    RigidBody body;
    body.addPoint(x,y);

    Geometry geom;
    EXPECT_EQ( geom.getNumPoints(), 0 );
    geom.addBody(body);
    EXPECT_EQ( geom.getNumPoints(), 1 );

    BoundaryVector pts = geom.getPoints();
    EXPECT_EQ( pts.getNumPoints(), 1 );
    EXPECT_DOUBLE_EQ( pts(X,0), x );
    EXPECT_DOUBLE_EQ( pts(Y,0), y );
}

TEST_F(GeometryTest, TwoBodies) {
    // Coordinates of points in bodies to test
    const double x[3] = {3, 5, 7};
    const double y[3] = {10, 20, 30};

    Geometry geom;

    // Define a RigidBody with one point
    RigidBody* body;
    body = new RigidBody();
    body->addPoint( x[0], y[0] );
    geom.addBody( *body );
    delete body;
    EXPECT_EQ( geom.getNumPoints(), 1 );

    // Define a RigidBody with two points
    body = new RigidBody();
    body->addPoint( x[1], y[1] );
    body->addPoint( x[2], y[2] );
    geom.addBody( *body );
    delete body;
    EXPECT_EQ( geom.getNumPoints(), 3 );

    BoundaryVector points = geom.getPoints();
    for (int i=0; i < 3; ++i) {
        EXPECT_DOUBLE_EQ( points(X,i), x[i] );
        EXPECT_DOUBLE_EQ( points(Y,i), y[i] );
    }

}

}  // namespace

<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef SOL_STATE_VIEW_HPP
#define SOL_STATE_VIEW_HPP

#include "error.hpp"
#include "table.hpp"
#include <memory>

namespace sol {
enum class lib : char {
    base,
    package,
    coroutine,
    string,
    os,
    math,
    table,
    debug,
    bit32,
    io,
    count
};

class state_view {
private:
    lua_State* L;
    table reg;
    global_table global;
public:
    typedef typename global_table::iterator iterator;
    typedef typename global_table::const_iterator const_iterator;

    state_view(lua_State* L):
    L(L),
    reg(L, LUA_REGISTRYINDEX),
    global(L, detail::global_) {

    }

    lua_State* lua_state() const {
        return L;
    }

    template<typename... Args>
    void open_libraries(Args&&... args) {
        static_assert(meta::are_same<lib, Args...>::value, "all types must be libraries");
        if(sizeof...(args) == 0) {
            luaL_openlibs(L);
            return;
        }

        lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };

        for(auto&& library : libraries) {
            switch(library) {
#if SOL_LUA_VERSION <= 501 && defined(SOL_LUAJIT)
            case lib::coroutine:
#endif // luajit opens coroutine base stuff
            case lib::base:
                luaL_requiref(L, "base", luaopen_base, 1);
                lua_pop(L, 1);
                break;
            case lib::package:
                luaL_requiref(L, "package", luaopen_package, 1);
                lua_pop(L, 1);
                break;
#if !defined(SOL_LUAJIT)
            case lib::coroutine:
#if SOL_LUA_VERSION > 501
                luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
                lua_pop(L, 1);
#endif // Lua 5.2+ only
                break;
#endif // Not LuaJIT
            case lib::string:
                luaL_requiref(L, "string", luaopen_string, 1);
                lua_pop(L, 1);
                break;
            case lib::table:
                luaL_requiref(L, "table", luaopen_table, 1);
                lua_pop(L, 1);
                break;
            case lib::math:
                luaL_requiref(L, "math", luaopen_math, 1);
                lua_pop(L, 1);
                break;
            case lib::bit32:
#if SOL_LUA_VERSION > 501
                luaL_requiref(L, "bit32", luaopen_bit32, 1);
                lua_pop(L, 1);
#else
#endif // Lua 5.2+ only
                break;
            case lib::io:
                luaL_requiref(L, "io", luaopen_io, 1);
                lua_pop(L, 1);
                break;
            case lib::os:
                luaL_requiref(L, "os", luaopen_os, 1);
                lua_pop(L, 1);
                break;
            case lib::debug:
                luaL_requiref(L, "debug", luaopen_debug, 1);
                lua_pop(L, 1);
                break;
            case lib::count:
            default:
                break;
            }
        }
    }

    void script(const std::string& code) {
        if(luaL_dostring(L, code.c_str())) {
            lua_error(L);
        }
    }

    void script_file(const std::string& filename) {
        if(luaL_dofile(L, filename.c_str())) {
            lua_error(L);
        }
    }

    iterator begin () const {
        return global.begin();
    }

    iterator end() const {
        return global.end();
    }

    const_iterator cbegin() const {
        return global.cbegin();
    }

    const_iterator cend() const {
        return global.cend();
    }

    global_table globals() const {
        return global;
    }

    table registry() const {
        return reg;
    }

    void set_panic(lua_CFunction panic){
        lua_atpanic(L, panic);
    }

    template<typename... Args, typename... Keys>
    decltype(auto) get(Keys&&... keys) const {
        return global.get<Args...>(std::forward<Keys>(keys)...);
    }

    template<typename T, typename Key>
    decltype(auto) get_or(Key&& key, T&& otherwise) const {
        return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
    }

    template<typename T, typename Key, typename D>
    decltype(auto) get_or(Key&& key, D&& otherwise) const {
        return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
    }

    template<typename... Args>
    state_view& set(Args&&... args) {
        global.set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T, typename... Keys>
    decltype(auto) traverse_get(Keys&&... keys) const {
        return global.traverse_get<T>(std::forward<Keys>(keys)...);
    }

    template<typename... Args>
    state_view& traverse_set(Args&&... args) {
        global.traverse_set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T>
    state_view& set_usertype(usertype<T>& user) {
        return set_usertype(usertype_traits<T>::name, user);
    }

    template<typename Key, typename T>
    state_view& set_usertype(Key&& key, usertype<T>& user) {
        global.set_usertype(std::forward<Key>(key), user);
        return *this;
    }

    template<typename Class, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename CTor0, typename... CTor, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename... CArgs, typename... Args>
    state_view& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
        global.new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
        return *this;
    }

    template <typename Fx>
    void for_each(Fx&& fx) {
        global.for_each(std::forward<Fx>(fx));
    }

    template<typename T>
    proxy<global_table&, T> operator[](T&& key) {
        return global[std::forward<T>(key)];
    }

    template<typename T>
    proxy<const global_table&, T> operator[](T&& key) const {
        return global[std::forward<T>(key)];
    }

    template<typename Sig, typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template<typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template <typename Name>
    table create_table(Name&& name, int narr = 0, int nrec = 0) {
        return global.create(std::forward<Name>(name), narr, nrec);
    }

    template <typename Name, typename Key, typename Value, typename... Args>
    table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename Name, typename... Args>
    table create_named_table(Name&& name, Args&&... args) {
        table x = global.create_with(std::forward<Args>(args)...);
        global.set(std::forward<Name>(name), x);
        return x;
    }

    table create_table(int narr = 0, int nrec = 0) {
        return create_table(lua_state(), narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    table create_table_with(Args&&... args) {
        return create_table_with(lua_state(), std::forward<Args>(args)...);
    }

    static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
        return global_table::create(L, narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    static inline table create_table_with(lua_State* L, Args&&... args) {
        return global_table::create_with(L, std::forward<Args>(args)...);
    }
};
} // sol

#endif // SOL_STATE_VIEW_HPP
<commit_msg>implicit conversion operator to make using the framework easier.<commit_after>// The MIT License (MIT)

// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors

// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#ifndef SOL_STATE_VIEW_HPP
#define SOL_STATE_VIEW_HPP

#include "error.hpp"
#include "table.hpp"
#include <memory>

namespace sol {
enum class lib : char {
    base,
    package,
    coroutine,
    string,
    os,
    math,
    table,
    debug,
    bit32,
    io,
    count
};

class state_view {
private:
    lua_State* L;
    table reg;
    global_table global;
public:
    typedef typename global_table::iterator iterator;
    typedef typename global_table::const_iterator const_iterator;

    state_view(lua_State* L):
    L(L),
    reg(L, LUA_REGISTRYINDEX),
    global(L, detail::global_) {

    }

    lua_State* lua_state() const {
        return L;
    }

    template<typename... Args>
    void open_libraries(Args&&... args) {
        static_assert(meta::are_same<lib, Args...>::value, "all types must be libraries");
        if(sizeof...(args) == 0) {
            luaL_openlibs(L);
            return;
        }

        lib libraries[1 + sizeof...(args)] = { lib::count, std::forward<Args>(args)... };

        for(auto&& library : libraries) {
            switch(library) {
#if SOL_LUA_VERSION <= 501 && defined(SOL_LUAJIT)
            case lib::coroutine:
#endif // luajit opens coroutine base stuff
            case lib::base:
                luaL_requiref(L, "base", luaopen_base, 1);
                lua_pop(L, 1);
                break;
            case lib::package:
                luaL_requiref(L, "package", luaopen_package, 1);
                lua_pop(L, 1);
                break;
#if !defined(SOL_LUAJIT)
            case lib::coroutine:
#if SOL_LUA_VERSION > 501
                luaL_requiref(L, "coroutine", luaopen_coroutine, 1);
                lua_pop(L, 1);
#endif // Lua 5.2+ only
                break;
#endif // Not LuaJIT
            case lib::string:
                luaL_requiref(L, "string", luaopen_string, 1);
                lua_pop(L, 1);
                break;
            case lib::table:
                luaL_requiref(L, "table", luaopen_table, 1);
                lua_pop(L, 1);
                break;
            case lib::math:
                luaL_requiref(L, "math", luaopen_math, 1);
                lua_pop(L, 1);
                break;
            case lib::bit32:
#if SOL_LUA_VERSION > 501
                luaL_requiref(L, "bit32", luaopen_bit32, 1);
                lua_pop(L, 1);
#else
#endif // Lua 5.2+ only
                break;
            case lib::io:
                luaL_requiref(L, "io", luaopen_io, 1);
                lua_pop(L, 1);
                break;
            case lib::os:
                luaL_requiref(L, "os", luaopen_os, 1);
                lua_pop(L, 1);
                break;
            case lib::debug:
                luaL_requiref(L, "debug", luaopen_debug, 1);
                lua_pop(L, 1);
                break;
            case lib::count:
            default:
                break;
            }
        }
    }

    void script(const std::string& code) {
        if(luaL_dostring(L, code.c_str())) {
            lua_error(L);
        }
    }

    void script_file(const std::string& filename) {
        if(luaL_dofile(L, filename.c_str())) {
            lua_error(L);
        }
    }

    iterator begin () const {
        return global.begin();
    }

    iterator end() const {
        return global.end();
    }

    const_iterator cbegin() const {
        return global.cbegin();
    }

    const_iterator cend() const {
        return global.cend();
    }

    global_table globals() const {
        return global;
    }

    table registry() const {
        return reg;
    }

    operator lua_State* () const {
        return lua_state();
    }

    void set_panic(lua_CFunction panic){
        lua_atpanic(L, panic);
    }

    template<typename... Args, typename... Keys>
    decltype(auto) get(Keys&&... keys) const {
        return global.get<Args...>(std::forward<Keys>(keys)...);
    }

    template<typename T, typename Key>
    decltype(auto) get_or(Key&& key, T&& otherwise) const {
        return global.get_or(std::forward<Key>(key), std::forward<T>(otherwise));
    }

    template<typename T, typename Key, typename D>
    decltype(auto) get_or(Key&& key, D&& otherwise) const {
        return global.get_or<T>(std::forward<Key>(key), std::forward<D>(otherwise));
    }

    template<typename... Args>
    state_view& set(Args&&... args) {
        global.set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T, typename... Keys>
    decltype(auto) traverse_get(Keys&&... keys) const {
        return global.traverse_get<T>(std::forward<Keys>(keys)...);
    }

    template<typename... Args>
    state_view& traverse_set(Args&&... args) {
        global.traverse_set(std::forward<Args>(args)...);
        return *this;
    }

    template<typename T>
    state_view& set_usertype(usertype<T>& user) {
        return set_usertype(usertype_traits<T>::name, user);
    }

    template<typename Key, typename T>
    state_view& set_usertype(Key&& key, usertype<T>& user) {
        global.set_usertype(std::forward<Key>(key), user);
        return *this;
    }

    template<typename Class, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename CTor0, typename... CTor, typename... Args>
    state_view& new_usertype(const std::string& name, Args&&... args) {
        global.new_usertype<Class, CTor0, CTor...>(name, std::forward<Args>(args)...);
        return *this;
    }

    template<typename Class, typename... CArgs, typename... Args>
    state_view& new_usertype(const std::string& name, constructors<CArgs...> ctor, Args&&... args) {
        global.new_usertype<Class>(name, ctor, std::forward<Args>(args)...);
        return *this;
    }

    template <typename Fx>
    void for_each(Fx&& fx) {
        global.for_each(std::forward<Fx>(fx));
    }

    template<typename T>
    proxy<global_table&, T> operator[](T&& key) {
        return global[std::forward<T>(key)];
    }

    template<typename T>
    proxy<const global_table&, T> operator[](T&& key) const {
        return global[std::forward<T>(key)];
    }

    template<typename Sig, typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function<Sig>(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template<typename... Args, typename Key>
    state_view& set_function(Key&& key, Args&&... args) {
        global.set_function(std::forward<Key>(key), std::forward<Args>(args)...);
        return *this;
    }

    template <typename Name>
    table create_table(Name&& name, int narr = 0, int nrec = 0) {
        return global.create(std::forward<Name>(name), narr, nrec);
    }

    template <typename Name, typename Key, typename Value, typename... Args>
    table create_table(Name&& name, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global.create(std::forward<Name>(name), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename Name, typename... Args>
    table create_named_table(Name&& name, Args&&... args) {
        table x = global.create_with(std::forward<Args>(args)...);
        global.set(std::forward<Name>(name), x);
        return x;
    }

    table create_table(int narr = 0, int nrec = 0) {
        return create_table(lua_state(), narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    table create_table(int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return create_table(lua_state(), narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    table create_table_with(Args&&... args) {
        return create_table_with(lua_state(), std::forward<Args>(args)...);
    }

    static inline table create_table(lua_State* L, int narr = 0, int nrec = 0) {
        return global_table::create(L, narr, nrec);
    }

    template <typename Key, typename Value, typename... Args>
    static inline table create_table(lua_State* L, int narr, int nrec, Key&& key, Value&& value, Args&&... args) {
        return global_table::create(L, narr, nrec, std::forward<Key>(key), std::forward<Value>(value), std::forward<Args>(args)...);
    }

    template <typename... Args>
    static inline table create_table_with(lua_State* L, Args&&... args) {
        return global_table::create_with(L, std::forward<Args>(args)...);
    }
};
} // sol

#endif // SOL_STATE_VIEW_HPP
<|endoftext|>


<commit_before>#ifndef PI
#define PI 3.14159265359f
#endif

#include "gpgpu_test_scene.hpp"
#include "code/ylikuutio/ontology/scene.hpp"
#include "code/ylikuutio/ontology/shader.hpp"
#include "code/ylikuutio/ontology/compute_task.hpp"
#include "code/ylikuutio/ontology/shader_struct.hpp"
#include "code/ylikuutio/ontology/compute_task_struct.hpp"
#include "code/ylikuutio/ontology/entity_factory.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <iostream>   // std::cout, std::cin, std::cerr
#include <string>     // std::string

namespace yli
{
    namespace ontology
    {
        class World;
        class Entity;
    }
}

namespace gpgpu_test
{
    yli::ontology::Entity* create_gpgpu_test_scene(yli::ontology::EntityFactory* entity_factory, yli::ontology::World* const world)
    {
        // GPGPU test `Scene` begins here.
        std::cout << "Creating yli::ontology::Entity* gpgpu_test_scene_entity ...\n";
        yli::ontology::Entity* const gpgpu_test_scene_entity = entity_factory->create_Scene(world, 0.9f);
        std::cout << "Creating yli::ontology::Scene* gpgpu_test_scene ...\n";
        yli::ontology::Scene* const gpgpu_test_scene = dynamic_cast<yli::ontology::Scene*>(gpgpu_test_scene_entity);

        if (gpgpu_test_scene == nullptr)
        {
            std::cerr << "Failed to create Scene.\n";
            return nullptr;
        }

        gpgpu_test_scene->set_name("gpgpu_test_scene");

        gpgpu_test_scene->set_turbo_factor(5.0f);
        gpgpu_test_scene->set_twin_turbo_factor(100.0f);

        // Create the shader, store it in `identity_shader`.
        ShaderStruct identity_shader_struct;
        identity_shader_struct.parent = gpgpu_test_scene;
        identity_shader_struct.vertex_shader = "identity.vert";
        identity_shader_struct.fragment_shader = "identity.frag";

        std::cout << "Creating yli::ontology::Entity* identity_shader_entity ...\n";
        yli::ontology::Entity* const identity_shader_entity = entity_factory->create_Shader(identity_shader_struct);
        std::cout << "Creating yli::ontology::Shader* identity_shader ...\n";
        yli::ontology::Shader* const identity_shader = dynamic_cast<yli::ontology::Shader*>(identity_shader_entity);

        if (identity_shader == nullptr)
        {
            std::cerr << "Failed to create Shader.\n";
            return nullptr;
        }

        identity_shader->set_name("identity_shader");

        ComputeTaskStruct identity_shader_compute_task_struct;
        identity_shader_compute_task_struct.texture_file_format = "bmp";
        identity_shader_compute_task_struct.texture_filename = "numbers_123456_black_and_white.bmp";
        identity_shader_compute_task_struct.output_filename = "gpgpu_identity_output.data";
        identity_shader_compute_task_struct.parent = identity_shader;
        identity_shader_compute_task_struct.texture_width = 512;
        identity_shader_compute_task_struct.texture_height = 512;

        std::cout << "Creating yli::ontology::Entity* identity_shader_compute_task_entity ...\n";
        yli::ontology::Entity* const identity_shader_compute_task_entity = entity_factory->create_ComputeTask(identity_shader_compute_task_struct);
        std::cout << "Creating yli::ontology::ComputeTask* identity_shader ...\n";
        yli::ontology::ComputeTask* const identity_shader_compute_task = dynamic_cast<yli::ontology::ComputeTask*>(identity_shader_compute_task_entity);

        if (identity_shader_compute_task == nullptr)
        {
            std::cerr << "Failed to create ComputeTask.\n";
            return nullptr;
        }

        // Create the shader, store it in `sobel_shader`.
        ShaderStruct sobel_shader_struct;
        sobel_shader_struct.parent = gpgpu_test_scene;
        sobel_shader_struct.vertex_shader = "identity.vert";
        sobel_shader_struct.fragment_shader = "sobel_gradient_magnitude.frag";

        std::cout << "Creating yli::ontology::Entity* sobel_shader_entity ...\n";
        yli::ontology::Entity* const sobel_shader_entity = entity_factory->create_Shader(sobel_shader_struct);
        std::cout << "Creating yli::ontology::Shader* sobel_shader ...\n";
        yli::ontology::Shader* const sobel_shader = dynamic_cast<yli::ontology::Shader*>(sobel_shader_entity);

        if (sobel_shader == nullptr)
        {
            std::cerr << "Failed to create Shader.\n";
            return nullptr;
        }

        sobel_shader->set_name("sobel_shader");

        ComputeTaskStruct sobel_shader_compute_task_struct;
        sobel_shader_compute_task_struct.texture_file_format = "bmp";
        sobel_shader_compute_task_struct.texture_filename = "numbers_123456_black_and_white.bmp";
        sobel_shader_compute_task_struct.output_filename = "gpgpu_sobel_output.data";
        sobel_shader_compute_task_struct.parent = sobel_shader;
        sobel_shader_compute_task_struct.texture_width = 512;
        sobel_shader_compute_task_struct.texture_height = 512;

        std::cout << "Creating yli::ontology::Entity* sobel_shader_compute_task_entity ...\n";
        yli::ontology::Entity* const sobel_shader_compute_task_entity = entity_factory->create_ComputeTask(sobel_shader_compute_task_struct);
        std::cout << "Creating yli::ontology::ComputeTask* sobel_shader ...\n";
        yli::ontology::ComputeTask* const sobel_shader_compute_task = dynamic_cast<yli::ontology::ComputeTask*>(sobel_shader_compute_task_entity);

        if (sobel_shader_compute_task == nullptr)
        {
            std::cerr << "Failed to create ComputeTask.\n";
            return nullptr;
        }

        return gpgpu_test_scene_entity;
    }
}
<commit_msg>GPGPU test: iterate Sobel operator 5 times.<commit_after>#ifndef PI
#define PI 3.14159265359f
#endif

#include "gpgpu_test_scene.hpp"
#include "code/ylikuutio/ontology/scene.hpp"
#include "code/ylikuutio/ontology/shader.hpp"
#include "code/ylikuutio/ontology/compute_task.hpp"
#include "code/ylikuutio/ontology/shader_struct.hpp"
#include "code/ylikuutio/ontology/compute_task_struct.hpp"
#include "code/ylikuutio/ontology/entity_factory.hpp"

// Include GLM
#ifndef __GLM_GLM_HPP_INCLUDED
#define __GLM_GLM_HPP_INCLUDED
#include <glm/glm.hpp> // glm
#endif

// Include standard headers
#include <iostream>   // std::cout, std::cin, std::cerr
#include <string>     // std::string

namespace yli
{
    namespace ontology
    {
        class World;
        class Entity;
    }
}

namespace gpgpu_test
{
    yli::ontology::Entity* create_gpgpu_test_scene(yli::ontology::EntityFactory* entity_factory, yli::ontology::World* const world)
    {
        // GPGPU test `Scene` begins here.
        std::cout << "Creating yli::ontology::Entity* gpgpu_test_scene_entity ...\n";
        yli::ontology::Entity* const gpgpu_test_scene_entity = entity_factory->create_Scene(world, 0.9f);
        std::cout << "Creating yli::ontology::Scene* gpgpu_test_scene ...\n";
        yli::ontology::Scene* const gpgpu_test_scene = dynamic_cast<yli::ontology::Scene*>(gpgpu_test_scene_entity);

        if (gpgpu_test_scene == nullptr)
        {
            std::cerr << "Failed to create Scene.\n";
            return nullptr;
        }

        gpgpu_test_scene->set_name("gpgpu_test_scene");

        gpgpu_test_scene->set_turbo_factor(5.0f);
        gpgpu_test_scene->set_twin_turbo_factor(100.0f);

        // Create the shader, store it in `identity_shader`.
        ShaderStruct identity_shader_struct;
        identity_shader_struct.parent = gpgpu_test_scene;
        identity_shader_struct.vertex_shader = "identity.vert";
        identity_shader_struct.fragment_shader = "identity.frag";

        std::cout << "Creating yli::ontology::Entity* identity_shader_entity ...\n";
        yli::ontology::Entity* const identity_shader_entity = entity_factory->create_Shader(identity_shader_struct);
        std::cout << "Creating yli::ontology::Shader* identity_shader ...\n";
        yli::ontology::Shader* const identity_shader = dynamic_cast<yli::ontology::Shader*>(identity_shader_entity);

        if (identity_shader == nullptr)
        {
            std::cerr << "Failed to create Shader.\n";
            return nullptr;
        }

        identity_shader->set_name("identity_shader");

        ComputeTaskStruct identity_shader_compute_task_struct;
        identity_shader_compute_task_struct.texture_file_format = "bmp";
        identity_shader_compute_task_struct.texture_filename = "numbers_123456_black_and_white.bmp";
        identity_shader_compute_task_struct.output_filename = "gpgpu_identity_output.data";
        identity_shader_compute_task_struct.parent = identity_shader;
        identity_shader_compute_task_struct.texture_width = 512;
        identity_shader_compute_task_struct.texture_height = 512;

        std::cout << "Creating yli::ontology::Entity* identity_shader_compute_task_entity ...\n";
        yli::ontology::Entity* const identity_shader_compute_task_entity = entity_factory->create_ComputeTask(identity_shader_compute_task_struct);
        std::cout << "Creating yli::ontology::ComputeTask* identity_shader ...\n";
        yli::ontology::ComputeTask* const identity_shader_compute_task = dynamic_cast<yli::ontology::ComputeTask*>(identity_shader_compute_task_entity);

        if (identity_shader_compute_task == nullptr)
        {
            std::cerr << "Failed to create ComputeTask.\n";
            return nullptr;
        }

        // Create the shader, store it in `sobel_shader`.
        ShaderStruct sobel_shader_struct;
        sobel_shader_struct.parent = gpgpu_test_scene;
        sobel_shader_struct.vertex_shader = "identity.vert";
        sobel_shader_struct.fragment_shader = "sobel_gradient_magnitude.frag";

        std::cout << "Creating yli::ontology::Entity* sobel_shader_entity ...\n";
        yli::ontology::Entity* const sobel_shader_entity = entity_factory->create_Shader(sobel_shader_struct);
        std::cout << "Creating yli::ontology::Shader* sobel_shader ...\n";
        yli::ontology::Shader* const sobel_shader = dynamic_cast<yli::ontology::Shader*>(sobel_shader_entity);

        if (sobel_shader == nullptr)
        {
            std::cerr << "Failed to create Shader.\n";
            return nullptr;
        }

        sobel_shader->set_name("sobel_shader");

        ComputeTaskStruct sobel_shader_compute_task_struct;
        sobel_shader_compute_task_struct.texture_file_format = "bmp";
        sobel_shader_compute_task_struct.texture_filename = "numbers_123456_black_and_white.bmp";
        sobel_shader_compute_task_struct.output_filename = "gpgpu_sobel_output.data";
        sobel_shader_compute_task_struct.parent = sobel_shader;
        sobel_shader_compute_task_struct.n_max_iterations = 5;
        sobel_shader_compute_task_struct.texture_width = 512;
        sobel_shader_compute_task_struct.texture_height = 512;
        sobel_shader_compute_task_struct.should_ylikuutio_save_intermediate_results = true;

        std::cout << "Creating yli::ontology::Entity* sobel_shader_compute_task_entity ...\n";
        yli::ontology::Entity* const sobel_shader_compute_task_entity = entity_factory->create_ComputeTask(sobel_shader_compute_task_struct);
        std::cout << "Creating yli::ontology::ComputeTask* sobel_shader ...\n";
        yli::ontology::ComputeTask* const sobel_shader_compute_task = dynamic_cast<yli::ontology::ComputeTask*>(sobel_shader_compute_task_entity);

        if (sobel_shader_compute_task == nullptr)
        {
            std::cerr << "Failed to create ComputeTask.\n";
            return nullptr;
        }

        return gpgpu_test_scene_entity;
    }
}
<|endoftext|>