<commit_before>#include "FileStatusColumn.h"

#include <Catalog.h>
#include <ControlLook.h>
#include <StringForRate.h>

#include "Utils.h"
#include "stdio.h"

#define kTEXT_MARGIN	8
#define kSPACE_TEXT		0

#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "FileStatusColumn"

//=====================================================================

FileStatusField::FileStatusField(FileStatus status)
	:fWidth(0),
	fString(""),
	fClippedString("")
{
	SetFileStatus(status);
	SetFilePercentage(0);
}

void
FileStatusField::SetFileStatus(FileStatus status)
{
	if(status!=fStatus) {

		fWidth = 0;
		fClippedString.SetTo("");
		fStatus=status;

		switch(fStatus){
				case NO_ENCLOSURE:
					fOriginalStatus.SetTo(" ");
				break;
				case NEW:
			 		fOriginalStatus.SetTo(B_TRANSLATE("new"));
			 	break;
			 	case NOT_DOWNLOADED:
			 	  	fOriginalStatus.SetTo(B_TRANSLATE("not downloaded"));
			 	break;
		     	case DOWNLOADED:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("downloaded"));
			 	break;
		     	case ERROR:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("error"));
			 	break;
		     	case STOPPED:
		     	 	 	fOriginalStatus.SetTo(B_TRANSLATE("stopped"));
			 	break;
		     	case NOT_FOUND:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("not found"));
			 	break;
			 	case CANT_CONNECT:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("can't connect"));
			 	break;
		     	case DOWNLOADING:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("downloading"));
			 	break;
			 	case ENQUEQUED:
			 		fOriginalStatus.SetTo(B_TRANSLATE("enquequed"));
			 	break;
			 	case CONNECTING:
			 		fOriginalStatus.SetTo(B_TRANSLATE("connecting"));
			 	break;
			 	default:
			 		fOriginalStatus.SetTo(B_TRANSLATE("error"));
			 	break;
		 }
		 	fString=fOriginalStatus;
		 	if(fStatus==STOPPED){
		 		//pervert game
		 		int perv=fPercentage;
		 		SetFilePercentage(0);
		 		SetFilePercentage(perv);
		 	}
		}

}

void
FileStatusField::SetFilePercentage(int per,float speed)
{
	if (fPercentage == per)
		return;

	if (per < 0)
		per = 0;

	fWidth = 0;

	fClippedString.SetTo("");
	fPercentage=per;

	if(fStatus == STOPPED || fStatus == DOWNLOADING) {
		BString sp;
		sp << per << "% ";

		if(speed>0 &&  fStatus == DOWNLOADING)
		{
			char rateString[32];
			sp << string_for_rate(speed, rateString, sizeof(rateString)) << " ";
		}
		sp << fOriginalStatus;
		fString = sp;
	}
}

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

void FileStatusField::SetString(const char* val)
{
	fString = val;
	fClippedString = "";
	fWidth = 0;
}

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

const char* FileStatusField::String() const
{
	return fString.String();
}

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

void FileStatusField::SetWidth(float width)
{
	fWidth = width;
}

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

float FileStatusField::Width()
{
	return fWidth;
}

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

void FileStatusField::SetClippedString(const char* val)
{
	fClippedString = val;
}

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

const char* FileStatusField::ClippedString()
{
	return fClippedString.String();
}

//=====================================================================

FileStatusColumn::FileStatusColumn(const char* title, float width, float minWidth,
							 float maxWidth, uint32 truncate, alignment align)
	:BTitledColumn(title, width, minWidth, maxWidth, align),
	fTruncate(truncate)
{

}

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

void FileStatusColumn::DrawField(BField* _field, BRect rect, BView* parent)
{

	FileStatusField*	field = static_cast<FileStatusField*>(_field);

	float			width = rect.Width() - (2 * kTEXT_MARGIN);
	float 			basePoint = 0;

	if(field->GetFileStatus() == STOPPED ||
	   field->GetFileStatus() == DOWNLOADING )
	   {
			basePoint = 100 + kSPACE_TEXT;
	   }

	if (width - basePoint != field->Width())
	{
		BString		out_string(field->String());

		parent->TruncateString(&out_string, fTruncate, width + 2 - basePoint);
		field->SetClippedString(out_string.String());
		field->SetWidth(width - basePoint);
	}

	if(basePoint>0){
		DrawBar(parent,rect,field->GetPercentage());
	}
	rect.left +=basePoint;
	DrawString(field->ClippedString(), parent, rect);
}

void
FileStatusColumn::DrawBar(BView* parent,BRect rect,int number)
{

	parent->PushState();
	//parent->SetDrawingMode( B_OP_ALPHA );
	//parent->SetBlendingMode( B_PIXEL_ALPHA, B_ALPHA_OVERLAY);

	BRect graphRect(rect);
	graphRect.left += 2;
	graphRect.right = graphRect.left + 99 + 1;
	float offsetY = (graphRect.Height() - 12) / 2;
	graphRect.top += offsetY;
	graphRect.bottom -= offsetY;

	number = number > 0 ? number : 1;

	be_control_look->DrawStatusBar(parent, graphRect, graphRect,
		ui_color(B_LIST_BACKGROUND_COLOR), ui_color(B_STATUS_BAR_COLOR),
		graphRect.left + number);

	parent->PopState();

}

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

int FileStatusColumn::CompareFields(BField* field1, BField* field2)
{
	return(ICompare(((FileStatusField*)field1)->String(),
				   (((FileStatusField*)field2)->String())));
}

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

bool FileStatusColumn::AcceptsField(const BField *field) const
{
	return static_cast<bool>(dynamic_cast<const FileStatusField*>(field));
}

<commit_msg>Fix download/stop status column<commit_after>#include "FileStatusColumn.h"

#include <Catalog.h>
#include <ControlLook.h>
#include <StringForRate.h>

#include "Utils.h"
#include "stdio.h"

#define kTEXT_MARGIN	8
#define kSPACE_TEXT		0

#undef B_TRANSLATION_CONTEXT
#define B_TRANSLATION_CONTEXT "FileStatusColumn"

//=====================================================================

FileStatusField::FileStatusField(FileStatus status)
	:fWidth(0),
	fString(""),
	fClippedString("")
{
	SetFileStatus(status);
	SetFilePercentage(0);
}

void
FileStatusField::SetFileStatus(FileStatus status)
{
	if(status!=fStatus) {

		fWidth = 0;
		fClippedString.SetTo("");
		fStatus=status;

		switch(fStatus){
				case NO_ENCLOSURE:
					fOriginalStatus.SetTo(" ");
				break;
				case NEW:
			 		fOriginalStatus.SetTo(B_TRANSLATE("new"));
			 	break;
			 	case NOT_DOWNLOADED:
			 	  	fOriginalStatus.SetTo(B_TRANSLATE("not downloaded"));
			 	break;
		     	case DOWNLOADED:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("downloaded"));
			 	break;
		     	case ERROR:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("error"));
			 	break;
		     	case STOPPED:
		     	 	 	fOriginalStatus.SetTo(B_TRANSLATE("stopped"));
			 	break;
		     	case NOT_FOUND:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("not found"));
			 	break;
			 	case CANT_CONNECT:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("can't connect"));
			 	break;
		     	case DOWNLOADING:
			 	 	fOriginalStatus.SetTo(B_TRANSLATE("downloading"));
			 	break;
			 	case ENQUEQUED:
			 		fOriginalStatus.SetTo(B_TRANSLATE("enquequed"));
			 	break;
			 	case CONNECTING:
			 		fOriginalStatus.SetTo(B_TRANSLATE("connecting"));
			 	break;
			 	default:
			 		fOriginalStatus.SetTo(B_TRANSLATE("error"));
			 	break;
		 }
		 	fString=fOriginalStatus;
		 	if(fStatus==STOPPED){
		 		//pervert game
		 		int perv=fPercentage;
		 		SetFilePercentage(0);
		 		SetFilePercentage(perv);
		 	}
		}

}

void
FileStatusField::SetFilePercentage(int per,float speed)
{
	if (fPercentage == per)
		return;

	if (per < 0)
		per = 0;

	fWidth = 0;

	fClippedString.SetTo("");
	fPercentage=per;

	if(fStatus == STOPPED || fStatus == DOWNLOADING) {
		BString sp;
		sp << per << "% ";

		if(speed>0 &&  fStatus == DOWNLOADING)
		{
			char rateString[32];
			sp << "- " << string_for_rate(speed, rateString, sizeof(rateString));
		}
		if (fStatus == STOPPED)
			sp << fOriginalStatus;
		fString = sp;
	}
}

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

void FileStatusField::SetString(const char* val)
{
	fString = val;
	fClippedString = "";
	fWidth = 0;
}

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

const char* FileStatusField::String() const
{
	return fString.String();
}

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

void FileStatusField::SetWidth(float width)
{
	fWidth = width;
}

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

float FileStatusField::Width()
{
	return fWidth;
}

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

void FileStatusField::SetClippedString(const char* val)
{
	fClippedString = val;
}

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

const char* FileStatusField::ClippedString()
{
	return fClippedString.String();
}

//=====================================================================

FileStatusColumn::FileStatusColumn(const char* title, float width, float minWidth,
							 float maxWidth, uint32 truncate, alignment align)
	:BTitledColumn(title, width, minWidth, maxWidth, align),
	fTruncate(truncate)
{

}

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

void FileStatusColumn::DrawField(BField* _field, BRect rect, BView* parent)
{

	FileStatusField*	field = static_cast<FileStatusField*>(_field);

	float			width = rect.Width() - (2 * kTEXT_MARGIN);
	float 			basePoint = 0;

	if((field->GetFileStatus() == STOPPED && field->GetPercentage() > 0)||
	   field->GetFileStatus() == DOWNLOADING)
	   {
			basePoint = 100 + kSPACE_TEXT;
	   }

	if (width - basePoint != field->Width())
	{
		BString		out_string(field->String());

		parent->TruncateString(&out_string, fTruncate, width + 2 - basePoint);
		field->SetClippedString(out_string.String());
		field->SetWidth(width - basePoint);
	}

	if(basePoint>0){
		DrawBar(parent,rect,field->GetPercentage());
	}
	rect.left +=basePoint;
	DrawString(field->ClippedString(), parent, rect);
}

void
FileStatusColumn::DrawBar(BView* parent,BRect rect,int number)
{

	parent->PushState();
	//parent->SetDrawingMode( B_OP_ALPHA );
	//parent->SetBlendingMode( B_PIXEL_ALPHA, B_ALPHA_OVERLAY);

	BRect graphRect(rect);
	graphRect.left += 2;
	graphRect.right = graphRect.left + 99 + 1;
	float offsetY = (graphRect.Height() - 12) / 2;
	graphRect.top += offsetY;
	graphRect.bottom -= offsetY;

	number = number > 0 ? number : 1;

	be_control_look->DrawStatusBar(parent, graphRect, graphRect,
		ui_color(B_LIST_BACKGROUND_COLOR), ui_color(B_STATUS_BAR_COLOR),
		graphRect.left + number);

	parent->PopState();

}

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

int FileStatusColumn::CompareFields(BField* field1, BField* field2)
{
	return(ICompare(((FileStatusField*)field1)->String(),
				   (((FileStatusField*)field2)->String())));
}

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

bool FileStatusColumn::AcceptsField(const BField *field) const
{
	return static_cast<bool>(dynamic_cast<const FileStatusField*>(field));
}

<|endoftext|>


<commit_before>#include "Chain.h"
#include <memory>
#include <array>
#include <algorithm>
#include "xoroshiro128plus.hpp"
#include <QDebug>

using namespace Xoroshiro;

Chain::Chain(QSize size)
    : d_ptr(new ChainPrivate(size), &QObject::deleteLater)
{
}

Chain::Chain(const Chain &other)
    : d_ptr(other.d_ptr)
{
}

Chain::operator QString() const {
    return QString("Chain(%1x%2, %3)").arg(d_ptr->m_size.width()).arg(d_ptr->m_size.height()).arg(thread()->objectName());
}

QSize Chain::size() {
    return d_ptr->m_size;
}

GLuint Chain::noiseTexture() {
    if (!d_ptr->m_noiseTexture.isCreated()) {
        d_ptr->m_noiseTexture.setSize(d_ptr->m_size.width(), d_ptr->m_size.height());
        d_ptr->m_noiseTexture.setFormat(QOpenGLTexture::RGBA32F);
        d_ptr->m_noiseTexture.allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::Float32);
        d_ptr->m_noiseTexture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
        d_ptr->m_noiseTexture.setWrapMode(QOpenGLTexture::Repeat);

        auto compCount = d_ptr->m_size.width() * d_ptr->m_size.height() * 4;
        auto data = std::make_unique<float[]>(compCount);

        auto xsr = xoroshiro128plus_engine(reinterpret_cast<uint64_t>(this));

        auto xsrd = [&xsr, div = (1./(UINT64_C(1)<<53))](){
            return (xsr() >> 11) * div;
        };
        std::generate(&data[0],&data[compCount],xsrd);
        d_ptr->m_noiseTexture.setData(QOpenGLTexture::RGBA, QOpenGLTexture::Float32, &data[0]);
        glFlush();

        if (QThread::currentThread() != thread()) {
            moveToThread(QThread::currentThread());
        }
    }

    return d_ptr->m_noiseTexture.textureId();
}

GLuint Chain::blankTexture() {
    if (!d_ptr->m_blankTexture.isCreated()) {
        d_ptr->m_blankTexture.setSize(1, 1);
        d_ptr->m_blankTexture.setFormat(QOpenGLTexture::RGBA8_UNorm);
        d_ptr->m_blankTexture.allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
        d_ptr->m_blankTexture.setMinMagFilters(QOpenGLTexture::Nearest, QOpenGLTexture::Nearest);
        d_ptr->m_blankTexture.setWrapMode(QOpenGLTexture::Repeat);

        auto data = std::array<uint8_t,4>();
        d_ptr->m_blankTexture.setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, &data[0]);

        if (QThread::currentThread() != thread()) {
            moveToThread(QThread::currentThread());
        }
    }

    return d_ptr->m_blankTexture.textureId();
}

QOpenGLVertexArrayObject *Chain::vao() {
    if (!d_ptr->m_vao.isCreated()) {
        d_ptr->m_vao.create();

        if (QThread::currentThread() != thread()) {
            moveToThread(QThread::currentThread());
        }
    }
    return &d_ptr->m_vao;
}

bool Chain::operator==(const Chain &other) const {
    return d_ptr == other.d_ptr;
}

bool Chain::operator>(const Chain &other) const {
    return d_ptr.data() > other.d_ptr.data();
}

bool Chain::operator<(const Chain &other) const {
    return d_ptr.data() > other.d_ptr.data();
}

Chain &Chain::operator=(const Chain &other) {
    d_ptr = other.d_ptr;
    return *this;
}

ChainPrivate::ChainPrivate(QSize size)
    : m_noiseTexture(QOpenGLTexture::Target2D)
    , m_blankTexture(QOpenGLTexture::Target2D)
    , m_vao(new QOpenGLVertexArrayObject())
    , m_size(size)
{
}

ChainPrivate::~ChainPrivate() {
}
<commit_msg>clarify deletion semantics<commit_after>#include "Chain.h"
#include <memory>
#include <array>
#include <algorithm>
#include "xoroshiro128plus.hpp"
#include <QDebug>

using namespace Xoroshiro;

Chain::Chain(QSize size)
    : d_ptr(new ChainPrivate(size), &QObject::deleteLater)
{
}

Chain::Chain(const Chain &other)
    : d_ptr(other.d_ptr)
{
}

Chain::operator QString() const {
    return QString("Chain(%1x%2, %3)").arg(d_ptr->m_size.width()).arg(d_ptr->m_size.height()).arg(thread()->objectName());
}

QSize Chain::size() {
    return d_ptr->m_size;
}

GLuint Chain::noiseTexture() {
    if (!d_ptr->m_noiseTexture.isCreated()) {
        d_ptr->m_noiseTexture.setSize(d_ptr->m_size.width(), d_ptr->m_size.height());
        d_ptr->m_noiseTexture.setFormat(QOpenGLTexture::RGBA32F);
        d_ptr->m_noiseTexture.allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::Float32);
        d_ptr->m_noiseTexture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear);
        d_ptr->m_noiseTexture.setWrapMode(QOpenGLTexture::Repeat);

        auto compCount = d_ptr->m_size.width() * d_ptr->m_size.height() * 4;
        auto data = std::make_unique<float[]>(compCount);

        auto xsr = xoroshiro128plus_engine(reinterpret_cast<uint64_t>(this));

        auto xsrd = [&xsr, div = (1./(UINT64_C(1)<<53))](){
            return (xsr() >> 11) * div;
        };
        std::generate(&data[0],&data[compCount],xsrd);
        d_ptr->m_noiseTexture.setData(QOpenGLTexture::RGBA, QOpenGLTexture::Float32, &data[0]);
        glFlush();

        if (QThread::currentThread() != d_ptr->thread()) {
            d_ptr->moveToThread(QThread::currentThread());
        }
    }

    return d_ptr->m_noiseTexture.textureId();
}

GLuint Chain::blankTexture() {
    if (!d_ptr->m_blankTexture.isCreated()) {
        d_ptr->m_blankTexture.setSize(1, 1);
        d_ptr->m_blankTexture.setFormat(QOpenGLTexture::RGBA8_UNorm);
        d_ptr->m_blankTexture.allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
        d_ptr->m_blankTexture.setMinMagFilters(QOpenGLTexture::Nearest, QOpenGLTexture::Nearest);
        d_ptr->m_blankTexture.setWrapMode(QOpenGLTexture::Repeat);

        auto data = std::array<uint8_t,4>();
        d_ptr->m_blankTexture.setData(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, &data[0]);

        if (QThread::currentThread() != d_ptr->thread()) {
            d_ptr->moveToThread(QThread::currentThread());
        }
    }

    return d_ptr->m_blankTexture.textureId();
}

QOpenGLVertexArrayObject *Chain::vao() {
    if (!d_ptr->m_vao.isCreated()) {
        d_ptr->m_vao.create();

        if (QThread::currentThread() != d_ptr->thread()) {
            d_ptr->moveToThread(QThread::currentThread());
        }
    }
    return &d_ptr->m_vao;
}

bool Chain::operator==(const Chain &other) const {
    return d_ptr == other.d_ptr;
}

bool Chain::operator>(const Chain &other) const {
    return d_ptr.data() > other.d_ptr.data();
}

bool Chain::operator<(const Chain &other) const {
    return d_ptr.data() > other.d_ptr.data();
}

Chain &Chain::operator=(const Chain &other) {
    d_ptr = other.d_ptr;
    return *this;
}

ChainPrivate::ChainPrivate(QSize size)
    : m_noiseTexture(QOpenGLTexture::Target2D)
    , m_blankTexture(QOpenGLTexture::Target2D)
    , m_vao(new QOpenGLVertexArrayObject())
    , m_size(size)
{
}

ChainPrivate::~ChainPrivate() {
}
<|endoftext|>


<commit_before>/*-----------------------------------------------------------------------------
This source file is part of Hopsan NG

Copyright (c) 2011
Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

This file is provided "as is", with no guarantee or warranty for the
functionality or reliability of the contents. All contents in this file is
the original work of the copyright holders at the Division of Fluid and
Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
redistributing any part of this file is prohibited without explicit
permission from the copyright holders.
-----------------------------------------------------------------------------*/

#define S_FUNCTION_NAME HopsanSimulink
#define S_FUNCTION_LEVEL 2

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <fstream>
#include "simstruc.h"
#include "HopsanCore/include/HopsanCore.h"
using namespace hopsan;

//! @todo need to be able to error report if file not fond, or maybe not, if no external libs used you dont want error message
void readExternalLibsFromTxtFile(const std::string filePath, std::vector<std::string> &rExtLibFileNames)
{
    rExtLibFileNames.clear();
    std::string line;
    std::ifstream file;
    file.open(filePath.c_str());
    if ( file.is_open() )
    {
        while ( file.good() )
        {
            getline(file, line);
            if ((*line.begin() != '#') && !line.empty())
            {
                rExtLibFileNames.push_back(line);
            }
       }
        file.close();
    }
    else
    {
        std::cout << "error, could not open file: " << filePath << std::endl;
    }
}

HopsanEssentials gHopsanCore;
ComponentSystem* pComponentSystem;
bool isOkToSimulate = false;

<<<15>>>
static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 0);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))
    {
        return;
    }

    //Define S-function input signals
    if (!ssSetNumInputPorts(S,<<<0>>>)) return;				//Number of input signals
<<<1>>>
    //Define S-function output signals
    if (!ssSetNumOutputPorts(S,<<<2>>>)) return;				//Number of output signals
<<<3>>>
    ssSetOutputPortWidth(S, <<<14>>>, DYNAMICALLY_SIZED);		//Debug output signal
    ssSetNumSampleTimes(S, 1);
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);

    std::vector<std::string> extLibs;
    readExternalLibsFromTxtFile("externalLibs.txt",extLibs);
    for (size_t i=0; i<extLibs.size(); ++i)
    {
        gHopsanCore.loadExternalComponentLib(extLibs[i].c_str());
    }

    const char* hmfFilePath = "<<<4>>>";
    double startT, stopT;
    pComponentSystem = gHopsanCore.loadHMFModel(hmfFilePath, startT, stopT);
    if (pComponentSystem==0)
    {
        ssSetErrorStatus(S,"Error could not open model: <<<4>>>");
        return;
    }
    startT = ssGetTStart(S);
    stopT = ssGetTFinal(S);
    pComponentSystem->setDesiredTimestep(0.001);
<<<5>>>}

static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, 0.001);
    ssSetOffsetTime(S, 0, 0.0);

    //Update tunable parameters
    const mxArray* in;
    const char* c_str;
    std::string str;
<<<6>>>

    isOkToSimulate = pComponentSystem->checkModelBeforeSimulation();
    if (isOkToSimulate)
    {
        pComponentSystem->setNumLogSamples(0);
        pComponentSystem->disableLog();
        pComponentSystem->initialize(0,1);
    }
    else
    {
        ssSetErrorStatus(S,"Error isSimulationOk() returned False! Most likely some components could not be loaded or some connections could not be established.");
        return;
    }

<<<16>>>}

static void mdlOutputs(SimStruct *S, int_T tid)
{
    //S-function input signals
    InputRealPtrsType uPtrs1 = ssGetInputPortRealSignalPtrs(S,0);

    //S-function output signals
    <<<7>>>
    int_T width1 = ssGetOutputPortWidth(S,0);

    //Input parameters
<<<8>>>
    //Equations
<<<9>>>
    output<<<10>>> = 0;		//Error code 0: Nothing is wrong

<<<11>>>
    double timestep = pComponentSystem->getDesiredTimeStep();
    double time = ssGetT(S);
    pComponentSystem->simulate(time+timestep);

<<<12>>>

    //Output parameters
<<<13>>>}

     static void mdlTerminate(SimStruct *S){}

 /* Simulink/Simulink Coder Interfaces */
 #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
 #include "simulink.c" /* MEX-file interface mechanism */
 #else
 #include "cg_sfun.h" /* Code generation registration function */
 #endif

<commit_msg>Added finalize call in Simulink export. Needs to be validated in Windows. Related to #853.<commit_after>/*-----------------------------------------------------------------------------
This source file is part of Hopsan NG

Copyright (c) 2011
Mikael Axin, Robert Braun, Alessandro Dell'Amico, Björn Eriksson,
Peter Nordin, Karl Pettersson, Petter Krus, Ingo Staack

This file is provided "as is", with no guarantee or warranty for the
functionality or reliability of the contents. All contents in this file is
the original work of the copyright holders at the Division of Fluid and
Mechatronic Systems (Flumes) at Linköping University. Modifying, using or
redistributing any part of this file is prohibited without explicit
permission from the copyright holders.
-----------------------------------------------------------------------------*/

#define S_FUNCTION_NAME HopsanSimulink
#define S_FUNCTION_LEVEL 2

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <fstream>
#include "simstruc.h"
#include "HopsanCore/include/HopsanCore.h"
using namespace hopsan;

//! @todo need to be able to error report if file not fond, or maybe not, if no external libs used you dont want error message
void readExternalLibsFromTxtFile(const std::string filePath, std::vector<std::string> &rExtLibFileNames)
{
    rExtLibFileNames.clear();
    std::string line;
    std::ifstream file;
    file.open(filePath.c_str());
    if ( file.is_open() )
    {
        while ( file.good() )
        {
            getline(file, line);
            if ((*line.begin() != '#') && !line.empty())
            {
                rExtLibFileNames.push_back(line);
            }
       }
        file.close();
    }
    else
    {
        std::cout << "error, could not open file: " << filePath << std::endl;
    }
}

HopsanEssentials gHopsanCore;
ComponentSystem* pComponentSystem;
bool isOkToSimulate = false;

<<<15>>>
static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S, 0);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S))
    {
        return;
    }

    //Define S-function input signals
    if (!ssSetNumInputPorts(S,<<<0>>>)) return;				//Number of input signals
<<<1>>>
    //Define S-function output signals
    if (!ssSetNumOutputPorts(S,<<<2>>>)) return;				//Number of output signals
<<<3>>>
    ssSetOutputPortWidth(S, <<<14>>>, DYNAMICALLY_SIZED);		//Debug output signal
    ssSetNumSampleTimes(S, 1);
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);

    std::vector<std::string> extLibs;
    readExternalLibsFromTxtFile("externalLibs.txt",extLibs);
    for (size_t i=0; i<extLibs.size(); ++i)
    {
        gHopsanCore.loadExternalComponentLib(extLibs[i].c_str());
    }

    const char* hmfFilePath = "<<<4>>>";
    double startT, stopT;
    pComponentSystem = gHopsanCore.loadHMFModel(hmfFilePath, startT, stopT);
    if (pComponentSystem==0)
    {
        ssSetErrorStatus(S,"Error could not open model: <<<4>>>");
        return;
    }
    startT = ssGetTStart(S);
    stopT = ssGetTFinal(S);
    pComponentSystem->setDesiredTimestep(0.001);
<<<5>>>}

static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, 0.001);
    ssSetOffsetTime(S, 0, 0.0);

    //Update tunable parameters
    const mxArray* in;
    const char* c_str;
    std::string str;
<<<6>>>

    isOkToSimulate = pComponentSystem->checkModelBeforeSimulation();
    if (isOkToSimulate)
    {
        pComponentSystem->setNumLogSamples(0);
        pComponentSystem->disableLog();
        pComponentSystem->initialize(0,1);
    }
    else
    {
        ssSetErrorStatus(S,"Error isSimulationOk() returned False! Most likely some components could not be loaded or some connections could not be established.");
        return;
    }

<<<16>>>}

static void mdlOutputs(SimStruct *S, int_T tid)
{
    //S-function input signals
    InputRealPtrsType uPtrs1 = ssGetInputPortRealSignalPtrs(S,0);

    //S-function output signals
    <<<7>>>
    int_T width1 = ssGetOutputPortWidth(S,0);

    //Input parameters
<<<8>>>
    //Equations
<<<9>>>
    output<<<10>>> = 0;		//Error code 0: Nothing is wrong

<<<11>>>
    double timestep = pComponentSystem->getDesiredTimeStep();
    double time = ssGetT(S);
    pComponentSystem->simulate(time+timestep);

<<<12>>>

    //Output parameters
<<<13>>>}

static void mdlTerminate(SimStruct *S)
{
    pComponentSystem->finalize();
}

 /* Simulink/Simulink Coder Interfaces */
 #ifdef MATLAB_MEX_FILE /* Is this file being compiled as a MEX-file? */
 #include "simulink.c" /* MEX-file interface mechanism */
 #else
 #include "cg_sfun.h" /* Code generation registration function */
 #endif

<|endoftext|>


<commit_before>#include "Wavenet/Coach.h"
#include "Wavenet/Generators.h" /* To determine whether generator has natural epochs. */

namespace wavenet {

void Coach::setBasedir (const std::string& basedir) {
    m_basedir = basedir;
    if (strcmp(&m_basedir.back(), "/") == 0) { m_basedir.append("/"); }
    return;
}

void Coach::setNumEvents (const int& numEvents) {
    if (numEvents < 0 and numEvents != -1) {
        WARNING("Input number of events (%d) not supported.", numEvents);
        return;
    }
    m_numEvents = numEvents;
    return;
}

void Coach::setNumCoeffs (const unsigned& numCoeffs) {
    if (!isRadix2(numCoeffs)) {
        WARNING("Input number of coefficients (%d) is not radix 2.", numCoeffs);
        return;
    }
    m_numCoeffs = numCoeffs;
    return;
}

void Coach::setTargetPrecision (const double& targetPrecision) {
    if (targetPrecision != -1 && targetPrecision <= 0) {
        WARNING("Requested target precision (%f) is no good. Exiting.", targetPrecision);
        return;
    }
    if (!(useAdaptiveLearningRate() || useAdaptiveBatchSize())) {
        WARNING("Target precision is to be used in conjuction with 'adaptive learning rate' or 'adaptive batch size'.");
        WARNING("Remember to set it using 'Coach::setUseAdaptiveLearningRate()' or 'Coach::setUseAdaptiveBatchSize()'.");
        WARNING(" Going to continue, but the set value of target precision won't have any effect on its own.");
    }
    m_targetPrecision = targetPrecision;
    return;
}

void Coach::checkMakeOutdir (const std::string& subdir) const {

    // Perform checks.
    if (m_basedir == "" || outdir() == "") {
        WARNING("Directory not set.");
        return;
    }

    if (strcmp(outdir().substr(0,1).c_str(), "/") == 0) {
        WARNING("Directory '%s' not accepted. Only accepting realtive paths.", outdir().c_str());
        return;
    }

    const std::string dir = outdir() + subdir;

    if (dirExists(dir)) {
        DEBUG("Directory '%s' already exists. Exiting.", dir.c_str());
        return;
    }

    // Create the directory.
    INFO("Creating directory '%s'.", dir.c_str());
    system(("mkdir -p " + dir).c_str());

    return;
}

bool Coach::run () {

    // Perform checks.
    if (!m_wavenet) {
        ERROR("WaveletML object not set.Exiting.");
        return false;
    }

    if (!m_generator) {
        ERROR("Input generator not set. Exiting.");
        return false;
    }

    if (!m_generator->initialised()) {
        ERROR("Generator was not properly initialised. Did you remember to specify a valid shape? Exiting.");
        return false;
    }

    if (!m_name.size()) {
        ERROR("Coach name not set. Exiting.");
        return false;
    }

    if (m_numEvents < 0) {
        if ((dynamic_cast<NeedleGenerator*>  (m_generator) != nullptr ||
             dynamic_cast<UniformGenerator*> (m_generator) != nullptr ||
             dynamic_cast<GaussianGenerator*>(m_generator) != nullptr) &&
            !((useAdaptiveLearningRate() || useAdaptiveBatchSize()) && targetPrecision() > 0.)) {
            WARNING("The number of events is set to %d while using", m_numEvents);
            WARNING(".. a generator with no natural epochs and with");
            WARNING(".. no target precision set. Etiher choose a ");
            WARNING(".. different generator or use");
            WARNING(".. 'Coach::setUseAdaptiveLearningRate()' or")
            WARNING(".. 'Coach::setUseAdaptiveLearningRate()', and");
            WARNING("'Coach::setTargetPrecision(someValue)'.");
            WARNING("Exiting.");
            return false;
        }
    }

    INFO("Start training, using coach '%s'.", m_name.c_str());

    // Save base snapshot of initial condition, so as to be able to restore same
    // configuration for each intitialisation (in particular, to roll back
    //changes made by adaptive learning methods.)
    Snapshot baseSnap (outdir() + "snapshots/.tmp.snap");
    m_wavenet->save(baseSnap);

    // Define number of trailing steps, for use with adaptive learning rate.
    const unsigned useLastN = 10;
    // Definition bare, specified regularsation constant, for use with simulated
    // annealing.
    const double lambdaBare = m_wavenet->lambda();

    // Define snapshot object, for saving the final configuration for each
    // initialisation.
    Snapshot snap (outdir() + "snapshots/" + m_name + ".%06u.snap", 0);

    // Loop initialisations.
    for (unsigned init = 0; init < m_numInits; init++) {

        // Print progress.
        if (m_printLevel > 0) {
            INFO("Initialisation %d/%d", init + 1, m_numInits);
        }

        // Load base snapshot.
        m_wavenet->load(baseSnap);
        m_wavenet->clear();

        // Generate initial coefficient configuration as random point on unit
        // N-sphere. In this way we immediately fullfill one out of the (at
        // most) four (non-trivial) conditions on the filter coefficients.
        m_wavenet->setFilter( PointOnNSphere(m_numCoeffs) );

        // Definitions for adaptive learning.
        bool done = false; // Whether the training is done, i.e. whether to
                           // break training early
        unsigned tail = 0; // The number of updates since beginning of training
                           // or last update of the learning rate, whichever is
                           // latest.
        unsigned currentCostLogSize  = 0; // Number of entries in cost log, now
        unsigned previousCostLogSize = 0; // and at previous step in the loop.
                                          // Used to determine whether a batch
                                          // update occurred.

        // Get the number of digits to use when printing the number of events.
        const unsigned eventDigits = (m_numEvents > 0 ? unsigned(log10(m_numEvents)) + 1 : 1);

        // Loop epochs.
        for (unsigned epoch = 0; epoch < m_numEpochs; epoch++) {

            // Reset (re-open) generator.
            m_generator->reset();

            // Print progress.
            if (m_printLevel > 1) {
                INFO("  Epoch %d/%d", epoch + 1, m_numEpochs);
            }

            // Loop events.
            int event = 0;
            int eventPrint = m_wavenet->batchSize();
            do {
                // Simulated annealing.
                if (useSimulatedAnnealing()) {
                     const double f = (event + epoch * numEvents()) / float(numEvents() * numEpochs());
                     const double effectiveLambda = lambdaBare * f / sq(2 - f);
                     m_wavenet->setLambda(effectiveLambda);
                }

                // Main training call.
                bool status = m_wavenet->train( m_generator->next() );

                // In case something goes wrong.
                if (!status) {
                    done = true;
                    break;
                }

                // Adaptive learning rate.
                if (useAdaptiveLearningRate() || useAdaptiveBatchSize()) {

                    // Determine whether a batch upate took place, by checking
                    // whether the size of the cost log changed.
                    previousCostLogSize = currentCostLogSize;
                    currentCostLogSize  = m_wavenet->costLog().size();
                    bool changed = (currentCostLogSize != previousCostLogSize);

                    // If it changed and the tail (number of updates since last
                    // learning rate update) is sufficiently large, initiate
                    // adaptation.
                    if (changed && ++tail > useLastN) {

                        const unsigned filterLogSize = m_wavenet->filterLog().size();

                        // Compute the (vector) size of the last N steps in the
                        // SGD, as well as the mean (scalar) size of these.
                        std::vector< arma::Col<double> > lastNsteps(useLastN);
                        double meanStepSize  = 0;
                        for (unsigned i = 0; i < useLastN; i++) {
                            lastNsteps.at(i) = m_wavenet->filterLog().at(filterLogSize - useLastN + i) - m_wavenet->filterLog().at(filterLogSize - useLastN + i - 1);
                            meanStepSize += arma::norm(lastNsteps.at(i));
                        }
                        meanStepSize /= float(useLastN);

                        // Compute the total (vector) size of the last N steps
                        // in the SGD combined, as well as the (scalar) size.
                        arma::Col<double> totalStep = m_wavenet->filterLog().at(filterLogSize - 1) - m_wavenet->filterLog().at(filterLogSize - 1 - useLastN);
                        double totalStepSize = arma::norm(totalStep);

                        // Check whether we have reached target precision or
                        // whether to perform adaptive learning rate update.
                        if (targetPrecision() != -1 && meanStepSize < targetPrecision() && !useSimulatedAnnealing()) {
                            INFO("[Adaptive learning] The mean step size over the last %d updates (%f)", useLastN, meanStepSize);
                            INFO("[Adaptive learning] is smaller than the target precision (%f). Done.", targetPrecision());
                            done = true;
                        } else if (totalStepSize < meanStepSize) {
                            INFO("[Adaptive learning] Total step size (%f) is smaller than mean step size (%f).", totalStepSize, meanStepSize);

                            // Update batch size.
                            if (useAdaptiveBatchSize()) {
                               INFO("[Adaptive learning]   Increasing batch size from %d to %d.", m_wavenet->batchSize(), 2 * m_wavenet->batchSize());
                               m_wavenet->setBatchSize( 2 * m_wavenet->batchSize() );
                            }

                            // Update learning rate.
                            if (useAdaptiveLearningRate()) {
                                INFO("[Adaptive learning]   Reducing learning rate (alpha) from %f to %f.", m_wavenet->alpha(), (1./2.) * m_wavenet->alpha() ); //* (totalStepSize/meanStepSize));
                                m_wavenet->setAlpha( (1./2.) * m_wavenet->alpha() ); // * (totalStepSize/meanStepSize));
                            }

                            tail = 0;
                        }

                    }

                }

                // Print progress.
                if (m_printLevel > 2 && ((event + 1) % eventPrint == 0  || event + 1 == m_numEvents)) {
                    if (m_numEvents == -1) { INFO("    Event %*d/- (cost: %7.3f)",   eventDigits, event + 1, m_wavenet->lastCost()); }
                    else                   { INFO("    Event %*d/%*d (cost: %7.3f)", eventDigits, event + 1, eventDigits, m_numEvents, m_wavenet->lastCost()); }
                    if ((event + 1) == 10 * eventPrint) { eventPrint *= 10; }
                }

                // Increment event number. (Only level not in a for-loop, since
                // the number of events may be unspecified, i.e. be -1.)
                ++event;

                // If the generator is not in a good condition, break.
                if (!m_generator->good()) { break; }

            } while (!done && (event < m_numEvents || m_numEvents < 0 ));

            if (done) { break; }
        }

        // Clean up, by removing the last entry in the cost log, which isn't
        // properly scaled to batch size since the batch queue hasn't been flushed,
        // and therefore might bias result.
        m_wavenet->costLog().pop_back();

        // Saving snapshot to file.
        m_wavenet->save(snap++);
    }

    // Writing setup to run-specific README file.
    INFO("Writing run configuration to '%s'.", (outdir() + "README").c_str());
    std::ofstream outFileStream (outdir() + "README");

    outFileStream << "m_numEvents: " << m_numEvents << "\n";
    outFileStream << "m_numEpochs: " << m_numEpochs << "\n";
    outFileStream << "m_numInits: "  << m_numInits  << "\n";
    outFileStream << "m_numCoeffs: " << m_numCoeffs << "\n";

    outFileStream.close();

    // Clean up.
    m_wavenet->clear();

    return true;
}

} // namespace
<commit_msg>Don't clear wavenet object after training.<commit_after>#include "Wavenet/Coach.h"
#include "Wavenet/Generators.h" /* To determine whether generator has natural epochs. */

namespace wavenet {

void Coach::setBasedir (const std::string& basedir) {
    m_basedir = basedir;
    if (strcmp(&m_basedir.back(), "/") == 0) { m_basedir.append("/"); }
    return;
}

void Coach::setNumEvents (const int& numEvents) {
    if (numEvents < 0 and numEvents != -1) {
        WARNING("Input number of events (%d) not supported.", numEvents);
        return;
    }
    m_numEvents = numEvents;
    return;
}

void Coach::setNumCoeffs (const unsigned& numCoeffs) {
    if (!isRadix2(numCoeffs)) {
        WARNING("Input number of coefficients (%d) is not radix 2.", numCoeffs);
        return;
    }
    m_numCoeffs = numCoeffs;
    return;
}

void Coach::setTargetPrecision (const double& targetPrecision) {
    if (targetPrecision != -1 && targetPrecision <= 0) {
        WARNING("Requested target precision (%f) is no good. Exiting.", targetPrecision);
        return;
    }
    if (!(useAdaptiveLearningRate() || useAdaptiveBatchSize())) {
        WARNING("Target precision is to be used in conjuction with 'adaptive learning rate' or 'adaptive batch size'.");
        WARNING("Remember to set it using 'Coach::setUseAdaptiveLearningRate()' or 'Coach::setUseAdaptiveBatchSize()'.");
        WARNING(" Going to continue, but the set value of target precision won't have any effect on its own.");
    }
    m_targetPrecision = targetPrecision;
    return;
}

void Coach::checkMakeOutdir (const std::string& subdir) const {

    // Perform checks.
    if (m_basedir == "" || outdir() == "") {
        WARNING("Directory not set.");
        return;
    }

    if (strcmp(outdir().substr(0,1).c_str(), "/") == 0) {
        WARNING("Directory '%s' not accepted. Only accepting realtive paths.", outdir().c_str());
        return;
    }

    const std::string dir = outdir() + subdir;

    if (dirExists(dir)) {
        DEBUG("Directory '%s' already exists. Exiting.", dir.c_str());
        return;
    }

    // Create the directory.
    INFO("Creating directory '%s'.", dir.c_str());
    system(("mkdir -p " + dir).c_str());

    return;
}

bool Coach::run () {

    // Perform checks.
    if (!m_wavenet) {
        ERROR("WaveletML object not set.Exiting.");
        return false;
    }

    if (!m_generator) {
        ERROR("Input generator not set. Exiting.");
        return false;
    }

    if (!m_generator->initialised()) {
        ERROR("Generator was not properly initialised. Did you remember to specify a valid shape? Exiting.");
        return false;
    }

    if (!m_name.size()) {
        ERROR("Coach name not set. Exiting.");
        return false;
    }

    if (m_numEvents < 0) {
        if ((dynamic_cast<NeedleGenerator*>  (m_generator) != nullptr ||
             dynamic_cast<UniformGenerator*> (m_generator) != nullptr ||
             dynamic_cast<GaussianGenerator*>(m_generator) != nullptr) &&
            !((useAdaptiveLearningRate() || useAdaptiveBatchSize()) && targetPrecision() > 0.)) {
            WARNING("The number of events is set to %d while using", m_numEvents);
            WARNING(".. a generator with no natural epochs and with");
            WARNING(".. no target precision set. Etiher choose a ");
            WARNING(".. different generator or use");
            WARNING(".. 'Coach::setUseAdaptiveLearningRate()' or")
            WARNING(".. 'Coach::setUseAdaptiveLearningRate()', and");
            WARNING("'Coach::setTargetPrecision(someValue)'.");
            WARNING("Exiting.");
            return false;
        }
    }

    INFO("Start training, using coach '%s'.", m_name.c_str());

    // Save base snapshot of initial condition, so as to be able to restore same
    // configuration for each intitialisation (in particular, to roll back
    //changes made by adaptive learning methods.)
    Snapshot baseSnap (outdir() + "snapshots/.tmp.snap");
    m_wavenet->save(baseSnap);

    // Define number of trailing steps, for use with adaptive learning rate.
    const unsigned useLastN = 10;
    // Definition bare, specified regularsation constant, for use with simulated
    // annealing.
    const double lambdaBare = m_wavenet->lambda();

    // Define snapshot object, for saving the final configuration for each
    // initialisation.
    Snapshot snap (outdir() + "snapshots/" + m_name + ".%06u.snap", 0);

    // Loop initialisations.
    for (unsigned init = 0; init < m_numInits; init++) {

        // Print progress.
        if (m_printLevel > 0) {
            INFO("Initialisation %d/%d", init + 1, m_numInits);
        }

        // Load base snapshot.
        m_wavenet->load(baseSnap);
        m_wavenet->clear();

        // Generate initial coefficient configuration as random point on unit
        // N-sphere. In this way we immediately fullfill one out of the (at
        // most) four (non-trivial) conditions on the filter coefficients.
        m_wavenet->setFilter( PointOnNSphere(m_numCoeffs) );

        // Definitions for adaptive learning.
        bool done = false; // Whether the training is done, i.e. whether to
                           // break training early
        unsigned tail = 0; // The number of updates since beginning of training
                           // or last update of the learning rate, whichever is
                           // latest.
        unsigned currentCostLogSize  = 0; // Number of entries in cost log, now
        unsigned previousCostLogSize = 0; // and at previous step in the loop.
                                          // Used to determine whether a batch
                                          // update occurred.

        // Get the number of digits to use when printing the number of events.
        const unsigned eventDigits = (m_numEvents > 0 ? unsigned(log10(m_numEvents)) + 1 : 1);

        // Loop epochs.
        for (unsigned epoch = 0; epoch < m_numEpochs; epoch++) {

            // Reset (re-open) generator.
            m_generator->reset();

            // Print progress.
            if (m_printLevel > 1) {
                INFO("  Epoch %d/%d", epoch + 1, m_numEpochs);
            }

            // Loop events.
            int event = 0;
            int eventPrint = m_wavenet->batchSize();
            do {
                // Simulated annealing.
                if (useSimulatedAnnealing()) {
                     const double f = (event + epoch * numEvents()) / float(numEvents() * numEpochs());
                     const double effectiveLambda = lambdaBare * f / sq(2 - f);
                     m_wavenet->setLambda(effectiveLambda);
                }

                // Main training call.
                bool status = m_wavenet->train( m_generator->next() );

                // In case something goes wrong.
                if (!status) {
                    done = true;
                    break;
                }

                // Adaptive learning rate.
                if (useAdaptiveLearningRate() || useAdaptiveBatchSize()) {

                    // Determine whether a batch upate took place, by checking
                    // whether the size of the cost log changed.
                    previousCostLogSize = currentCostLogSize;
                    currentCostLogSize  = m_wavenet->costLog().size();
                    bool changed = (currentCostLogSize != previousCostLogSize);

                    // If it changed and the tail (number of updates since last
                    // learning rate update) is sufficiently large, initiate
                    // adaptation.
                    if (changed && ++tail > useLastN) {

                        const unsigned filterLogSize = m_wavenet->filterLog().size();

                        // Compute the (vector) size of the last N steps in the
                        // SGD, as well as the mean (scalar) size of these.
                        std::vector< arma::Col<double> > lastNsteps(useLastN);
                        double meanStepSize  = 0;
                        for (unsigned i = 0; i < useLastN; i++) {
                            lastNsteps.at(i) = m_wavenet->filterLog().at(filterLogSize - useLastN + i) - m_wavenet->filterLog().at(filterLogSize - useLastN + i - 1);
                            meanStepSize += arma::norm(lastNsteps.at(i));
                        }
                        meanStepSize /= float(useLastN);

                        // Compute the total (vector) size of the last N steps
                        // in the SGD combined, as well as the (scalar) size.
                        arma::Col<double> totalStep = m_wavenet->filterLog().at(filterLogSize - 1) - m_wavenet->filterLog().at(filterLogSize - 1 - useLastN);
                        double totalStepSize = arma::norm(totalStep);

                        // Check whether we have reached target precision or
                        // whether to perform adaptive learning rate update.
                        if (targetPrecision() != -1 && meanStepSize < targetPrecision() && !useSimulatedAnnealing()) {
                            INFO("[Adaptive learning] The mean step size over the last %d updates (%f)", useLastN, meanStepSize);
                            INFO("[Adaptive learning] is smaller than the target precision (%f). Done.", targetPrecision());
                            done = true;
                        } else if (totalStepSize < meanStepSize) {
                            INFO("[Adaptive learning] Total step size (%f) is smaller than mean step size (%f).", totalStepSize, meanStepSize);

                            // Update batch size.
                            if (useAdaptiveBatchSize()) {
                               INFO("[Adaptive learning]   Increasing batch size from %d to %d.", m_wavenet->batchSize(), 2 * m_wavenet->batchSize());
                               m_wavenet->setBatchSize( 2 * m_wavenet->batchSize() );
                            }

                            // Update learning rate.
                            if (useAdaptiveLearningRate()) {
                                INFO("[Adaptive learning]   Reducing learning rate (alpha) from %f to %f.", m_wavenet->alpha(), (1./2.) * m_wavenet->alpha() ); //* (totalStepSize/meanStepSize));
                                m_wavenet->setAlpha( (1./2.) * m_wavenet->alpha() ); // * (totalStepSize/meanStepSize));
                            }

                            tail = 0;
                        }

                    }

                }

                // Print progress.
                if (m_printLevel > 2 && ((event + 1) % eventPrint == 0  || event + 1 == m_numEvents)) {
                    if (m_numEvents == -1) { INFO("    Event %*d/- (cost: %7.3f)",   eventDigits, event + 1, m_wavenet->lastCost()); }
                    else                   { INFO("    Event %*d/%*d (cost: %7.3f)", eventDigits, event + 1, eventDigits, m_numEvents, m_wavenet->lastCost()); }
                    if ((event + 1) == 10 * eventPrint) { eventPrint *= 10; }
                }

                // Increment event number. (Only level not in a for-loop, since
                // the number of events may be unspecified, i.e. be -1.)
                ++event;

                // If the generator is not in a good condition, break.
                if (!m_generator->good()) { break; }

            } while (!done && (event < m_numEvents || m_numEvents < 0 ));

            if (done) { break; }
        }

        // Clean up, by removing the last entry in the cost log, which isn't
        // properly scaled to batch size since the batch queue hasn't been flushed,
        // and therefore might bias result.
        m_wavenet->costLog().pop_back();

        // Saving snapshot to file.
        m_wavenet->save(snap++);
    }

    // Writing setup to run-specific README file.
    INFO("Writing run configuration to '%s'.", (outdir() + "README").c_str());
    std::ofstream outFileStream (outdir() + "README");

    outFileStream << "m_numEvents: " << m_numEvents << "\n";
    outFileStream << "m_numEpochs: " << m_numEpochs << "\n";
    outFileStream << "m_numInits: "  << m_numInits  << "\n";
    outFileStream << "m_numCoeffs: " << m_numCoeffs << "\n";

    outFileStream.close();

    // We're not clearing the wavenet object, since it might be useful to look
    // at the filter- and cost log immediately after training (i.e. without
    // interacting with Snapshots).

    return true;
}

} // namespace
<|endoftext|>


<commit_before>/**
 *  main.cpp
 *  This file is part of MultitouchPadOsc
 *
 *
 *  The MIT License
 *  Copyright (c) 2012 Paul Vollmer, http://www.wrong-entertainment.com
 *  All rights reserved.
 *
 *  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.
 *
 *
 *  @plattform        MacOs 10.6+
 *                    Win XXX
 *                    Linux XXX
 *  @openFrameworks   0071
 *  @dependencies
 *  @modified         2012.07.15
 *  @version          0.1.2
 */

#include "ofMain.h"
#include "MultitouchPadOscApp.h"
#include "ofAppGlutWindow.h"
#include "Cocoa/Cocoa.h"

int main() {
    ofAppGlutWindow window;
	ofSetupOpenGL(&window, 600, 600, OF_WINDOW); // setup the GL context

	if (NSApp){
        NSMenu      *menu;
        NSMenuItem  *menuItem;

        [NSApp setMainMenu:[[NSMenu alloc] init]];

		// Appname menu
		menu = [[NSMenu alloc] initWithTitle:@""];
		[menu addItemWithTitle:@"About MultitouchPadOsc" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];

		[menu addItem:[NSMenuItem separatorItem]];

		[menu addItemWithTitle:@"Hide MultitouchPadOsc" action:@selector(hide:) keyEquivalent:@"h"];

		menuItem = (NSMenuItem *)[menu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
		[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];

		[menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];

		[menu addItem:[NSMenuItem separatorItem]];

		[menu addItemWithTitle:@"Quit MultitouchPadOsc" action:@selector(terminate:) keyEquivalent:@"q"];

		// Put menu into the menubar
		menuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""];
		[menuItem setSubmenu:menu];
		[[NSApp mainMenu] addItem:menuItem];
		// Tell the application object that this is now the application menu
		//[NSApp setMainMenu:menu];

    }

	// this kicks off the running of my app can be
	// OF_WINDOW or OF_FULLSCREEN pass in width and height too:
	ofRunApp(new MultitouchPadOscApp());
}
<commit_msg>changed window size<commit_after>/**
 *  main.cpp
 *  This file is part of MultitouchPadOsc
 *
 *
 *  The MIT License
 *  Copyright (c) 2012 Paul Vollmer, http://www.wrong-entertainment.com
 *  All rights reserved.
 *
 *  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.
 *
 *
 *  @plattform        MacOs 10.6+
 *                    Win XXX
 *                    Linux XXX
 *  @openFrameworks   0071
 *  @dependencies
 *  @modified         2012.07.15
 *  @version          0.1.2
 */

#include "ofMain.h"
#include "MultitouchPadOscApp.h"
#include "ofAppGlutWindow.h"
#include "Cocoa/Cocoa.h"

int main() {
    ofAppGlutWindow window;
	ofSetupOpenGL(&window, 500, 400, OF_WINDOW); // setup the GL context

	if (NSApp){
        NSMenu      *menu;
        NSMenuItem  *menuItem;

        [NSApp setMainMenu:[[NSMenu alloc] init]];

		// Appname menu
		menu = [[NSMenu alloc] initWithTitle:@""];
		[menu addItemWithTitle:@"About MultitouchPadOsc" action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];

		[menu addItem:[NSMenuItem separatorItem]];

		[menu addItemWithTitle:@"Hide MultitouchPadOsc" action:@selector(hide:) keyEquivalent:@"h"];

		menuItem = (NSMenuItem *)[menu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
		[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];

		[menu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];

		[menu addItem:[NSMenuItem separatorItem]];

		[menu addItemWithTitle:@"Quit MultitouchPadOsc" action:@selector(terminate:) keyEquivalent:@"q"];

		// Put menu into the menubar
		menuItem = [[NSMenuItem alloc] initWithTitle:@"Apple" action:nil keyEquivalent:@""];
		[menuItem setSubmenu:menu];
		[[NSApp mainMenu] addItem:menuItem];
		// Tell the application object that this is now the application menu
		//[NSApp setMainMenu:menu];

    }

	// this kicks off the running of my app can be
	// OF_WINDOW or OF_FULLSCREEN pass in width and height too:
	ofRunApp(new MultitouchPadOscApp());
}
<|endoftext|>


<commit_before>#include <cstdlib>
#include <cmath>
#include <ctime>
#include <GL/glut.h>
#include <assert.h>
#include <cstdlib>

#include "main.hpp"
#include "Scene.hpp"

// don't define anything in headers! only declare it!!!1!one!
Vec3Df MyCameraPosition;

// double buffered
unsigned int textures[2];
unsigned int activeTexIndex = 0;
unsigned int isDrawingTexture = 0;
unsigned int isRealtimeRaytracing = 0;
Tree MyTree;
Scene MyScene;

// options
extern bool g_phong;
extern bool g_checkerboard;
extern bool g_debug;

bool needRebuild = false; // if the raytrace needs to be built

/**
 * draw a full-screen texture
 */
void drawTexture(int texIndex){
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textures[texIndex]);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);
    glVertex3f(0, 0, 0);
    glTexCoord2f(1, 0);
    glVertex3f(4, 0, 0);
    glTexCoord2f(1, 1);
    glVertex3f(4, 4, 0);
    glTexCoord2f(0, 1);
    glVertex3f(0, 4, 0);
    glEnd();
}

void animate() {
    MyCameraPosition = getCameraPosition();
    glutPostRedisplay();
}

void display(void);
void reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);

// entry point
int main(int argc, char** argv){
    glutInit(&argc, argv);

    // couches du framebuffer utilisees par l'application
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);

    // position et taille de la fenetre
    glutInitWindowPosition(200, 100);
    glutInitWindowSize(WINDOW_RES_X, WINDOW_RES_Y);
    glutCreateWindow(argv[0]);

    // Initialisation du point de vue
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0, 0, -4);
    glRotatef(0, -1, 1, 1);
    tbInitTransform();     // initialisation du point de vue
    tbHelp();                      // affiche l'aide sur la traqueboule
    MyCameraPosition = getCameraPosition();
    //
    // Active la lumière
    // Pour la partie
    // ECLAIRAGE

    glEnable( GL_LIGHTING);
    glEnable( GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);
    int LightPos[4] = {0, 0, 3, 1};
    glLightiv(GL_LIGHT0, GL_POSITION, LightPos);
    //glMaterialiv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec);
    //glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,10);

    glEnable(GL_NORMALIZE);
    glClearColor(0.0, 0.0, 0.0, 0.0);

    // Details sur le mode de tracé
    glEnable( GL_DEPTH_TEST);            // effectuer le test de profondeur
    //glEnable(GL_CULL_FACE);
    //glCullFace(GL_BACK);
    glPolygonMode(GL_FRONT, GL_FILL);
    glPolygonMode(GL_BACK, GL_LINE);
    glShadeModel(GL_SMOOTH);

    // init textures
    char* buf = new char[1024 * 1024 * 3];
    glGenTextures(2, textures);

    // texture 1
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB,
    GL_UNSIGNED_BYTE, buf);

    // texture 2
    glBindTexture(GL_TEXTURE_2D, textures[1]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB,
    GL_UNSIGNED_BYTE, buf);

    delete[] buf;

    // cablage des callback
    glutReshapeFunc(reshape);
    glutSetKeyRepeat(true);
    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyup);
    glutDisplayFunc(display);
    glutMouseFunc(tbMouseFunc);    // traqueboule utilise la souris
    glutMotionFunc(tbMotionFunc);  // traqueboule utilise la souris
    glutIdleFunc(animate);

    int ret = init(argc, argv);
    if(ret == 255)
        return 0;
    if(ret > 0)
        return ret;

    // lancement de la boucle principale
    glutMainLoop();

    return 0;  // instruction jamais exécutée
}

// draw fps
void drawInfo(){
    if(fpsTimer.needsDisplay()){
        float fps = 1. / fpsTimer.avg();
        fpsTimer.updateLastDisplay();
        sprintf(infoString, "%06.1f fps - Current object : %s", fps,
                MyScene.object->getName().c_str());
        MyScene.update();
    }

    int i = 0;
    while(infoString[i] != '\0'){
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, infoString[i++]);
    }
}

// display
clock_t ticks;
void display(void) {

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    // Effacer tout
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // la couleur et le z

    drawInfo();

    glLoadIdentity();  // repere camera

    if(isDrawingTexture || isRealtimeRaytracing){
        const static GLdouble viewport[] = {
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
           -2,-2,-4, 1
        };

        glMultMatrixd(viewport);
        drawTexture(activeTexIndex);

        // reset view
        glLoadIdentity();
        tbVisuTransform();

        // swap buffers; draw on back buffer
        if (isRealtimeRaytracing){
            clock_t start = clock();
            startRayTracing(!activeTexIndex, false);
            ticks = clock() - start;
            activeTexIndex = !activeTexIndex;
        } else {
            if (needRebuild == true){
                int millis = (int)(ticks * 1000. / CLOCKS_PER_SEC);
                long long expected = millis;
                expected *= RAYTRACE_RES_X / PREVIEW_RES_X;
                expected *= RAYTRACE_RES_Y / PREVIEW_RES_Y;
                expected *= MSAA / PREVIEW_MSAA;
                expected *= MSAA / PREVIEW_MSAA;
               //  expected /= THREADS; only for mac!
                if (expected < 1000)
                    printf("will take %d milliseconds\n", (int)expected);
                else if (expected < 1000 * 60)
                    printf("will take %d seconds\n", (int)(expected / 1000));
                else if (expected < 1000 * 60 * 60)
                    printf("will take %d minutes\n", (int)(expected / 1000 / 60));
                else if (expected < 1000 * 60 * 60 * 24) {
                    printf("RENDERING WILL TAKE LONG!\n");
                    printf("will take %d hour\n", (int)(expected / 1000 / 60 / 60));
                } else if (expected < (long long)1000 * 60 * 60 * 24 * 365) {
                    printf("RENDERING WILL TAKE VERY LONG!\n");
                    printf("will take %d days\n", (int)(expected / 1000 / 60 / 60 / 24));
                }
                else if (expected < (long long)1000 * 60 * 60 * 24 * 365 * 1000) {
                    printf("RENDERING will take years!\n");
                    printf("will take %d year\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000));
                }
                else if (expected < (long long)1000 * 60 * 60 * 24 * 365 * 1000 * 1000) {
                    printf("RENDERING will take thousands of years!\n");
                    printf("will take %d millenia\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000 / 1000));
                }
                else if (expected < (long long)1000 * 60 * 60 * 24 * 365 * 1000 * 1000) {
                    printf("RENDERING will take millions of years!\n");
                    printf("will take %d million years\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000 / 1000));
                }
                else if (expected < (float)1000 * 60 * 60 * 24 * 365 * 1000 * 1000 * 1000) {
                    printf("If the dinosaurs were alive when you started rendering, it would be ready now.\n");
                    printf("will take %d billion years\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000 / 100));
                }
                else {
                    printf("THIS IS MADNESS!\n");
                    printf("will take %s seconds\n", "<overflow error>");
                }
                startRayTracing(activeTexIndex, true);
                needRebuild = false;
            }
        }
    } else {
        tbVisuTransform(); // origine et orientation de la scene
        MyScene.draw();
		if (g_debug)
			MyScene.debugDraw();
    }

    glutSwapBuffers();
    glPopAttrib();
}
// pour changement de taille ou desiconification
void reshape(int w, int h){
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //glOrtho (-1.1, 1.1, -1.1,1.1, -1000.0, 1000.0);
    gluPerspective(50, (float)w / h, 1, 10);
    glMatrixMode(GL_MODELVIEW);
}

// prise en compte du clavier
void keyboard(unsigned char key, int x, int y){
    cout << "down " << key << endl;
    switch(key){
        case 't':
            cout << "Deprecated, 'b' toggles raytracing" << endl;
            isDrawingTexture = 0;
            isRealtimeRaytracing = 0;
            break;
        case 'L':
            MyCameraPosition = getCameraPosition();
            MyScene.addLightPoint(MyCameraPosition);
            break;
        case 'l':
			MyScene.lights[0] = getCameraPosition();
            break;
        case 'r':
            needRebuild = true;
            isDrawingTexture = 1;
            isRealtimeRaytracing = 0;
            break;
        case 'b':
            if(isRealtimeRaytracing){
                isDrawingTexture = 0;
                isRealtimeRaytracing = 0;
            }else{
                cout << "Using " << THREADS << " threads and resolution of "
                << PREVIEW_RES_X << "x" << PREVIEW_RES_Y << endl;
                isRealtimeRaytracing = 1;
                isDrawingTexture = 0;
            }
            break;
        case 27:     // touche ESC
            exit(0);
        default:
            if(!yourKeyboardPress(key, x, y)){
                printf("Unknown key %c\n", key);
            }
            break;
    }
}

void keyup(unsigned char key, int x, int y) {
    cout << "up " << key << endl;
    yourKeyboardRelease(key, x, y);
}

<commit_msg>Increased view window range.<commit_after>#include <cstdlib>
#include <cmath>
#include <ctime>
#include <GL/glut.h>
#include <assert.h>
#include <cstdlib>

#include "main.hpp"
#include "Scene.hpp"

// don't define anything in headers! only declare it!!!1!one!
Vec3Df MyCameraPosition;

// double buffered
unsigned int textures[2];
unsigned int activeTexIndex = 0;
unsigned int isDrawingTexture = 0;
unsigned int isRealtimeRaytracing = 0;
Tree MyTree;
Scene MyScene;

// options
extern bool g_phong;
extern bool g_checkerboard;
extern bool g_debug;

bool needRebuild = false; // if the raytrace needs to be built

/**
 * draw a full-screen texture
 */
void drawTexture(int texIndex){
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, textures[texIndex]);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0);
    glVertex3f(0, 0, 0);
    glTexCoord2f(1, 0);
    glVertex3f(4, 0, 0);
    glTexCoord2f(1, 1);
    glVertex3f(4, 4, 0);
    glTexCoord2f(0, 1);
    glVertex3f(0, 4, 0);
    glEnd();
}

void animate() {
    MyCameraPosition = getCameraPosition();
    glutPostRedisplay();
}

void display(void);
void reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);

// entry point
int main(int argc, char** argv){
    glutInit(&argc, argv);

    // couches du framebuffer utilisees par l'application
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);

    // position et taille de la fenetre
    glutInitWindowPosition(200, 100);
    glutInitWindowSize(WINDOW_RES_X, WINDOW_RES_Y);
    glutCreateWindow(argv[0]);

    // Initialisation du point de vue
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0, 0, -4);
    glRotatef(0, -1, 1, 1);
    tbInitTransform();     // initialisation du point de vue
    tbHelp();                      // affiche l'aide sur la traqueboule
    MyCameraPosition = getCameraPosition();
    //
    // Active la lumière
    // Pour la partie
    // ECLAIRAGE

    glEnable( GL_LIGHTING);
    glEnable( GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);
    int LightPos[4] = {0, 0, 3, 1};
    glLightiv(GL_LIGHT0, GL_POSITION, LightPos);
    //glMaterialiv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec);
    //glMateriali(GL_FRONT_AND_BACK,GL_SHININESS,10);

    glEnable(GL_NORMALIZE);
    glClearColor(0.0, 0.0, 0.0, 0.0);

    // Details sur le mode de tracé
    glEnable( GL_DEPTH_TEST);            // effectuer le test de profondeur
    //glEnable(GL_CULL_FACE);
    //glCullFace(GL_BACK);
    glPolygonMode(GL_FRONT, GL_FILL);
    glPolygonMode(GL_BACK, GL_LINE);
    glShadeModel(GL_SMOOTH);

    // init textures
    char* buf = new char[1024 * 1024 * 3];
    glGenTextures(2, textures);

    // texture 1
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB,
    GL_UNSIGNED_BYTE, buf);

    // texture 2
    glBindTexture(GL_TEXTURE_2D, textures[1]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 1024, 0, GL_RGB,
    GL_UNSIGNED_BYTE, buf);

    delete[] buf;

    // cablage des callback
    glutReshapeFunc(reshape);
    glutSetKeyRepeat(true);
    glutKeyboardFunc(keyboard);
    glutKeyboardUpFunc(keyup);
    glutDisplayFunc(display);
    glutMouseFunc(tbMouseFunc);    // traqueboule utilise la souris
    glutMotionFunc(tbMotionFunc);  // traqueboule utilise la souris
    glutIdleFunc(animate);

    int ret = init(argc, argv);
    if(ret == 255)
        return 0;
    if(ret > 0)
        return ret;

    // lancement de la boucle principale
    glutMainLoop();

    return 0;  // instruction jamais exécutée
}

// draw fps
void drawInfo(){
    if(fpsTimer.needsDisplay()){
        float fps = 1. / fpsTimer.avg();
        fpsTimer.updateLastDisplay();
        sprintf(infoString, "%06.1f fps - Current object : %s", fps,
                MyScene.object->getName().c_str());
        MyScene.update();
    }

    int i = 0;
    while(infoString[i] != '\0'){
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, infoString[i++]);
    }
}

// display
clock_t ticks;
void display(void) {

    glPushAttrib(GL_ALL_ATTRIB_BITS);
    // Effacer tout
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // la couleur et le z

    drawInfo();

    glLoadIdentity();  // repere camera

    if(isDrawingTexture || isRealtimeRaytracing){
        const static GLdouble viewport[] = {
            1, 0, 0, 0,
            0, 1, 0, 0,
            0, 0, 1, 0,
           -2,-2,-4, 1
        };

        glMultMatrixd(viewport);
        drawTexture(activeTexIndex);

        // reset view
        glLoadIdentity();
        tbVisuTransform();

        // swap buffers; draw on back buffer
        if (isRealtimeRaytracing){
            clock_t start = clock();
            startRayTracing(!activeTexIndex, false);
            ticks = clock() - start;
            activeTexIndex = !activeTexIndex;
        } else {
            if (needRebuild == true){
                int millis = (int)(ticks * 1000. / CLOCKS_PER_SEC);
                long long expected = millis;
                expected *= RAYTRACE_RES_X / PREVIEW_RES_X;
                expected *= RAYTRACE_RES_Y / PREVIEW_RES_Y;
                expected *= MSAA / PREVIEW_MSAA;
                expected *= MSAA / PREVIEW_MSAA;
               //  expected /= THREADS; only for mac!
                if (expected < 1000)
                    printf("will take %d milliseconds\n", (int)expected);
                else if (expected < 1000 * 60)
                    printf("will take %d seconds\n", (int)(expected / 1000));
                else if (expected < 1000 * 60 * 60)
                    printf("will take %d minutes\n", (int)(expected / 1000 / 60));
                else if (expected < 1000 * 60 * 60 * 24) {
                    printf("RENDERING WILL TAKE LONG!\n");
                    printf("will take %d hour\n", (int)(expected / 1000 / 60 / 60));
                } else if (expected < (long long)1000 * 60 * 60 * 24 * 365) {
                    printf("RENDERING WILL TAKE VERY LONG!\n");
                    printf("will take %d days\n", (int)(expected / 1000 / 60 / 60 / 24));
                }
                else if (expected < (long long)1000 * 60 * 60 * 24 * 365 * 1000) {
                    printf("RENDERING will take years!\n");
                    printf("will take %d year\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000));
                }
                else if (expected < (long long)1000 * 60 * 60 * 24 * 365 * 1000 * 1000) {
                    printf("RENDERING will take thousands of years!\n");
                    printf("will take %d millenia\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000 / 1000));
                }
                else if (expected < (long long)1000 * 60 * 60 * 24 * 365 * 1000 * 1000) {
                    printf("RENDERING will take millions of years!\n");
                    printf("will take %d million years\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000 / 1000));
                }
                else if (expected < (float)1000 * 60 * 60 * 24 * 365 * 1000 * 1000 * 1000) {
                    printf("If the dinosaurs were alive when you started rendering, it would be ready now.\n");
                    printf("will take %d billion years\n", (int)(expected / 1000 / 60 / 60 / 24 / 365 / 1000 / 100));
                }
                else {
                    printf("THIS IS MADNESS!\n");
                    printf("will take %s seconds\n", "<overflow error>");
                }
                startRayTracing(activeTexIndex, true);
                needRebuild = false;
            }
        }
    } else {
        tbVisuTransform(); // origine et orientation de la scene
        MyScene.draw();
		if (g_debug)
			MyScene.debugDraw();
    }

    glutSwapBuffers();
    glPopAttrib();
}
// pour changement de taille ou desiconification
void reshape(int w, int h){
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //glOrtho (-1.1, 1.1, -1.1,1.1, -1000.0, 1000.0);
    gluPerspective(50, (float)w / h, 1, 1000);
    glMatrixMode(GL_MODELVIEW);
}

// prise en compte du clavier
void keyboard(unsigned char key, int x, int y){
    cout << "down " << key << endl;
    switch(key){
        case 't':
            cout << "Deprecated, 'b' toggles raytracing" << endl;
            isDrawingTexture = 0;
            isRealtimeRaytracing = 0;
            break;
        case 'L':
            MyCameraPosition = getCameraPosition();
            MyScene.addLightPoint(MyCameraPosition);
            break;
        case 'l':
			MyScene.lights[0] = getCameraPosition();
            break;
        case 'r':
            needRebuild = true;
            isDrawingTexture = 1;
            isRealtimeRaytracing = 0;
            break;
        case 'b':
            if(isRealtimeRaytracing){
                isDrawingTexture = 0;
                isRealtimeRaytracing = 0;
            }else{
                cout << "Using " << THREADS << " threads and resolution of "
                << PREVIEW_RES_X << "x" << PREVIEW_RES_Y << endl;
                isRealtimeRaytracing = 1;
                isDrawingTexture = 0;
            }
            break;
        case 27:     // touche ESC
            exit(0);
        default:
            if(!yourKeyboardPress(key, x, y)){
                printf("Unknown key %c\n", key);
            }
            break;
    }
}

void keyup(unsigned char key, int x, int y) {
    cout << "up " << key << endl;
    yourKeyboardRelease(key, x, y);
}

<|endoftext|>